<commit_before>/**
 * Creates article and bulletin JSON
 * @param collectionId
 * @param releaseDate
 * @param pageType
 * @param parentUrl
 */

function loadT4Creator(collectionId, releaseDate, pageType, parentUrl) {
    var releaseDate = null;             //overwrite scheduled collection date
    var conditions = true;
    var pageType, pageTitle, uriSection, pageTitleTrimmed, pageEditionTrimmed, releaseDateManual,
        isInheriting, newUri, pageData, natStat, contactName, contactEmail,
        contactTel, keyWords, metaDescr, relatedData, summary, relatedMethodology;
    var parentUrlData = parentUrl + "/data";
    $.ajax({
        url: parentUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (checkData) {
            if (checkData.type === 'product_page' && !Florence.globalVars.welsh) {
                var checkedUrl = checkPathSlashes(checkData.uri);
                submitFormHandler(checkedUrl);
                return true;
            }
            if ((checkData.type === 'bulletin' && pageType === 'bulletin') || (checkData.type === 'article' && pageType === 'article') || (checkData.type === 'article_download' && pageType === 'article_download')) {
                var checkedUrl = checkPathSlashes(checkData.uri);
                var safeParentUrl = getParentPage(checkedUrl);
                natStat = checkData.description.nationalStatistic;
                contactName = checkData.description.contact.name;
                contactEmail = checkData.description.contact.email;
                contactTel = checkData.description.contact.telephone;
                pageTitle = checkData.description.title;
                keyWords = checkData.description.keywords;
                summary = checkData.description.summary;
                metaDescr = checkData.description.metaDescription;
                relatedMethodology = checkData.relatedMethodology;
                if (checkData.type === 'bulletin' && pageType === 'bulletin') {
                    relatedData = checkData.relatedData;
                }
                isInheriting = true;
                submitFormHandler(safeParentUrl, pageTitle, isInheriting);
                return true;
            } else {
                sweetAlert("This is not a valid place to create this page.");
                loadCreateScreen(parentUrl, collectionId);
            }
        },
        error: function () {
            console.log('No page data returned');
        }
    });

    function submitFormHandler(parentUrl, title, isInheriting) {

        $('.edition').append(
            '
' +
            '  Edition' +
            '  <input id="edition" type="text" placeholder="August 2010, Q3 2015, 1978, etc." />' +
            '
'
        );
        if (!releaseDate) {
            $('.edition').append(
                '
' +
                '  Release date' +
                '  <input id="releaseDate" type="text" placeholder="day month year" />' +
                '
'
            );
            creatorDatePicker();
        }
        if(!isInheriting) {
            $('.btn-page-create').before(
                '
Creating a publication here will create a new series.
'
            )
        }
        if (title) {
            pageTitle = title;
            $('#pagename').val(title);
        }

        $('form').off().submit(function (e) {
            e.preventDefault();
            releaseDateManual = $('#releaseDate').val();

            // Do input validation
            var nameValid = validatePageName();
            if (!nameValid) {
                return false;
            }

            pageData = pageTypeDataT4(pageType);
            pageData.description.edition = $('#edition').val();
            if (title) {
                //do nothing;
            } else {
                pageTitle = $('#pagename').val();
            }
            pageData.description.title = pageTitle;
            if (pageType === 'article_download') {
                uriSection = 'articles';
            } else {
                uriSection = pageType + "s";
            }
            pageTitleTrimmed = pageTitle.replace(/[^A-Z0-9]+/ig, "").toLowerCase();
            if (pageData.description.edition) {
                pageEditionTrimmed = pageData.description.edition.replace(/[^A-Z0-9]+/ig, "").toLowerCase();
                var releaseUri = pageEditionTrimmed;
            }

            if (!pageData.description.edition && releaseDateManual) {                          //Manual collections
                date = $.datepicker.parseDate("dd MM yy", releaseDateManual);
                releaseUri = $.datepicker.formatDate('yy-mm-dd', date);
            } else if (!pageData.description.edition && !releaseDateManual) {
                releaseUri = $.datepicker.formatDate('yy-mm-dd', new Date(releaseDate));
            }

            if (!releaseDate) {
                pageData.description.releaseDate = new Date($('#releaseDate').val()).toISOString();
            } else {
                pageData.description.releaseDate = releaseDate;
            }
            if (isInheriting) {
                pageData.description.nationalStatistic = natStat;
                pageData.description.contact.name = contactName;
                pageData.description.contact.email = contactEmail;
                pageData.description.contact.telephone = contactTel;
                pageData.description.keywords = keyWords;
                pageData.description.metaDescription = metaDescr;
                pageData.relatedMethodology = relatedMethodology;
                if (pageType === 'bulletin') {
                    pageData.description.summary = summary;
                    pageData.relatedData = relatedData;
                }
                newUri = makeUrl(parentUrl, releaseUri);
            } else {
                newUri = makeUrl(parentUrl, uriSection, pageTitleTrimmed, releaseUri);
            }
            var safeNewUri = checkPathSlashes(newUri);

            if (pageType === 'bulletin' && !pageData.description.edition) {
                sweetAlert('Edition can not be empty');
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            if (!pageData.description.releaseDate) {
                sweetAlert('Release date can not be empty');
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            if (pageTitle.length < 5) {
                sweetAlert("This is not a valid file title");
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            else if (conditions) {
                saveContent(collectionId, safeNewUri, pageData);
            }
        });
    }

    function pageTypeDataT4(pageType) {

        if (pageType === "bulletin") {
            return {
                "description": {
                    "title": "",
                    "edition": "",
                    "summary": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "headline1": "",
                    "headline2": "",
                    "headline3": "",
                    "keywords": [],
                    "metaDescription": "",
                },
                "sections": [],
                "accordion": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "pdfTable": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else if (pageType === "article") {
            return {
                "description": {
                    "title": "",
                    "edition": "",
                    "_abstract": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "keywords": [],
                    "metaDescription": "",
                },
                "sections": [],
                "accordion": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "pdfTable": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else if (pageType === "article_download") {
            return {
                "description": {
                    "title": "",
                    "_abstract": "",
                    "edition": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "keywords": [],
                    "metaDescription": ""
                },
                "markdown": [],
                "downloads": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else {
            sweetAlert('Unsupported page type. This is not an article or a bulletin');
        }
    }
}

<commit_msg>Add edition validating to bulletin only on T4 creator screen<commit_after>/**
 * Creates article and bulletin JSON
 * @param collectionId
 * @param releaseDate
 * @param pageType
 * @param parentUrl
 */

function loadT4Creator(collectionId, releaseDate, pageType, parentUrl) {
    var releaseDate = null;             //overwrite scheduled collection date
    var conditions = true;
    var pageType, pageTitle, uriSection, pageTitleTrimmed, pageEditionTrimmed, releaseDateManual,
        isInheriting, newUri, pageData, natStat, contactName, contactEmail,
        contactTel, keyWords, metaDescr, relatedData, summary, relatedMethodology;
    var parentUrlData = parentUrl + "/data";
    $.ajax({
        url: parentUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (checkData) {
            if (checkData.type === 'product_page' && !Florence.globalVars.welsh) {
                var checkedUrl = checkPathSlashes(checkData.uri);
                submitFormHandler(checkedUrl);
                return true;
            }
            if ((checkData.type === 'bulletin' && pageType === 'bulletin') || (checkData.type === 'article' && pageType === 'article') || (checkData.type === 'article_download' && pageType === 'article_download')) {
                var checkedUrl = checkPathSlashes(checkData.uri);
                var safeParentUrl = getParentPage(checkedUrl);
                natStat = checkData.description.nationalStatistic;
                contactName = checkData.description.contact.name;
                contactEmail = checkData.description.contact.email;
                contactTel = checkData.description.contact.telephone;
                pageTitle = checkData.description.title;
                keyWords = checkData.description.keywords;
                summary = checkData.description.summary;
                metaDescr = checkData.description.metaDescription;
                relatedMethodology = checkData.relatedMethodology;
                if (checkData.type === 'bulletin' && pageType === 'bulletin') {
                    relatedData = checkData.relatedData;
                }
                isInheriting = true;
                submitFormHandler(safeParentUrl, pageTitle, isInheriting);
                return true;
            } else {
                sweetAlert("This is not a valid place to create this page.");
                loadCreateScreen(parentUrl, collectionId);
            }
        },
        error: function () {
            console.log('No page data returned');
        }
    });

    function submitFormHandler(parentUrl, title, isInheriting) {

        $('.edition').append(
            '
' +
            '  Edition' +
            '  <input id="edition" type="text" placeholder="August 2010, Q3 2015, 1978, etc." />' +
            '
'
        );
        if (!releaseDate) {
            $('.edition').append(
                '
' +
                '  Release date' +
                '  <input id="releaseDate" type="text" placeholder="day month year" />' +
                '
'
            );
            creatorDatePicker();
        }
        if(!isInheriting) {
            $('.btn-page-create').before(
                '
Creating a publication here will create a new series.
'
            )
        }
        if (title) {
            pageTitle = title;
            $('#pagename').val(title);
        }

        $('form').off().submit(function (e) {
            e.preventDefault();
            releaseDateManual = $('#releaseDate').val();

            // Do input validation
            var nameValid = validatePageName();
            if (!nameValid) {
                return false;
            }

            if (pageType === 'bulletin' && !validatePageName($('#edition'))) {
                return false;
            }

            pageData = pageTypeDataT4(pageType);
            pageData.description.edition = $('#edition').val();
            if (title) {
                //do nothing;
            } else {
                pageTitle = $('#pagename').val();
            }
            pageData.description.title = pageTitle;
            if (pageType === 'article_download') {
                uriSection = 'articles';
            } else {
                uriSection = pageType + "s";
            }
            pageTitleTrimmed = pageTitle.replace(/[^A-Z0-9]+/ig, "").toLowerCase();
            if (pageData.description.edition) {
                pageEditionTrimmed = pageData.description.edition.replace(/[^A-Z0-9]+/ig, "").toLowerCase();
                var releaseUri = pageEditionTrimmed;
            }

            if (!pageData.description.edition && releaseDateManual) {                          //Manual collections
                date = $.datepicker.parseDate("dd MM yy", releaseDateManual);
                releaseUri = $.datepicker.formatDate('yy-mm-dd', date);
            } else if (!pageData.description.edition && !releaseDateManual) {
                releaseUri = $.datepicker.formatDate('yy-mm-dd', new Date(releaseDate));
            }

            if (!releaseDate) {
                pageData.description.releaseDate = new Date($('#releaseDate').val()).toISOString();
            } else {
                pageData.description.releaseDate = releaseDate;
            }
            if (isInheriting) {
                pageData.description.nationalStatistic = natStat;
                pageData.description.contact.name = contactName;
                pageData.description.contact.email = contactEmail;
                pageData.description.contact.telephone = contactTel;
                pageData.description.keywords = keyWords;
                pageData.description.metaDescription = metaDescr;
                pageData.relatedMethodology = relatedMethodology;
                if (pageType === 'bulletin') {
                    pageData.description.summary = summary;
                    pageData.relatedData = relatedData;
                }
                newUri = makeUrl(parentUrl, releaseUri);
            } else {
                newUri = makeUrl(parentUrl, uriSection, pageTitleTrimmed, releaseUri);
            }
            var safeNewUri = checkPathSlashes(newUri);

            if (pageType === 'bulletin' && !pageData.description.edition) {
                sweetAlert('Edition can not be empty');
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            if (!pageData.description.releaseDate) {
                sweetAlert('Release date can not be empty');
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            if (pageTitle.length < 5) {
                sweetAlert("This is not a valid file title");
                $('.select-wrap').remove();
                $('#edition-div').remove();
                $('#release-div').remove();
                loadT4Creator(collectionId, releaseDate, pageType, parentUrl);
                e.preventDefault();
                conditions = false;
            }
            else if (conditions) {
                saveContent(collectionId, safeNewUri, pageData);
            }
        });
    }

    function pageTypeDataT4(pageType) {

        if (pageType === "bulletin") {
            return {
                "description": {
                    "title": "",
                    "edition": "",
                    "summary": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "headline1": "",
                    "headline2": "",
                    "headline3": "",
                    "keywords": [],
                    "metaDescription": "",
                },
                "sections": [],
                "accordion": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "pdfTable": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else if (pageType === "article") {
            return {
                "description": {
                    "title": "",
                    "edition": "",
                    "_abstract": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "keywords": [],
                    "metaDescription": "",
                },
                "sections": [],
                "accordion": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "pdfTable": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else if (pageType === "article_download") {
            return {
                "description": {
                    "title": "",
                    "_abstract": "",
                    "edition": "",
                    "releaseDate": "",
                    "nextRelease": "",
                    "contact": {
                        "name": "",
                        "email": "",
                        "telephone": ""
                    },
                    "nationalStatistic": false,
                    "keywords": [],
                    "metaDescription": ""
                },
                "markdown": [],
                "downloads": [],
                "relatedDocuments": [],
                "relatedData": [],
                "relatedMethodology": [],
                "relatedMethodologyArticle": [],
                "topics": [],
                "links": [],
                "charts": [],
                "tables": [],
                "equations": [],
                "images": [],
                "alerts": [],
                "versions": [],
                type: pageType
            };
        }

        else {
            sweetAlert('Unsupported page type. This is not an article or a bulletin');
        }
    }
}

<|endoftext|>


<commit_before>var temp;
var random;
var img;
var answer = "CATS";
var text_before = "IT'S RAINING";
var text_after = "AND DOGS";
var val;

// This function is called when the user submits an answer
//

$(document).ready(function(){
    $('#search_tag').keypress(function(e){
      if(e.keyCode==13)
      $("button").click()(function(){
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) {
                return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }
      })
    });
});
$(document).ready(function() {
    $("button").click(function() {
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) { return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }

    });
});

function cleartext(){
    document.getElementById("search_tag").value = "";
}

function clearimage() {
    document.getElementById("gif-place").removeChild(img);
}

function newQuestion(text){
    $('#question').html(function() { return text });
}

function getRandom() {
    return Math.floor((Math.random() * 25));
}

function display_image(search_term){
    counter = 0;
    console.log("search_term = " + search_term);
    if(counter == 0)
        ;
    else
        answer = search_term;
    var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=" + answer + "&api_key=dc6zaTOxFJmzC&limit=25");
        xhr.done(
            function(response) {
            temp = response;
            console.log(temp);
            console.log("success got data", response);
            //var select_gif = response.data[random].images.original;
            show_image(response);
        });
}

function show_image(image_object) {

    //console.log(height, width);
    random = getRandom();
    //var width = image_object.data[random].images.original.width;
    //var height = image_object.data[random].images.original.height;
    var source = image_object.data[random].images.original.url;
    //var resized = resize(height, width);

    //height = resized[0];
    //width = resized[1];
    //console.log(height, width);

    img = document.createElement("img");
    img.src = source;
    img.width = 400; //temp.data[random].images.original.width;
    img.height = 400; //temp.data[random].images.original.height;
    img.alt = "Guess the word!";
    document.getElementById("gif-place").appendChild(img);
}

// resize is deprecated bc we chose to have all gifs be the same size for consistency's sake
/*
 *function resize(height, width) {
 *
 *    console.log(height, width);
 *
 *    var MAX_HEIGHT = 400;
 *    var MAX_WIDTH = 400;
 *
 *    var gcd = get_gcd(height, width);
 *
 *    console.log("gcd = " + gcd);
 *    width = width / gcd;
 *    height = height / gcd;
 *
 *    var width_mult = MAX_WIDTH / width;
 *    var height_mult = MAX_HEIGHT / height;
 *    var multiplier = Math.min(width_mult, height_mult);
 *    console.log("multiplier = " + multiplier);
 *    width = width * multiplier;
 *    height = height * multiplier;
 *    console.log(height, width);
 *    return [height, width];
 *}
 */

function get_gcd (a, b) {
    if ( ! b) {
        return a;
    }
    return get_gcd(b, a % b);
};

/*
 *  THIS IS FOR SPACE
 *
 */

var sentences = {
    "A BARREL OF MONKEYS":[3],
    "IT'S RAINING CATS AND DOGS":[2],
    "AS STUBBORN AS AN OX":[4],
    "TALLER THAN A TREE":[3],
    "IT TAKES TWO TO TANGO":[4],
    "HAVE YOUR CAKE AND EAT IT TOO":[2],
    "IN THE HEAT OF THE MOMENT":[2],
    "KILL TWO BIRDS WITH ONE STONE":[2],
    "SPEAK OF THE DEVIL":[3],
    "STEAL SOMEONE'S THUNDER":[2],
    "STRAIGHT FROM THE HORSE'S MOUTH":[3],
    "A PICTURE PAINTS A THOUSAND WORDS":[5],
    "HIT THE NAIL ON THE HEAD":[2],
    "EVERY CLOUD HAS A SILVER LINING":[4],
    "DON'T JUDGE A BOOK BY IT'S COVER":[3],
    "EVERYTHING BUT THE KITCHEN SINK":[3],
    "EVERYBODY LOVES PUSHEEN":[2],
    "GREAT MINDS THINK ALIKE":[1],
    "BEAT AROUND THE BUSH":[3],
    "CRY OVER SPILLED MILK": [3],
    "STEAL SOMEONE'S THUNDER": [2],
    "DON'T PUT ALL YOUR EGGS IN ONE BASKET": [4]
}

/* selects a random sentence from the remaining possible sentences
 * and returns an array containing both the sentence as a string
 * and the indices of the words that should be converted to gifs
 */
function getRandomSentence(possible_sentences) {

    var key = getRandomKey(possible_sentences);
    var value = possible_sentences[key];
    // remove used key so we don't repeat puzzles (TODO)
    return [key, value];
}

function getRandomKey (sentences) {
    var result;
    var count = 0;
    for (var prop in sentences)
        if (Math.random() < 1/++count)
           result = prop;
    return result;
}

function display_puzzle () {
    /* gets random sentence
     * iterates through sentence:
     * if word is regular word: put it in body of html
     * if word should be gif:
     *          convert to gif, display in body of html
     *
     * create appropriate text boxes for answers
     * returns answers to puzzle, to be checked by other function
     */

    // sentence will be an array containing a string and an array of integers
    var sentence = getRandomSentence(sentences);
    var words = sentence[0].split(" ");
    console.log("sentence is" + words);
    console.log(words[0]);

    /*
     *for (index in sentence[1]) {
     *    answers.append(words[index]);
     *}
     */

    // redefines global variable 'answer'
    answer = words[sentence[1][0]];
    var answer_index = sentence[1][0];
    console.log("answer = " + answer);

    //var toDisplay = [];
    text_before = "";
    for(i = 0; i < answer_index; i++) {
        text_before = text_before + words[i] + " ";
    }
    $('#question-before').html(function() { return text_before});
    search_term = words[answer_index];
    display_image(search_term);
    text_after = "";
    for(i = answer_index + 1; i < words.length; i++) {
        text_after = text_after + words[i] + " ";
    }
    $('#question-after').html(function() { return text_after});

    delete sentences[sentence[0]];

    /*
     *for(i = 0; i < words.length; i++) {
     *    if (words[i] == answer) {
     *        console.log("word = " + words[i]);
     *        display_image(words[i]);
     *    }
     *    else
     *        newQuestion(words[i]);
     *
     *}
     */
}

function saveScore(val) {
    document.cookie = 'snum:'+val; //Set the cookie
}

function getScore() {
    var start = document.cookie.indexOf('snum:'); //Get the location of the cookie value
    var stop = document.cookie.indexOf(';'); //Get the end of the cookie value

    return document.cookie.substring(start+5, stop); //Return the value of the cookie (+5 because 'snum:' is 5 chars long)
}

<commit_msg>removed console.log() from js so people don't cheatgit add .<commit_after>var temp;
var random;
var img;
var answer = "CATS";
var text_before = "IT'S RAINING";
var text_after = "AND DOGS";
var val;

// This function is called when the user submits an answer
//

$(document).ready(function(){
    $('#search_tag').keypress(function(e){
      if(e.keyCode==13)
      $("button").click()(function(){
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) {
                return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }
      })
    });
});
$(document).ready(function() {
    $("button").click(function() {
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) { return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }

    });
});

function cleartext(){
    document.getElementById("search_tag").value = "";
}

function clearimage() {
    document.getElementById("gif-place").removeChild(img);
}

function newQuestion(text){
    $('#question').html(function() { return text });
}

function getRandom() {
    return Math.floor((Math.random() * 25));
}

function display_image(search_term){
    counter = 0;
    //console.log("search_term = " + search_term);
    if(counter == 0)
        ;
    else
        answer = search_term;
    var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=" + answer + "&api_key=dc6zaTOxFJmzC&limit=25");
        xhr.done(
            function(response) {
            temp = response;
            //console.log(temp);
            //console.log("success got data", response);
            //var select_gif = response.data[random].images.original;
            show_image(response);
        });
}

function show_image(image_object) {

    //console.log(height, width);
    random = getRandom();
    //var width = image_object.data[random].images.original.width;
    //var height = image_object.data[random].images.original.height;
    var source = image_object.data[random].images.original.url;
    //var resized = resize(height, width);

    //height = resized[0];
    //width = resized[1];
    //console.log(height, width);

    img = document.createElement("img");
    img.src = source;
    img.width = 400; //temp.data[random].images.original.width;
    img.height = 400; //temp.data[random].images.original.height;
    img.alt = "Guess the word!";
    document.getElementById("gif-place").appendChild(img);
}

// resize is deprecated bc we chose to have all gifs be the same size for consistency's sake
/*
 *function resize(height, width) {
 *
 *    console.log(height, width);
 *
 *    var MAX_HEIGHT = 400;
 *    var MAX_WIDTH = 400;
 *
 *    var gcd = get_gcd(height, width);
 *
 *    console.log("gcd = " + gcd);
 *    width = width / gcd;
 *    height = height / gcd;
 *
 *    var width_mult = MAX_WIDTH / width;
 *    var height_mult = MAX_HEIGHT / height;
 *    var multiplier = Math.min(width_mult, height_mult);
 *    console.log("multiplier = " + multiplier);
 *    width = width * multiplier;
 *    height = height * multiplier;
 *    console.log(height, width);
 *    return [height, width];
 *}
 */

function get_gcd (a, b) {
    if ( ! b) {
        return a;
    }
    return get_gcd(b, a % b);
};

/*
 *  THIS IS FOR SPACE
 *
 */

var sentences = {
    "A BARREL OF MONKEYS":[3],
    "IT'S RAINING CATS AND DOGS":[2],
    "AS STUBBORN AS AN OX":[4],
    "TALLER THAN A TREE":[3],
    "IT TAKES TWO TO TANGO":[4],
    "HAVE YOUR CAKE AND EAT IT TOO":[2],
    "IN THE HEAT OF THE MOMENT":[2],
    "KILL TWO BIRDS WITH ONE STONE":[2],
    "SPEAK OF THE DEVIL":[3],
    "STEAL SOMEONE'S THUNDER":[2],
    "STRAIGHT FROM THE HORSE'S MOUTH":[3],
    "A PICTURE PAINTS A THOUSAND WORDS":[5],
    "HIT THE NAIL ON THE HEAD":[2],
    "EVERY CLOUD HAS A SILVER LINING":[4],
    "DON'T JUDGE A BOOK BY IT'S COVER":[3],
    "EVERYTHING BUT THE KITCHEN SINK":[3],
    "EVERYBODY LOVES PUSHEEN":[2],
    "GREAT MINDS THINK ALIKE":[1],
    "BEAT AROUND THE BUSH":[3],
    "CRY OVER SPILLED MILK": [3],
    "STEAL SOMEONE'S THUNDER": [2],
    "DON'T PUT ALL YOUR EGGS IN ONE BASKET": [4]
}

/* selects a random sentence from the remaining possible sentences
 * and returns an array containing both the sentence as a string
 * and the indices of the words that should be converted to gifs
 */
function getRandomSentence(possible_sentences) {

    var key = getRandomKey(possible_sentences);
    var value = possible_sentences[key];
    // remove used key so we don't repeat puzzles (TODO)
    return [key, value];
}

function getRandomKey (sentences) {
    var result;
    var count = 0;
    for (var prop in sentences)
        if (Math.random() < 1/++count)
           result = prop;
    return result;
}

function display_puzzle () {
    /* gets random sentence
     * iterates through sentence:
     * if word is regular word: put it in body of html
     * if word should be gif:
     *          convert to gif, display in body of html
     *
     * create appropriate text boxes for answers
     * returns answers to puzzle, to be checked by other function
     */

    // sentence will be an array containing a string and an array of integers
    var sentence = getRandomSentence(sentences);
    var words = sentence[0].split(" ");
    //console.log("sentence is" + words);
    //console.log(words[0]);

    /*
     *for (index in sentence[1]) {
     *    answers.append(words[index]);
     *}
     */

    // redefines global variable 'answer'
    answer = words[sentence[1][0]];
    var answer_index = sentence[1][0];
    //console.log("answer = " + answer);

    //var toDisplay = [];
    text_before = "";
    for(i = 0; i < answer_index; i++) {
        text_before = text_before + words[i] + " ";
    }
    $('#question-before').html(function() { return text_before});
    search_term = words[answer_index];
    display_image(search_term);
    text_after = "";
    for(i = answer_index + 1; i < words.length; i++) {
        text_after = text_after + words[i] + " ";
    }
    $('#question-after').html(function() { return text_after});

    delete sentences[sentence[0]];

    /*
     *for(i = 0; i < words.length; i++) {
     *    if (words[i] == answer) {
     *        console.log("word = " + words[i]);
     *        display_image(words[i]);
     *    }
     *    else
     *        newQuestion(words[i]);
     *
     *}
     */
}

function saveScore(val) {
    document.cookie = 'snum:'+val; //Set the cookie
}

function getScore() {
    var start = document.cookie.indexOf('snum:'); //Get the location of the cookie value
    var stop = document.cookie.indexOf(';'); //Get the end of the cookie value

    return document.cookie.substring(start+5, stop); //Return the value of the cookie (+5 because 'snum:' is 5 chars long)
}

<|endoftext|>


<commit_before>import $ from 'jquery';
import _ from 'underscore';
import '../../../lib/select2';
import app from '../../../app';
import loadTemplate from '../../../utils/loadTemplate';
import baseView from '../../baseVw';
import Listing from '../../../models/listing/Listing';
import ShippingOptions from './ShippingOptions';
import ShippingAddress from '../../../models/settings/ShippingAddress';

export default class extends baseView {
  constructor(options = {}) {
    super(options);
    this.options = options;

    if (!this.model || !(this.model instanceof Listing)) {
      throw new Error('Please provide a listing model');
    }

    this.validOptions = [];

    const userAddresses = app.settings.get('shippingAddresses');
    this.selectedAddress = this.selectedAddress || userAddresses.length ? userAddresses.at(0) : '';

    this.listenTo(app.settings.get('shippingAddresses'), 'update', (col) => {
      // If all the addresses were deleted, set the selection to blank.
      if (!col.models.length) {
        this.selectedAddress = '';
      } else {
        // If the old selected address doesn't exist any more, select the first address and set the
        // selection to the first valid value.
        this.selectedAddress = userAddresses.get(this.selectedAddress) ?
          this.selectedAddress : userAddresses.at(0);
      }
      this.render();
    });
  }

  className() {
    return 'shipping';
  }

  events() {
    return {
      'change #shippingAddress': 'changeShippingAddress',
    };
  }

  get selectedOption() {
    return this._selectedOption;
  }

  set selectedOption(opts) {
    if (!_.isEqual(this._selectedOption, opts)) {
      this._selectedOption = opts;
      this.trigger('shippingOptionSelected', opts);
    }
  }

  extractValidOptions(address) {
    // Any time the country is changed, the options valid for that country need to be extracted.
    if (address !== '' && !address instanceof ShippingAddress) {
      throw new Error('The address must be blank or an instance of the ShippingAddress model.');
    }

    const validOptions = [];
    const countryCode = address ? address.get('country') : '';

    const extractedOptions = this.model.get('shippingOptions').toJSON().filter((option) =>
      option.regions.includes(countryCode) || option.regions.includes('ALL'));

    if (extractedOptions.length) {
      extractedOptions.forEach(option => {
        if (option.type === 'LOCAL_PICKUP') {
          // local pickup options need a service with a name and price
          option.services[0] = { name: app.polyglot.t('purchase.localPickup'), price: 0 };
        }
        option.services = _.sortBy(option.services, 'price');
        option.services.forEach(optionService => {
          validOptions.push({
            ...optionService,
            name: option.name,
            service: optionService.name,
          });
        });
      });
    }

    return validOptions;
  }

  get selectedAddress() {
    return this._selectedAddress;
  }

  set selectedAddress(address) {
    if (this._selectedAddress && _.isEqual(this._selectedAddress, address)) return;

    let validOptions = [];

    // if the selected address has a new country, extract the valid shipping options.
    if (address && address.get('country') !== this.country) {
      validOptions = this.extractValidOptions(address);
    }

    this._selectedAddress = address;

    if (validOptions.length) {
      // If the previously selected shipping option is no longer valid, select the first valid
      // shipping option. this.selectionOption only has a name and service, as that's the expected
      // data for the server, the validOptions have additional data in them.
      const isSelectedValid = this.selectedOption && this.selectedOption.name &&
        !!validOptions.filter(option => option.name === this.selectedOption.name &&
          option.service === this.selectedOption.service).length;

      if (!isSelectedValid) {
        this.selectedOption = {
          name: validOptions[0].name,
          service: validOptions[0].service,
        };
      }
    } else {
      this.selectedOption = { name: '', service: '' };
    }

    if (this.shippingOptions) {
      this.shippingOptions.validOptions = validOptions;
      this.shippingOptions.selectedOption = this.selectedOption;
      this.shippingOptions.render();
    }

    this.validOptions = validOptions;
  }

  changeShippingAddress(e) {
    const index = $(e.target).val();
    this.selectedAddress = app.settings.get('shippingAddresses').at(index);
  }

  render() {
    const userAddresses = app.settings.get('shippingAddresses');

    const selectedAddressIndex = this.selectedAddress && userAddresses.length ?
      userAddresses.indexOf(this.selectedAddress) : '';

    loadTemplate('modals/purchase/shipping.html', t => {
      this.$el.html(t({
        userAddresses: userAddresses.toJSON(),
        selectedAddressIndex,
      }));
    });
    this.$('#shippingAddress').select2({
      // disables the search box
      minimumResultsForSearch: Infinity,
    });

    if (this.shippingOptions) this.shippingOptions.remove();
    this.shippingOptions = this.createChild(ShippingOptions, {
      model: this.model,
      validOptions: this.validOptions,
      selectedOption: this.selectedOption,
    });
    this.listenTo(this.shippingOptions, 'shippingOptionSelected', ((opts) => {
      this.selectedOption = opts;
    }));

    this.$('.js-shippingOptionsWrapper').append(this.shippingOptions.render().el);

    return this;
  }
}
<commit_msg>code cleanup<commit_after>import $ from 'jquery';
import _ from 'underscore';
import '../../../lib/select2';
import app from '../../../app';
import loadTemplate from '../../../utils/loadTemplate';
import baseView from '../../baseVw';
import Listing from '../../../models/listing/Listing';
import ShippingOptions from './ShippingOptions';
import ShippingAddress from '../../../models/settings/ShippingAddress';

export default class extends baseView {
  constructor(options = {}) {
    super(options);
    this.options = options;

    if (!this.model || !(this.model instanceof Listing)) {
      throw new Error('Please provide a listing model');
    }

    this.validOptions = [];

    const userAddresses = app.settings.get('shippingAddresses');
    this.selectedAddress = userAddresses.at(0) || '';

    this.listenTo(app.settings.get('shippingAddresses'), 'update', (col) => {
      // If all the addresses were deleted, set the selection to blank.
      if (!col.models.length) {
        this.selectedAddress = '';
      } else {
        // If the old selected address doesn't exist any more, select the first address and set the
        // selection to the first valid value.
        this.selectedAddress = userAddresses.get(this.selectedAddress) ?
          this.selectedAddress : userAddresses.at(0);
      }
      this.render();
    });
  }

  className() {
    return 'shipping';
  }

  events() {
    return {
      'change #shippingAddress': 'changeShippingAddress',
    };
  }

  get selectedOption() {
    return this._selectedOption;
  }

  set selectedOption(opts) {
    if (!_.isEqual(this._selectedOption, opts)) {
      this._selectedOption = opts;
      this.trigger('shippingOptionSelected', opts);
    }
  }

  extractValidOptions(address) {
    // Any time the country is changed, the options valid for that country need to be extracted.
    if (address !== '' && !address instanceof ShippingAddress) {
      throw new Error('The address must be blank or an instance of the ShippingAddress model.');
    }

    const validOptions = [];
    const countryCode = address ? address.get('country') : '';

    const extractedOptions = this.model.get('shippingOptions').toJSON().filter((option) =>
      option.regions.includes(countryCode) || option.regions.includes('ALL'));

    if (extractedOptions.length) {
      extractedOptions.forEach(option => {
        if (option.type === 'LOCAL_PICKUP') {
          // local pickup options need a service with a name and price
          option.services[0] = { name: app.polyglot.t('purchase.localPickup'), price: 0 };
        }
        option.services = _.sortBy(option.services, 'price');
        option.services.forEach(optionService => {
          validOptions.push({
            ...optionService,
            name: option.name,
            service: optionService.name,
          });
        });
      });
    }

    return validOptions;
  }

  get selectedAddress() {
    return this._selectedAddress;
  }

  set selectedAddress(address) {
    if (this._selectedAddress && _.isEqual(this._selectedAddress, address)) return;

    let validOptions = [];

    // if the selected address has a new country, extract the valid shipping options.
    if (address && address.get('country') !== this.country) {
      validOptions = this.extractValidOptions(address);
    }

    this._selectedAddress = address;

    if (validOptions.length) {
      // If the previously selected shipping option is no longer valid, select the first valid
      // shipping option. this.selectionOption only has a name and service, as that's the expected
      // data for the server, the validOptions have additional data in them.
      const isSelectedValid = this.selectedOption && this.selectedOption.name &&
        !!validOptions.filter(option => option.name === this.selectedOption.name &&
          option.service === this.selectedOption.service).length;

      if (!isSelectedValid) {
        this.selectedOption = {
          name: validOptions[0].name,
          service: validOptions[0].service,
        };
      }
    } else {
      this.selectedOption = { name: '', service: '' };
    }

    if (this.shippingOptions) {
      this.shippingOptions.validOptions = validOptions;
      this.shippingOptions.selectedOption = this.selectedOption;
      this.shippingOptions.render();
    }

    this.validOptions = validOptions;
  }

  changeShippingAddress(e) {
    const index = $(e.target).val();
    this.selectedAddress = app.settings.get('shippingAddresses').at(index);
  }

  render() {
    const userAddresses = app.settings.get('shippingAddresses');

    const selectedAddressIndex = this.selectedAddress && userAddresses.length ?
      userAddresses.indexOf(this.selectedAddress) : '';

    loadTemplate('modals/purchase/shipping.html', t => {
      this.$el.html(t({
        userAddresses: userAddresses.toJSON(),
        selectedAddressIndex,
      }));
    });
    this.$('#shippingAddress').select2({
      // disables the search box
      minimumResultsForSearch: Infinity,
    });

    if (this.shippingOptions) this.shippingOptions.remove();
    this.shippingOptions = this.createChild(ShippingOptions, {
      model: this.model,
      validOptions: this.validOptions,
      selectedOption: this.selectedOption,
    });
    this.listenTo(this.shippingOptions, 'shippingOptionSelected', ((opts) => {
      this.selectedOption = opts;
    }));

    this.$('.js-shippingOptionsWrapper').append(this.shippingOptions.render().el);

    return this;
  }
}
<|endoftext|>


<commit_before>// Sencha Touch App Tools
var path = require('path');

var create = require('../lib/create');
var live = require('../lib/live');
var serve = require('../lib/serve');

module.exports = {
    // CLI commands
    version: function(options) {
        console.info(options.pkg.name + " " + options.pkg.version);
    },
    settings: function(options) {
        console.info(options);
    },
    help: function(options) {
        var appName = (options.pkg && options.pkg.name) || path.basename(process.argv[1]);
        console.log(appName + ' create [domain] [AppName] - Creates and compiles a new Sencha Touch / PhoneGap 3.x app. Adds live update client.');
        console.log(appName + ' live add    - Add embedded live update client to existing Sencha Touch or PhoneGap project.');
        console.log(appName + ' live remove - Removes live update client from a Sencha Touch or PhoneGap project.');
        console.log(appName + ' live update - Updates live update client with latest version.');
        console.log(appName + ' serve       - Runs live update server for Sencha Touch or PhoneGap project.');
        console.log(appName + ' version     - Display app name & version');
        console.log(appName + ' settings    - Display configured options');
    },

    // LIB commands
    create: create,

    live: {
        // Add live client to project
        add: function(options) {
            live.add();

            console.info("Now rebuild using ...".lightGreen);
            console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
        },

        // Remove live client from project
        remove: function(options) {
            live.remove();

            console.info("Now rebuild using ...".lightGreen);
            console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
        },

        // Update live client to latest version
        update: function(options) {
            live.update();

            console.info("Now rebuild using ...".lightGreen);
            console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
        }

    },
    serve: serve,
    server: serve   // Someone's sure to misspell it :) .
};<commit_msg>Removed 'live' command word prefix for add/remove/update CLI commands<commit_after>// Sencha Touch App Tools
var path = require('path');

var create = require('../lib/create');
var live = require('../lib/live');
var serve = require('../lib/serve');

module.exports = {
    // CLI commands
    version: function(options) {
        console.info(options.pkg.name + " " + options.pkg.version);
    },
    settings: function(options) {
        console.info(options);
    },
    help: function(options) {
        var appName = (options.pkg && options.pkg.name) || path.basename(process.argv[1]);
        console.log(appName + ' create [domain] [AppName] - Creates and compiles a new Sencha Touch / PhoneGap 3.x app with "live edit" client.');
        console.log(appName + ' add      - Add "live edit" client to existing Sencha Touch or PhoneGap project.');
        console.log(appName + ' remove   - Removes "live edit" client from a Sencha Touch or PhoneGap project.');
        console.log(appName + ' update   - Updates "live edit" client with latest version.');
        console.log(appName + ' serve    - Runs live edit server for Sencha Touch or PhoneGap project.');
        console.log(appName + ' version  - Display app name & version');
        console.log(appName + ' settings - Display configured options');
    },

    // LIB commands
    create: create,

    // Add live client to project
    add: function(options) {
        live.add();

        console.info("Now rebuild using ...".lightGreen);
        console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
    },

    // Remove live client from project
    remove: function(options) {
        live.remove();

        console.info("Now rebuild using ...".lightGreen);
        console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
    },

    // Update live client to latest version
    update: function(options) {
        live.update();

        console.info("Now rebuild using ...".lightGreen);
        console.info(("$ " + options.senchaCmd + " app build native").lightGreen);
    },

    serve: serve,
    server: serve   // Someone's sure to misspell it :) .
};<|endoftext|>


<commit_before>//Module wrapper for the whole Pex library.
define("pex/Pex", [
    "pex/cameras/Cameras",
    "pex/core/Core",
    "pex/geom/Geom",
    "pex/gui/GUI",
    "pex/materials/Materials",
    "pex/sys/Sys",
    "pex/util/Util",
  ],
  function(Cameras, Core, Geom, GUI, Materials, Sys, Util) {
    var Pex = {
      Cameras : Cameras,
      Core : Core,
      Geom : Geom,
      GUI : GUI,
      Materials : Materials,
      Sys : Sys,
      Util : Util
    }
    return Pex;
  }
)<commit_msg>Updated Pex package<commit_after>//Module wrapper for the whole Pex library.
define("pex/Pex", [
    "pex/behaviors/Behaviors",
    "pex/cameras/Cameras",
    "pex/core/Core",
    "pex/geom/Geom",
    "pex/gui/GUI",
    "pex/materials/Materials",
    "pex/sys/Sys",
    "pex/util/Util",
  ],
  function(Behaviors, Cameras, Core, Geom, GUI, Materials, Sys, Util) {
    var Pex = {
      Behaviors : Behaviors,
      Cameras : Cameras,
      Core : Core,
      Geom : Geom,
      GUI : GUI,
      Materials : Materials,
      Sys : Sys,
      Util : Util
    }
    return Pex;
  }
)<|endoftext|>


<commit_before>var child_process = require('child_process')

function exec(command)
{
	return child_process.execSync(command).toString().trim()
}

let metadata_branch_exists = false

try
{
	exec('git rev-parse --verify update-metadata')
	metadata_branch_exists = true
}
catch (error)
{
	if (error.message.indexOf('fatal: Needed a single revision') === -1)
	{
		throw error
	}
}

if (!metadata_branch_exists)
{
	process.exit(0)
}

console.log(exec('hub pull-request -m "Phone number medatada update" -b halt-hammerzeit/libphonenumber-js:master -h update-metadata'))<commit_msg>Added comments on `hub` tokens<commit_after>// In order for this script to work:
//
// * Install `hub`: `brew install hub`
// * Create a "Personal Access Token" in GitHub account settings (just "repo_public" would be enough)
// * Tell `hub` to use the token for creating GitHub pull requests: `echo "---\ngithub.com:\n- protocol: https\n  user: GITHUB_USERNAME\n  oauth_token: TOKEN" >> ~/.config/hub`

var child_process = require('child_process')

function exec(command)
{
	return child_process.execSync(command).toString().trim()
}

let metadata_branch_exists = false

try
{
	exec('git rev-parse --verify update-metadata')
	metadata_branch_exists = true
}
catch (error)
{
	if (error.message.indexOf('fatal: Needed a single revision') === -1)
	{
		throw error
	}
}

if (!metadata_branch_exists)
{
	process.exit(0)
}

console.log(exec('hub pull-request -m "Phone number medatada update" -b halt-hammerzeit/libphonenumber-js:master -h update-metadata'))<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Sep 05 2013 14:14:49 GMT-0400 (EDT)

module.exports = function(config) {
	config.set({

		// base path, that will be used to resolve files and exclude
		basePath: "./",

		// frameworks to use
		frameworks: ["qunit"],

		// list of files / patterns to load in the browser
		files: [
			"test/d3.min.js",
			"src/cal-heatmap.js",
			"test/jquery-1.9.1.js",
			"test/test.js",
			{
				pattern: "test/data/data.*",
				included: false
			}
		],

		// list of files to exclude
		exclude: [

		],

		// test results reporter to use
		// possible values: "dots", "progress", "junit", "growl", "coverage"
		reporters: ["progress", "coverage"],

		// web server port
		port: 9876,

		// enable / disable colors in the output (reporters and logs)
		colors: true,

		// level of logging
		// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
		logLevel: config.LOG_INFO,

		// enable / disable watching file and executing tests whenever any file changes
		autoWatch: true,

		preprocessors: {
			// source files, that you wanna generate coverage for
			// do not include tests or libraries
			// (these files will be instrumented by Istanbul)
			"src/*.js": ["coverage"]
		},

		coverageReporter: {
			type: "lcov",
			dir: "coverage/"
		},

		// Start these browsers, currently available:
		// - Chrome
		// - ChromeCanary
		// - Firefox
		// - Opera
		// - Safari (only Mac)
		// - PhantomJS
		// - IE (only Windows)
		browsers: ["PhantomJS"],

		// If browser does not capture in given timeout [ms], kill it
		captureTimeout: 5000,

		// Continuous Integration mode
		// if true, it capture browsers, run tests and exit
		singleRun: false
	});
};
<commit_msg>Fix jQuery path in Karma config<commit_after>// Karma configuration
// Generated on Thu Sep 05 2013 14:14:49 GMT-0400 (EDT)

module.exports = function(config) {
	config.set({

		// base path, that will be used to resolve files and exclude
		basePath: "./",

		// frameworks to use
		frameworks: ["qunit"],

		// list of files / patterns to load in the browser
		files: [
			"test/d3.min.js",
			"src/cal-heatmap.js",
			"node_modules/jquery/jquery.min.js",
			"test/test.js",
			{
				pattern: "test/data/data.*",
				included: false
			}
		],

		// list of files to exclude
		exclude: [

		],

		// test results reporter to use
		// possible values: "dots", "progress", "junit", "growl", "coverage"
		reporters: ["progress", "coverage"],

		// web server port
		port: 9876,

		// enable / disable colors in the output (reporters and logs)
		colors: true,

		// level of logging
		// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
		logLevel: config.LOG_INFO,

		// enable / disable watching file and executing tests whenever any file changes
		autoWatch: true,

		preprocessors: {
			// source files, that you wanna generate coverage for
			// do not include tests or libraries
			// (these files will be instrumented by Istanbul)
			"src/*.js": ["coverage"]
		},

		coverageReporter: {
			type: "lcov",
			dir: "coverage/"
		},

		// Start these browsers, currently available:
		// - Chrome
		// - ChromeCanary
		// - Firefox
		// - Opera
		// - Safari (only Mac)
		// - PhantomJS
		// - IE (only Windows)
		browsers: ["PhantomJS"],

		// If browser does not capture in given timeout [ms], kill it
		captureTimeout: 5000,

		// Continuous Integration mode
		// if true, it capture browsers, run tests and exit
		singleRun: false
	});
};
<|endoftext|>


<commit_before>/**
 * Created by timadamson on 8/22/17.
 */

/**
 * An App self adds 3 camera streams, and the controlers to move the robot
 */

function init() {
    var arm_div = document.querySelectorAll('.js_arm_div');
    this.app = new App();
    var self = this;

    app.ros.on('connection', function () {
        console.log("We are connected!");
    });

    var elmnt = document.getElementById("camera1");

    var cameraWidth = "342";
    var cameraHeight = "342";

    var camera1Name = "camera1";
    var camera2Name = "camera2";

    var cam1Div = document.getElementById("camera1");
    var cam2Div = document.getElementById("camera2");

    var cam1X = "50";
    var cam1Y = "50";

    var cam2X = "50";
    var cam2Y = "50";

    var upBTN1 = document.createElement("button");
    upBTN1.innerHTML="";
    upBTN1.id='up';
    upBTN1.title='\u2191Up\u2191';
    upBTN1.className = "button";
    upBTN1.style.left=(cameraWidth - 80)/2 + "px";
    upBTN1.style.top= cameraHeight/4  + 10 + "px";
    upBTN1.value = `${camera1Name},${0},${-cam1Y}`;
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(upBTN1);

    var downBTN1 = document.createElement("button");
    downBTN1.innerHTML = "";
    downBTN1.id='down';
    downBTN1.title='\u2193Down\u2193';
    downBTN1.className = "button";
    downBTN1.style.left=(cameraWidth - 80)/2 + "px";
    downBTN1.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN1);

    var leftBTN1 = document.createElement("button");
    leftBTN1.innerHTML = "";
    leftBTN1.id='left';
    leftBTN1.title='\u2190Left\u2190';
    leftBTN1.className = "button";
    leftBTN1.style.left=15 + "px";
    leftBTN1.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN1);

    var rightBTN1 = document.createElement("button");
    rightBTN1.innerHTML = "";
    rightBTN1.id='right';
    rightBTN1.title='\u2192Right\u2192';
    rightBTN1.className = "button";
    rightBTN1.style.left=(cameraWidth - 37)+ "px";
    rightBTN1.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN1);

    var rotaterightBTN1 = document.createElement("button");
    rotaterightBTN1.innerHTML = "";
    rotaterightBTN1.id = 'rotateRight';
    rotaterightBTN1.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN1.className = "button";
    rotaterightBTN1.style.left =(cameraWidth -103)+ "px";
    rotaterightBTN1.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN1.style.height = 80 + "px";
    body.appendChild(rotaterightBTN1);

    var rotateleftBTN1 = document.createElement("button");
    rotateleftBTN1.innerHTML = "";
    rotateleftBTN1.id = 'rotateLeft';
    rotateleftBTN1.title = '\u21BARotate Left\u21BA';
    rotateleftBTN1.className = "button";
    rotateleftBTN1.style.width = 65 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    rotateleftBTN1.style.left =  70 + "px";
    rotateleftBTN1.style.top = (cameraHeight- (-90))/2 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    body.appendChild(rotateleftBTN1);

    var upBTN2 = document.createElement("button");
    upBTN2.innerHTML="";
    upBTN2.id='up2';
    upBTN2.title='\u2191Up\u2191';
    upBTN2.style.left=(cameraWidth - 100)*2 + "px";
    upBTN2.style.top= cameraHeight/4  + 10 + "px";
    body.appendChild(upBTN2);

    var downBTN2 = document.createElement("button");
    downBTN2.innerHTML = "";
    downBTN2.id='down2';
    downBTN2.title='\u2193Down\u2193';
    downBTN2.className = "button";
    downBTN2.style.left=(cameraWidth - 100)*2 + "px";
    downBTN2.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN2);

    var leftBTN2 = document.createElement("button");
    leftBTN2.innerHTML = "";
    leftBTN2.id='left2';
    leftBTN2.title='\u2190Left\u2190';
    leftBTN2.className = "button";
    leftBTN2.style.left=(cameraWidth- (-20)) + "px";
    leftBTN2.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN2);

    var rightBTN2 = document.createElement("button");
    rightBTN2.innerHTML = "";
    rightBTN2.id='right2';
    rightBTN2.title='\u2192Right\u2192';
    rightBTN2.className = "button";
    rightBTN2.style.left=(cameraWidth*2 - (33)) + "px";
    rightBTN2.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN2);

    var rotaterightBTN2 = document.createElement("button");
    rotaterightBTN2.innerHTML = "";
    rotaterightBTN2.id = 'rotateRight2';
    rotaterightBTN2.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN2.className = "button";
    rotaterightBTN2.style.left =(cameraWidth*2- (105)) + "px";
    rotaterightBTN2.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN2.style.height = 80 + "px";
    body.appendChild(rotaterightBTN2);

    var rotateleftBTN2 = document.createElement("button");
    rotateleftBTN2.innerHTML = "";
    rotateleftBTN2.id = 'rotateLeft2';
    rotateleftBTN2.title = '\u21BARotate Left\u21BA';
    rotateleftBTN2.className = "button";
    rotateleftBTN2.style.left =  (cameraWidth- (-74)) + "px";
    rotateleftBTN2.style.top = (cameraHeight- (-90))/2 + "px";
    body.appendChild(rotateleftBTN2);

    var buttons = document.querySelectorAll(".button");
    buttons.forEach(function (element) {
        element.addEventListener ("click", pubMoveMsg);
    });

    function pubMoveMsg() {
        var divData = this.value.split(",");
        console.log(divData);
        self.app.arm.moveArmByDelta(divData[1], divData[2], divData[0]);
    }
}<commit_msg>progress<commit_after>/**
 * Created by timadamson on 8/22/17.
 */

/**
 * An App self adds 3 camera streams, and the controlers to move the robot
 */

function init() {
    var arm_div = document.querySelectorAll('.js_arm_div');
    this.app = new App();
    var self = this;

    app.ros.on('connection', function () {
        console.log("We are connected!");
    });

    var elmnt = document.getElementById("camera1");

    var cameraWidth = "342";
    var cameraHeight = "342";

    var camera1Name = "camera1";
    var camera2Name = "camera2";

    var cam1Div = document.getElementById("camera1");
    var cam2Div = document.getElementById("camera2");

    var cam1X = "50";
    var cam1Y = "50";

    var cam2X = "50";
    var cam2Y = "50";

    var upBTN1 = document.createElement("button");
    upBTN1.innerHTML="";
    upBTN1.id='up';
    upBTN1.title='\u2191Up\u2191';
    upBTN1.className = "button";
    upBTN1.style.left=(cameraWidth - 80)/2 + "px";
    upBTN1.style.top= cameraHeight/4  + 10 + "px";
    upBTN1.value = `${camera1Name},${0},${-cam1Y}`;
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(upBTN1);

    var downBTN1 = document.createElement("button");
    downBTN1.innerHTML = "";
    downBTN1.id='down';
    downBTN1.title='\u2193Down\u2193';
    downBTN1.className = "button";
    downBTN1.style.left=(cameraWidth - 80)/2 + "px";
    downBTN1.style.top= (cameraHeight- (-50))+ "px";
    downBTN1.value = `${camera1Name},${0},${cam1Y}`;
    body.appendChild(downBTN1);

    var leftBTN1 = document.createElement("button");
    leftBTN1.innerHTML = "";
    leftBTN1.id='left';
    leftBTN1.title='\u2190Left\u2190';
    leftBTN1.className = "button";
    leftBTN1.style.left=15 + "px";
    leftBTN1.style.top=(cameraHeight- (-90))/2 + "px";
    leftBTN1.value = `${camera1Name},${-cam1X},${0}`;
    body.appendChild(leftBTN1);

    var rightBTN1 = document.createElement("button");
    rightBTN1.innerHTML = "";
    rightBTN1.id='right';
    rightBTN1.title='\u2192Right\u2192';
    rightBTN1.className = "button";
    rightBTN1.style.left=(cameraWidth - 37)+ "px";
    rightBTN1.style.top= (cameraHeight- (-90))/2 + "px";
    rightBTN1.value = `${camera1Name},${cam1X},${0}`;
    body.appendChild(rightBTN1);

    var rotaterightBTN1 = document.createElement("button");
    rotaterightBTN1.innerHTML = "";
    rotaterightBTN1.id = 'rotateRight';
    rotaterightBTN1.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN1.className = "button";
    rotaterightBTN1.style.left =(cameraWidth -103)+ "px";
    rotaterightBTN1.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN1.style.height = 80 + "px";
    body.appendChild(rotaterightBTN1);

    var rotateleftBTN1 = document.createElement("button");
    rotateleftBTN1.innerHTML = "";
    rotateleftBTN1.id = 'rotateLeft';
    rotateleftBTN1.title = '\u21BARotate Left\u21BA';
    rotateleftBTN1.className = "button";
    rotateleftBTN1.style.width = 65 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    rotateleftBTN1.style.left =  70 + "px";
    rotateleftBTN1.style.top = (cameraHeight- (-90))/2 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    body.appendChild(rotateleftBTN1);

    var upBTN2 = document.createElement("button");
    upBTN2.innerHTML="";
    upBTN2.id='up2';
    upBTN2.title='\u2191Up\u2191';
    upBTN2.style.left=(cameraWidth - 100)*2 + "px";
    upBTN2.style.top= cameraHeight/4  + 10 + "px";
    body.appendChild(upBTN2);

    var downBTN2 = document.createElement("button");
    downBTN2.innerHTML = "";
    downBTN2.id='down2';
    downBTN2.title='\u2193Down\u2193';
    downBTN2.className = "button";
    downBTN2.style.left=(cameraWidth - 100)*2 + "px";
    downBTN2.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN2);

    var leftBTN2 = document.createElement("button");
    leftBTN2.innerHTML = "";
    leftBTN2.id='left2';
    leftBTN2.title='\u2190Left\u2190';
    leftBTN2.className = "button";
    leftBTN2.style.left=(cameraWidth- (-20)) + "px";
    leftBTN2.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN2);

    var rightBTN2 = document.createElement("button");
    rightBTN2.innerHTML = "";
    rightBTN2.id='right2';
    rightBTN2.title='\u2192Right\u2192';
    rightBTN2.className = "button";
    rightBTN2.style.left=(cameraWidth*2 - (33)) + "px";
    rightBTN2.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN2);

    var rotaterightBTN2 = document.createElement("button");
    rotaterightBTN2.innerHTML = "";
    rotaterightBTN2.id = 'rotateRight2';
    rotaterightBTN2.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN2.className = "button";
    rotaterightBTN2.style.left =(cameraWidth*2- (105)) + "px";
    rotaterightBTN2.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN2.style.height = 80 + "px";
    body.appendChild(rotaterightBTN2);

    var rotateleftBTN2 = document.createElement("button");
    rotateleftBTN2.innerHTML = "";
    rotateleftBTN2.id = 'rotateLeft2';
    rotateleftBTN2.title = '\u21BARotate Left\u21BA';
    rotateleftBTN2.className = "button";
    rotateleftBTN2.style.left =  (cameraWidth- (-74)) + "px";
    rotateleftBTN2.style.top = (cameraHeight- (-90))/2 + "px";
    body.appendChild(rotateleftBTN2);

    var buttons = document.querySelectorAll(".button");
    buttons.forEach(function (element) {
        element.addEventListener ("click", pubMoveMsg);
    });

    function pubMoveMsg() {
        var divData = this.value.split(",");
        console.log(divData);
        self.app.arm.moveArmByDelta(divData[1], divData[2], divData[0]);
    }
}<|endoftext|>


<commit_before>var events      = require('events');
var util        = require('util');
var uuid        = require('uuid');
var DeviceDB    = require('./device-db');
var DeviceAuth  = require('./device-auth');
var CdifError   = require('./error').CdifError;
var DeviceError = require('./error').DeviceError;

function DeviceManager(mm) {
  this.deviceMap     = {};
  this.deviceDB      = new DeviceDB();
  this.deviceAuth    = new DeviceAuth(this.deviceDB);
  this.moduleManager = mm;

  this.moduleManager.on('deviceonline',  this.onDeviceOnline.bind(this));
  this.moduleManager.on('deviceoffline', this.onDeviceOffline.bind(this));
}

util.inherits(DeviceManager, events.EventEmitter);

DeviceManager.prototype.onDeviceOnline = function(cdifDevice, m) {
  //TODO: validate device spec schema
  var _this = this;
  cdifDevice.module = m;
  cdifDevice.auth = this.deviceAuth;

  cdifDevice.getHWAddress(function(err, addr) {
    var hwAddr;
    var deviceUUID;
    if(!err) {
      hwAddr = addr;
      _this.deviceDB.getDeviceUUIDFromHWAddr(hwAddr, function(err, data) {
        if (err) {
          console.error(err);
          return;
        }
        if (!data) {
          deviceUUID = uuid.v4();
          _this.deviceDB.setDeviceUUID(hwAddr, deviceUUID, function(err) {
            if (err) {
              console.error('cannot insert address record');
            }
          });
        } else {
          deviceUUID = data.uuid;
        }
        _this.deviceDB.setSpecForDevice(hwAddr, JSON.stringify(cdifDevice.spec));
        // TODO: handle device offline and purge dead devices
        cdifDevice.hwAddr = hwAddr;
        cdifDevice.deviceID = deviceUUID;
        if (!_this.deviceMap[deviceUUID]) {
          _this.deviceMap[deviceUUID] = cdifDevice;
        }
        cdifDevice.on('authorizeredirect', _this.onOAuthAuthorizeRedirect.bind(_this));
      });
    } else {
      console.error('cannot get HW address for device: ' + cdifDevice.spec.device.friendlyName);
    }
  });
};

DeviceManager.prototype.onDeviceOffline = function(cdifDevice) {
  //TODO
};

DeviceManager.prototype.discoverAll = function(callback) {
  this.moduleManager.discoverAllDevices();
  callback(null);
};

DeviceManager.prototype.stopDiscoverAll = function(callback) {
  this.moduleManager.stopDiscoverAllDevices();
  callback(null);
};

DeviceManager.prototype.getDiscoveredDeviceList = function(callback) {
  var deviceList = {};
  for (var i in this.deviceMap) {
    var cdifDevice = this.deviceMap[i];
    if (cdifDevice.spec) {
      //this is ugly but the easiest way to handle this request
      var desc = JSON.parse(JSON.stringify(cdifDevice.spec));
      desc.device.serviceList = {};
      deviceList[i] = desc;
    }
  }
  callback(null, deviceList);
};

DeviceManager.prototype.ensureDeviceState = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (cdifDevice == null) {  // check null or undefined
    callback(new CdifError('device not found'));
    return;
  }
  if (cdifDevice.module.discoverState === 'discovering') {
    callback(new CdifError('in discovering'));
    return;
  }
  if (cdifDevice.connected === false) {
    callback(new CdifError('device not connected'));
    return;
  }
  if (cdifDevice.spec.device.userAuth === true) {
    this.deviceAuth.verifyAccess(cdifDevice.secret, token, callback);
  } else {
    callback(null);
  }
};

DeviceManager.prototype.connectDevice = function(deviceID, user, pass, callback) {
  var _this = this;
  var cdifDevice = this.deviceMap[deviceID];
  if (!cdifDevice) {
    callback(new CdifError('device not found'), null);
    return;
  }
  if (cdifDevice.module.discoverState === 'discovering') {
    callback(new CdifError('in discovering', null));
    return;
  }

  cdifDevice.connect(user, pass, function(err, secret) {
    if (err) {
      callback(err, null);
    } else {
      if (secret) {
        var token = _this.deviceAuth.generateToken(user, secret, function(err, data) {
          if (err) {
            callback(new CdifError('cannot generate access token'), null);
          } else {
            callback(null, {'device_access_token': data});
          }
        });
      } else {
        callback(null, null);
      }
      if (cdifDevice.spec.device.devicePresentation === true) {
        if (cdifDevice.connections === 1)
          _this.emit('presentation', cdifDevice.deviceID);
      }
    }
  });
};

DeviceManager.prototype.disconnectDevice = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.disconnect(callback);
    }
  });
};

DeviceManager.prototype.invokeDeviceAction = function(deviceID, serviceID, actionName, args, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      try {
        cdifDevice.deviceControl(serviceID, actionName, args, callback);
      } catch (e) {
        callback(new DeviceError(e.message), null); //framework won't throw
      }
    }
  });
};

DeviceManager.prototype.getDeviceSpec = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.getDeviceSpec(callback);
    }
  });
}

DeviceManager.prototype.getDeviceState = function(deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.getServiceStates(serviceID, callback);
    }
  });
};

DeviceManager.prototype.eventSubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.subscribeDeviceEvent(subscriber, serviceID, callback);
    }
  });
};

DeviceManager.prototype.eventUnsubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.unSubscribeDeviceEvent(subscriber, serviceID, callback);
    }
  });
};

DeviceManager.prototype.getDeviceSchema = function(deviceID, path, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.resolveSchemaFromPath(path, null, function(error, self, data) {
        if (!error) {
          callback(null, data);
        } else {
          callback(error, null);
        }
      });
    }
  });
};

DeviceManager.prototype.setDeviceOAuthAccessToken = function(deviceID, params, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (cdifDevice == null) {  // check null or undefined
    callback(new CdifError('device not found'));
    return;
  }
  cdifDevice.setOAuthAccessToken(params, callback);
};

DeviceManager.prototype.getDeviceRootUrl = function(deviceID, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (!cdifDevice) {
    callback(new CdifError('device not found'));
  } else {
    cdifDevice.getDeviceRootUrl(callback);
  }
};

DeviceManager.prototype.onOAuthAuthorizeRedirect = function(authorize_redirect_url, deviceID) {
  this.emit('authorizeredirect', authorize_redirect_url, deviceID);
};

module.exports = DeviceManager;
<commit_msg>make device manager interface async<commit_after>var events      = require('events');
var util        = require('util');
var uuid        = require('uuid');
var DeviceDB    = require('./device-db');
var DeviceAuth  = require('./device-auth');
var CdifError   = require('./error').CdifError;
var DeviceError = require('./error').DeviceError;

function DeviceManager(mm) {
  this.deviceMap     = {};
  this.deviceDB      = new DeviceDB();
  this.deviceAuth    = new DeviceAuth(this.deviceDB);
  this.moduleManager = mm;

  this.moduleManager.on('deviceonline',  this.onDeviceOnline.bind(this));
  this.moduleManager.on('deviceoffline', this.onDeviceOffline.bind(this));

  this.on('discoverall',     this.onDiscoverAll.bind(this));
  this.on('stopdiscoverall', this.onStopDiscoverAll.bind(this));
  this.on('devicelist',      this.OnGetDiscoveredDeviceList.bind(this));
  this.on('connect',         this.onConnectDevice.bind(this));
  this.on('disconnect',      this.onDisconnectDevice.bind(this));
  this.on('invokeaction',    this.onInvokeDeviceAction.bind(this));
  this.on('getspec',         this.onGetDeviceSpec.bind(this));
  this.on('devicestate',     this.onGetDeviceState.bind(this));
  this.on('subscribe',       this.onEventSubscribe.bind(this));
  this.on('unsubscribe',     this.onEventUnsubscribe.bind(this));
  this.on('getschema',       this.onGetDeviceSchema.bind(this));
  this.on('setoauthtoken',   this.onSetDeviceOAuthAccessToken.bind(this));
  this.on('getrooturl',      this.onGetDeviceRootUrl.bind(this));
}

util.inherits(DeviceManager, events.EventEmitter);

DeviceManager.prototype.onDeviceOnline = function(cdifDevice, m) {
  //TODO: validate device spec schema
  var _this = this;
  cdifDevice.module = m;
  cdifDevice.auth = this.deviceAuth;

  cdifDevice.getHWAddress(function(err, addr) {
    var hwAddr;
    var deviceUUID;
    if(!err) {
      hwAddr = addr;
      _this.deviceDB.getDeviceUUIDFromHWAddr(hwAddr, function(err, data) {
        if (err) {
          console.error(err);
          return;
        }
        if (!data) {
          deviceUUID = uuid.v4();
          _this.deviceDB.setDeviceUUID(hwAddr, deviceUUID, function(err) {
            if (err) {
              console.error('cannot insert address record');
            }
          });
        } else {
          deviceUUID = data.uuid;
        }
        _this.deviceDB.setSpecForDevice(hwAddr, JSON.stringify(cdifDevice.spec));
        // TODO: handle device offline and purge dead devices
        cdifDevice.hwAddr = hwAddr;
        cdifDevice.deviceID = deviceUUID;
        if (!_this.deviceMap[deviceUUID]) {
          _this.deviceMap[deviceUUID] = cdifDevice;
        }
        cdifDevice.on('authorizeredirect', _this.onOAuthAuthorizeRedirect.bind(_this));
      });
    } else {
      console.error('cannot get HW address for device: ' + cdifDevice.spec.device.friendlyName);
    }
  });
};

DeviceManager.prototype.onDeviceOffline = function(cdifDevice) {
  //TODO
};

DeviceManager.prototype.discoverAll = function(callback) {
  this.emit('discoverall', callback);
};

DeviceManager.prototype.onDiscoverAll = function(callback) {
  this.moduleManager.discoverAllDevices();
  callback(null);
};

DeviceManager.prototype.stopDiscoverAll = function(callback) {
  this.emit('stopdiscoverall', callback);
};

DeviceManager.prototype.onStopDiscoverAll = function(callback) {
  this.moduleManager.stopDiscoverAllDevices();
  callback(null);
};

DeviceManager.prototype.getDiscoveredDeviceList = function(callback) {
  this.emit('devicelist', callback);
};

DeviceManager.prototype.OnGetDiscoveredDeviceList = function(callback) {
  var deviceList = {};
  for (var i in this.deviceMap) {
    var cdifDevice = this.deviceMap[i];
    if (cdifDevice.spec) {
      //this is ugly but the easiest way to handle this request
      var desc = JSON.parse(JSON.stringify(cdifDevice.spec));
      desc.device.serviceList = {};
      deviceList[i] = desc;
    }
  }
  callback(null, deviceList);
};

DeviceManager.prototype.ensureDeviceState = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (cdifDevice == null) {  // check null or undefined
    callback(new CdifError('device not found'));
    return;
  }
  if (cdifDevice.module.discoverState === 'discovering') {
    callback(new CdifError('in discovering'));
    return;
  }
  if (cdifDevice.connected === false) {
    callback(new CdifError('device not connected'));
    return;
  }
  if (cdifDevice.spec.device.userAuth === true) {
    this.deviceAuth.verifyAccess(cdifDevice.secret, token, callback);
  } else {
    callback(null);
  }
};

DeviceManager.prototype.connectDevice = function(deviceID, user, pass, callback) {
  this.emit('connect', deviceID, user, pass, callback);
};

DeviceManager.prototype.onConnectDevice = function(deviceID, user, pass, callback) {
  var _this = this;
  var cdifDevice = this.deviceMap[deviceID];
  if (!cdifDevice) {
    callback(new CdifError('device not found'), null);
    return;
  }
  if (cdifDevice.module.discoverState === 'discovering') {
    callback(new CdifError('in discovering', null));
    return;
  }

  cdifDevice.connect(user, pass, function(err, secret) {
    if (err) {
      callback(err, null);
    } else {
      if (secret) {
        var token = _this.deviceAuth.generateToken(user, secret, function(err, data) {
          if (err) {
            callback(new CdifError('cannot generate access token'), null);
          } else {
            callback(null, {'device_access_token': data});
          }
        });
      } else {
        callback(null, null);
      }
      if (cdifDevice.spec.device.devicePresentation === true) {
        if (cdifDevice.connections === 1)
          _this.emit('presentation', cdifDevice.deviceID);
      }
    }
  });
};

DeviceManager.prototype.disconnectDevice = function(deviceID, token, callback) {
  this.emit('disconnect', deviceID, token, callback);
};

DeviceManager.prototype.onDisconnectDevice = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.disconnect(callback);
    }
  });
};

DeviceManager.prototype.invokeDeviceAction = function(deviceID, serviceID, actionName, args, token, callback) {
  this.emit('invokeaction', deviceID, serviceID, actionName, args, token, callback);
};

DeviceManager.prototype.onInvokeDeviceAction = function(deviceID, serviceID, actionName, args, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      try {
        cdifDevice.deviceControl(serviceID, actionName, args, callback);
      } catch (e) {
        callback(new DeviceError(e.message), null); //framework won't throw
      }
    }
  });
};

DeviceManager.prototype.getDeviceSpec = function(deviceID, token, callback) {
  this.emit('getspec', deviceID, token, callback);
};

DeviceManager.prototype.onGetDeviceSpec = function(deviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.getDeviceSpec(callback);
    }
  });
};

DeviceManager.prototype.getDeviceState = function(deviceID, serviceID, token, callback) {
  this.emit('devicestate', deviceID, serviceID, token, callback);
};

DeviceManager.prototype.onGetDeviceState = function(deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.getServiceStates(serviceID, callback);
    }
  });
};

DeviceManager.prototype.eventSubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  this.emit('subscribe', subscriber, deviceID, serviceID, token, callback);
};

DeviceManager.prototype.onEventSubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.subscribeDeviceEvent(subscriber, serviceID, callback);
    }
  });
};

DeviceManager.prototype.eventUnsubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  this.emit('unsubscribe', subscriber, deviceID, serviceID, token, callback);
};

DeviceManager.prototype.onEventUnsubscribe = function(subscriber, deviceID, serviceID, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.unSubscribeDeviceEvent(subscriber, serviceID, callback);
    }
  });
};

DeviceManager.prototype.getDeviceSchema = function(deviceID, path, token, callback) {
  this.emit('getschema', deviceID, path, token, callback);
};

DeviceManager.prototype.onGetDeviceSchema = function(deviceID, path, token, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  this.ensureDeviceState(deviceID, token, function(err) {
    if (err) {
      callback(err);
    } else {
      cdifDevice.resolveSchemaFromPath(path, null, function(error, self, data) {
        if (!error) {
          callback(null, data);
        } else {
          callback(error, null);
        }
      });
    }
  });
};

DeviceManager.prototype.setDeviceOAuthAccessToken = function(deviceID, params, callback) {
  this.emit('setoauthtoken', deviceID, params, callback);
};

DeviceManager.prototype.onSetDeviceOAuthAccessToken = function(deviceID, params, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (cdifDevice == null) {  // check null or undefined
    callback(new CdifError('device not found'));
    return;
  }
  cdifDevice.setOAuthAccessToken(params, callback);
};

DeviceManager.prototype.getDeviceRootUrl = function(deviceID, callback) {
  this.emit('getrooturl', deviceID, callback);
};

DeviceManager.prototype.onGetDeviceRootUrl = function(deviceID, callback) {
  var cdifDevice = this.deviceMap[deviceID];

  if (!cdifDevice) {
    callback(new CdifError('device not found'));
  } else {
    cdifDevice.getDeviceRootUrl(callback);
  }
};

DeviceManager.prototype.onOAuthAuthorizeRedirect = function(authorize_redirect_url, deviceID) {
  this.emit('authorizeredirect', authorize_redirect_url, deviceID);
};

module.exports = DeviceManager;
<|endoftext|>