<commit_before>/**
 * This function replaces a range in a string
 * @param from the starting point of the substitution
 * @param to the end point of the substitution, can be -1 to drop the rest
 * @param substitute the substitution to use
 * @returns {string} a new string substituted with the desired content
 */
String.prototype.replaceRange = function(from, to, substitute) {
    var result = this.substring(0, from) + substitute;
    if (to != -1) {
        result += this.substring(to)
    }
    return result;
}

/**
 * Returns the last index of a substring found in a string or -1
 * @param substring the substring to find inside the string object
 * @returns {number|*} -1 if the substring is not in the string or the index
 */
String.prototype.indexOfEnd = function(substring) {
    const index = this.indexOf(substring);
    return index === -1 ? index : index + substring.length;
}

downloadLetter = function() {
    window.open("/my/download/labels/?child_id="+$('#child_id').text());
}
/**
 * Selects the element given the element type and the object id. This relies
 * on a smart choice of ids in the XML file.
 * @param obj_id the id of the object to select
 * @param elem_type the type of the object to select
 */
selectElement = function(obj_id, elem_type) {
    // The id in the XML must have this form precisely, for this to work.
    const elem_id = `${elem_type}_${obj_id}`;
    // Elements are selected by finding the corresponding image and setting
    // the border around the selected one
    const elements = $(`img[class~="${elem_type}-image"]`);
    elements.fadeTo(0, 0.7);
    elements.removeClass("border border-5 border-primary");
    const element = elements.filter(`#${elem_id}`);
    element.fadeTo(0, 1.0);

    // Here we are in the selected element
    element.addClass("border border-5 border-primary");

    // Change url to display selected child and template id
    const base_url = window.location.origin + window.location.pathname;
    var params = window.location.search;
    const from = params.indexOfEnd(`${elem_type}_id=`);
    if (from === -1) {
        params += `&${elem_type}_id=${obj_id}`;
    } else {
        const to = params.indexOf("&", from);
        params = params.replaceRange(from, to, obj_id);
    }

    // Scroll smoothly to selected child
    const card = document.getElementById(`card_${elem_type}_${obj_id}`);
    card.scrollIntoView({
        behavior: "smooth",
        block: "nearest",
        inline: "start",
    });

    // We correctly set some values for letter writing to work properly
    const name = $(`#${elem_type}_name_${obj_id}`);
    const local_id = $(`#${elem_type}_local_id_${obj_id}`);
    if (local_id) {
        $(`span[id^=${elem_type}]`).removeClass("font-weight-bold");
        name.addClass("font-weight-bold");
        local_id.addClass("font-weight-bold");
        $(`#${elem_type}_local_id`).text(local_id.text());
        $("#guideline_child_ref").text(local_id.text());
    }
    $(`#${elem_type}_id`).text(obj_id);
    $(`#${elem_type}_name`).text(name.text());

     // We use replaceState for refreshes to work as intended
    history.replaceState({}, document.title, base_url + params);
}

const max_size = 1000;
/**
 * This function compresses images that are too big by shrinking them and if
 * necessary compressing using JPEG
 * @param image the image to compress
 * @returns {Promise<unknown>} the image as a promised blob (to allow
 * asynchronous calls)
 */
const compressImage = async function(image) {
    var canvas = document.createElement('canvas');

    var width = image.width;
    var height = image.height;

    // calculate the width and height, constraining the proportions
    const min_width = Math.min(width, max_size);
    const min_height = Math.min(height, max_size);
    const factor = Math.min(min_width / width, min_height / height);

    // resize the canvas and draw the image data into it
    canvas.width = Math.floor(width * factor);
    canvas.height = Math.floor(height * factor);
    var ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);

    return await new Promise(resolve => ctx.canvas.toBlob(resolve, "image/jpeg"));
}

/**
 * Returns the index of the file in the array object, given some of its
 * characteristics
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 * @returns {number} the index if found or -1, else
 */
Array.prototype.indexOfFile = function(name, size, type) {
    for (var i = 0 ; i < this.length ; i++) {
        const f = this[i];
        if (f.name === name && f.size === size && f.type === type) {
            return i;
        }
    }
    return -1;
}

/**
 * Check whether a file is contained in the array object
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 * @returns {boolean} true if the file is contained in the array or false
 */
Array.prototype.containsFile = function(name, size, type) {
    return this.indexOfFile(name, size, type) !== -1;
}

/**
 * Remove the file of the array object, or does nothing if it is not contained
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 */
const removeFile = function(name, size, type) {
    if (images_list.containsFile(name, size, type)) {
        const index = images_list.indexOfFile(name, size, type);
        images_list.splice(index, 1);
        images_comp.splice(index, 1);
    }
}

/**
 * Remove the image from the array as well as the HTML page
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 */
const removeImage = function(name, size, type) {
    removeFile(name, size, type);
    document.getElementById(`${name}_${size}_${type}`).remove();
}

/**
 * Display the images contained in new_images inside the HTML page
 */
const displayImages = function() {
    const image_display = document.getElementById("image_display_table");

    // We use the images stored in the new_images array
    for (var i = 0 ; i < new_images.length ; i++) {
        const original_image = new_images[i];

        const reader = new FileReader();
        reader.onload = function(event) {
            var image = new Image();
            image.src = event.target.result;
            image.onload = function(event) {
                if (original_image.size > 2e5) {
                    compressImage(image).then((blob) => {
                        blob.name = original_image.name;
                        blob.lastModified = Date.now();
                        blob.webkitRelativePath = "";
                        images_comp = images_comp.concat(blob);
                    })
                } else {
                    images_comp = images_comp.concat(original_image);
                }

                image_display.innerHTML += `

                            ×

                `;
            };
        }
        reader.readAsDataURL(original_image);
    }

    new_images = [];
}

// The images compressed
var images_comp = [];
// The list of images actually displayed inside the view
var images_list = [];
// The new non-duplicated images to add to the view
var new_images = [];

/**
 * Handle the addition of new images and ignore the duplications
 * @param event the event containing the file, among other things
 */
document.getElementById("file_selector").onchange = function(event) {
    var input_images = event.target.files;

    // TODO CI-765: remove the following block to support multiple images
    for (var i = 0 ; i < images_list.length ; i++) {
        const file = images_list[i];
        removeImage(file.name, file.size, file.type);
    }
    // TODO CI-765: end of block

    for (var i = 0 ; i < input_images.length ; i++) {
        const file = input_images[i];

        const is_image = file.type.startsWith("image/");

        if (is_image && !images_list.containsFile(file.name, file.size, file.type)) {

            new_images = new_images.concat(file);
            images_list = images_list.concat(file);
        }
    }

    // TODO CI-765: uncomment the following block to support multiple images
    /*
    if (new_images.length > 0) {
        display_alert("letter_images_duplicated");
        return;
    }
    */
    // TODO CI-765: end of block

    displayImages();
}

var loading = false;
/**
 * Starts and end the loading of the type elements
 * @param type the type of elements to start or stop loading
 */
const startStopLoading = function(type) {
    loading = !loading;
    $("button").attr('disabled', loading);
    if(loading) {
        document.getElementById(`${type}_normal`).style.display = "none";
        document.getElementById(`${type}_loading`).style.display = "";
    } else {
        document.getElementById(`${type}_loading`).style.display = "none";
        document.getElementById(`${type}_normal`).style.display = "";
    }
}

/**
 * Create a new letter object in the database
 * @param preview boolean to determine whether we want to see the preview
 * @param with_loading determines whether we want to have a loading or not
 * @returns {Promise<unknown>} return the entire method as a promise so that
 * we can send a letter directly if the user pressed the corresponding button
 */
const createLetter = async function(preview=false, with_loading=true) {
    return new Promise(function(resolve) {
        if (with_loading) {
            startStopLoading("preview");
        }
        var form_data = new FormData();

        form_data.append("letter-copy", document.getElementById('letter_content').value);
        form_data.append("selected-child", $('#child_local_id').text());
        form_data.append("selected-letter-id", $('#template_id').text());
        form_data.append("source", "website");
        // TODO CI-765: Handle properly multiple images
        if (images_list.length > 0) {
            form_data.append("file_upl", images_comp[0]);
        }
        // TODO CI-765: end of block

        var xhr = new XMLHttpRequest();
        var url = `${window.location.origin}/mobile-app-api/correspondence/get_preview`;
        xhr.open("POST", url, true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (preview) {
                    if (with_loading) {
                        startStopLoading("preview");
                    }
                    if (xhr.status === 200) {
                        window.open(xhr.responseText.slice(1, -1), "_blank");
                    } else {
                        displayAlert("preview_error");
                    }
                }
                resolve();
            }
        };
        xhr.send(form_data);
    })
}

/**
 * This function takes care of sending a letter when the corresponding button
 * is clicked
 */
const sendLetter = async function() {
    startStopLoading("sending");
    await createLetter(preview=false, with_loading=false);

    var json_data = JSON.parse(`{
        "TemplateID": "${$('#template_id').text()}",
        "Need": "${$('#child_id').text()}"
    }`);

    var xhr = new XMLHttpRequest();
    var url = `${window.location.origin}/mobile-app-api/correspondence/send_letter`;
    xhr.open("POST", url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                // Empty images and text (to avoid duplicate)
                document.getElementById("letter_content").value = ""
                for (var i = 0 ; i < images_list.length ; i++) {
                    var image = images_list[i];
                    removeImage(image.name, image.size, image.type);
                }

                displayAlert("letter_sent_correctly");
            } else {
                displayAlert("letter_error");
            }
        }
        startStopLoading("sending");
    };
    xhr.send(JSON.stringify(json_data));
}
<commit_msg>CO-3683 convert non jpeg image to jpeg<commit_after>/**
 * This function replaces a range in a string
 * @param from the starting point of the substitution
 * @param to the end point of the substitution, can be -1 to drop the rest
 * @param substitute the substitution to use
 * @returns {string} a new string substituted with the desired content
 */
String.prototype.replaceRange = function(from, to, substitute) {
    var result = this.substring(0, from) + substitute;
    if (to != -1) {
        result += this.substring(to)
    }
    return result;
}

/**
 * Returns the last index of a substring found in a string or -1
 * @param substring the substring to find inside the string object
 * @returns {number|*} -1 if the substring is not in the string or the index
 */
String.prototype.indexOfEnd = function(substring) {
    const index = this.indexOf(substring);
    return index === -1 ? index : index + substring.length;
}

downloadLetter = function() {
    window.open("/my/download/labels/?child_id="+$('#child_id').text());
}
/**
 * Selects the element given the element type and the object id. This relies
 * on a smart choice of ids in the XML file.
 * @param obj_id the id of the object to select
 * @param elem_type the type of the object to select
 */
selectElement = function(obj_id, elem_type) {
    // The id in the XML must have this form precisely, for this to work.
    const elem_id = `${elem_type}_${obj_id}`;
    // Elements are selected by finding the corresponding image and setting
    // the border around the selected one
    const elements = $(`img[class~="${elem_type}-image"]`);
    elements.fadeTo(0, 0.7);
    elements.removeClass("border border-5 border-primary");
    const element = elements.filter(`#${elem_id}`);
    element.fadeTo(0, 1.0);

    // Here we are in the selected element
    element.addClass("border border-5 border-primary");

    // Change url to display selected child and template id
    const base_url = window.location.origin + window.location.pathname;
    var params = window.location.search;
    const from = params.indexOfEnd(`${elem_type}_id=`);
    if (from === -1) {
        params += `&${elem_type}_id=${obj_id}`;
    } else {
        const to = params.indexOf("&", from);
        params = params.replaceRange(from, to, obj_id);
    }

    // Scroll smoothly to selected child
    const card = document.getElementById(`card_${elem_type}_${obj_id}`);
    card.scrollIntoView({
        behavior: "smooth",
        block: "nearest",
        inline: "start",
    });

    // We correctly set some values for letter writing to work properly
    const name = $(`#${elem_type}_name_${obj_id}`);
    const local_id = $(`#${elem_type}_local_id_${obj_id}`);
    if (local_id) {
        $(`span[id^=${elem_type}]`).removeClass("font-weight-bold");
        name.addClass("font-weight-bold");
        local_id.addClass("font-weight-bold");
        $(`#${elem_type}_local_id`).text(local_id.text());
        $("#guideline_child_ref").text(local_id.text());
    }
    $(`#${elem_type}_id`).text(obj_id);
    $(`#${elem_type}_name`).text(name.text());

     // We use replaceState for refreshes to work as intended
    history.replaceState({}, document.title, base_url + params);
}

const max_size = 1000;
/**
 * This function compresses images that are too big by shrinking them and if
 * necessary compressing using JPEG
 * @param image the image to compress
 * @returns {Promise<unknown>} the image as a promised blob (to allow
 * asynchronous calls)
 */
const compressImage = async function(image) {
    var canvas = document.createElement('canvas');

    var width = image.width;
    var height = image.height;

    // calculate the width and height, constraining the proportions
    const min_width = Math.min(width, max_size);
    const min_height = Math.min(height, max_size);
    const factor = Math.min(min_width / width, min_height / height);

    // resize the canvas and draw the image data into it
    canvas.width = Math.floor(width * factor);
    canvas.height = Math.floor(height * factor);
    var ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);

    return await new Promise(resolve => ctx.canvas.toBlob(resolve, "image/jpeg"));
}

/**
 * Returns the index of the file in the array object, given some of its
 * characteristics
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 * @returns {number} the index if found or -1, else
 */
Array.prototype.indexOfFile = function(name, size, type) {
    for (var i = 0 ; i < this.length ; i++) {
        const f = this[i];
        if (f.name === name && f.size === size && f.type === type) {
            return i;
        }
    }
    return -1;
}

/**
 * Check whether a file is contained in the array object
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 * @returns {boolean} true if the file is contained in the array or false
 */
Array.prototype.containsFile = function(name, size, type) {
    return this.indexOfFile(name, size, type) !== -1;
}

/**
 * Remove the file of the array object, or does nothing if it is not contained
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 */
const removeFile = function(name, size, type) {
    if (images_list.containsFile(name, size, type)) {
        const index = images_list.indexOfFile(name, size, type);
        images_list.splice(index, 1);
        images_comp.splice(index, 1);
    }
}

/**
 * Remove the image from the array as well as the HTML page
 * @param name the name of the file
 * @param size the size of the file
 * @param type the type of the file
 */
const removeImage = function(name, size, type) {
    removeFile(name, size, type);
    document.getElementById(`${name}_${size}_${type}`).remove();
}

/**
 * Display the images contained in new_images inside the HTML page
 */
const displayImages = function() {
    const image_display = document.getElementById("image_display_table");

    // We use the images stored in the new_images array
    for (var i = 0 ; i < new_images.length ; i++) {
        const original_image = new_images[i];

        const reader = new FileReader();
        reader.onload = function(event) {
            var image = new Image();
            image.src = event.target.result;
            image.onload = function(event) {
                if (original_image.size > 2e5 || original_image.type.valueOf() != "image/jpeg") {
                    compressImage(image).then((blob) => {
                        blob.name = original_image.name;
                        blob.lastModified = Date.now();
                        blob.webkitRelativePath = "";
                        images_comp = images_comp.concat(blob);
                    })
                } else {
                    images_comp = images_comp.concat(original_image);
                }

                image_display.innerHTML += `

                            ×

                `;
            };
        }
        reader.readAsDataURL(original_image);
    }

    new_images = [];
}

// The images compressed
var images_comp = [];
// The list of images actually displayed inside the view
var images_list = [];
// The new non-duplicated images to add to the view
var new_images = [];

/**
 * Handle the addition of new images and ignore the duplications
 * @param event the event containing the file, among other things
 */
document.getElementById("file_selector").onchange = function(event) {
    var input_images = event.target.files;

    // TODO CI-765: remove the following block to support multiple images
    for (var i = 0 ; i < images_list.length ; i++) {
        const file = images_list[i];
        removeImage(file.name, file.size, file.type);
    }
    // TODO CI-765: end of block

    for (var i = 0 ; i < input_images.length ; i++) {
        const file = input_images[i];

        const is_image = file.type.startsWith("image/");

        if (is_image && !images_list.containsFile(file.name, file.size, file.type)) {

            new_images = new_images.concat(file);
            images_list = images_list.concat(file);
        }
    }

    // TODO CI-765: uncomment the following block to support multiple images
    /*
    if (new_images.length > 0) {
        display_alert("letter_images_duplicated");
        return;
    }
    */
    // TODO CI-765: end of block

    displayImages();
}

var loading = false;
/**
 * Starts and end the loading of the type elements
 * @param type the type of elements to start or stop loading
 */
const startStopLoading = function(type) {
    loading = !loading;
    $("button").attr('disabled', loading);
    if(loading) {
        document.getElementById(`${type}_normal`).style.display = "none";
        document.getElementById(`${type}_loading`).style.display = "";
    } else {
        document.getElementById(`${type}_loading`).style.display = "none";
        document.getElementById(`${type}_normal`).style.display = "";
    }
}

/**
 * Create a new letter object in the database
 * @param preview boolean to determine whether we want to see the preview
 * @param with_loading determines whether we want to have a loading or not
 * @returns {Promise<unknown>} return the entire method as a promise so that
 * we can send a letter directly if the user pressed the corresponding button
 */
const createLetter = async function(preview=false, with_loading=true) {
    return new Promise(function(resolve) {
        if (with_loading) {
            startStopLoading("preview");
        }
        var form_data = new FormData();

        form_data.append("letter-copy", document.getElementById('letter_content').value);
        form_data.append("selected-child", $('#child_local_id').text());
        form_data.append("selected-letter-id", $('#template_id').text());
        form_data.append("source", "website");
        // TODO CI-765: Handle properly multiple images
        if (images_list.length > 0) {
            form_data.append("file_upl", images_comp[0]);
        }
        // TODO CI-765: end of block

        var xhr = new XMLHttpRequest();
        var url = `${window.location.origin}/mobile-app-api/correspondence/get_preview`;
        xhr.open("POST", url, true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (preview) {
                    if (with_loading) {
                        startStopLoading("preview");
                    }
                    if (xhr.status === 200) {
                        window.open(xhr.responseText.slice(1, -1), "_blank");
                    } else {
                        displayAlert("preview_error");
                    }
                }
                resolve();
            }
        };
        xhr.send(form_data);
    })
}

/**
 * This function takes care of sending a letter when the corresponding button
 * is clicked
 */
const sendLetter = async function() {
    startStopLoading("sending");
    await createLetter(preview=false, with_loading=false);

    var json_data = JSON.parse(`{
        "TemplateID": "${$('#template_id').text()}",
        "Need": "${$('#child_id').text()}"
    }`);

    var xhr = new XMLHttpRequest();
    var url = `${window.location.origin}/mobile-app-api/correspondence/send_letter`;
    xhr.open("POST", url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                // Empty images and text (to avoid duplicate)
                document.getElementById("letter_content").value = ""
                for (var i = 0 ; i < images_list.length ; i++) {
                    var image = images_list[i];
                    removeImage(image.name, image.size, image.type);
                }

                displayAlert("letter_sent_correctly");
            } else {
                displayAlert("letter_error");
            }
        }
        startStopLoading("sending");
    };
    xhr.send(JSON.stringify(json_data));
}
<|endoftext|>


<commit_before>function setEditorSize(){
	// Sets the size of the text editor window.
	fillWindow($('#editor'));
}

function getFileExtension(file){
	var parts=file.split('.');
	return parts[parts.length-1];
}

function setSyntaxMode(ext){
	// Loads the syntax mode files and tells the editor
	var filetype = new Array();
	// add file extensions like this: filetype["extension"] = "filetype":
	filetype["h"] = "c_cpp";
	filetype["c"] = "c_cpp";
	filetype["clj"] = "clojure";
	filetype["coffee"] = "coffee"; // coffescript can be compiled to javascript
	filetype["coldfusion"] = "cfc";
	filetype["cpp"] = "c_cpp";
	filetype["cs"] = "csharp";
	filetype["css"] = "css";
	filetype["groovy"] = "groovy";
	filetype["haxe"] = "hx";
	filetype["html"] = "html";
	filetype["java"] = "java";
	filetype["js"] = "javascript";
	filetype["json"] = "json";
	filetype["latex"] = "latex";
	filetype["ly"] = "latex";
	filetype["ily"] = "latex";
	filetype["lua"] = "lua";
	filetype["markdown"] = "markdown";
	filetype["md"] = "markdown";
	filetype["mdown"] = "markdown";
	filetype["mdwn"] = "markdown";
	filetype["mkd"] = "markdown";
	filetype["ml"] = "ocaml";
	filetype["mli"] = "ocaml";
	filetype["pl"] = "perl";
	filetype["php"] = "php";
	filetype["powershell"] = "ps1";
	filetype["py"] = "python";
	filetype["rb"] = "ruby";
	filetype["scad"] = "scad"; // seems to be something like 3d model files printed with e.g. reprap
	filetype["scala"] = "scala";
	filetype["scss"] = "scss"; // "sassy css"
	filetype["sql"] = "sql";
	filetype["svg"] = "svg";
	filetype["textile"] = "textile"; // related to markdown
	filetype["xml"] = "xml";

	if(filetype[ext]!=null){
		// Then it must be in the array, so load the custom syntax mode
		// Set the syntax mode
		OC.addScript('files_texteditor','aceeditor/mode-'+filetype[ext], function(){
			var SyntaxMode = require("ace/mode/"+filetype[ext]).Mode;
			window.aceEditor.getSession().setMode(new SyntaxMode());
		});
	}
}

function showControls(filename,writeperms){
	// Loads the control bar at the top.
	// Load the new toolbar.
	var editorbarhtml = '

'+filename+'

';
	if(writeperms=="true"){
		editorbarhtml += '<button id="editor_save">'+t('files_texteditor','Save')+'</button>

';
	}
	editorbarhtml += 'Go to line:<input stype="text" id="gotolineval">Search:<input type="text" name="editorsearchval" id="editorsearchval">

<button id="editor_close">'+t('files_texteditor','Close')+'</button>
';
	// Change breadcrumb classes
	$('#controls .last').removeClass('last');
	$('#controls').append(editorbarhtml);
	$('#editorcontrols').fadeIn('slow');
}

function bindControlEvents(){
	$("#editor_save").die('click',doFileSave).live('click',doFileSave);
	$('#editor_close').die('click',closeBtnClick).live('click',closeBtnClick);
	$('#gotolineval').die('keyup', goToLine).live('keyup', goToLine);
	$('#editorsearchval').die('keyup', doSearch).live('keyup', doSearch);
	$('#clearsearchbtn').die('click', resetSearch).live('click', resetSearch);
	$('#nextsearchbtn').die('click', nextSearchResult).live('click', nextSearchResult);
}

// returns true or false if the editor is in view or not
function editorIsShown(){
	// Not working as intended. Always returns true.
	return is_editor_shown;
}

// Moves the editor view to the line number speificed in #gotolineval
function goToLine(){
	// Go to the line specified
	window.aceEditor.gotoLine($('#gotolineval').val());

}

//resets the search
function resetSearch(){
	$('#editorsearchval').val('');
	$('#nextsearchbtn').remove();
	$('#clearsearchbtn').remove();
	window.aceEditor.gotoLine(0);
}

// moves the cursor to the next search resukt
function nextSearchResult(){
	window.aceEditor.findNext();
}
// Performs the initial search
function doSearch(){
	// check if search box empty?
	if($('#editorsearchval').val()==''){
		// Hide clear button
		window.aceEditor.gotoLine(0);
		$('#nextsearchbtn').remove();
		$('#clearsearchbtn').remove();
	} else {
		// New search
		// Reset cursor
		window.aceEditor.gotoLine(0);
		// Do search
		window.aceEditor.find($('#editorsearchval').val(),{
			backwards: false,
			wrap: false,
			caseSensitive: false,
			wholeWord: false,
			regExp: false
		});
		// Show next and clear buttons
		// check if already there
		if($('#nextsearchbtn').length==0){
			var nextbtnhtml = '<button id="nextsearchbtn">Next</button>';
			var clearbtnhtml = '<button id="clearsearchbtn">Clear</button>';
			$('#editorsearchval').after(nextbtnhtml).after(clearbtnhtml);
		}
	}
}

// Tries to save the file.
function doFileSave(){
	if(editorIsShown()){
		// Changed contents?
		if($('#editor').attr('data-edited')=='true'){
			// Get file path
			var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
			// Get original mtime
			var mtime = $('#editor').attr('data-mtime');
			// Show saving spinner
			$("#editor_save").die('click',doFileSave);
			$('#save_result').remove();
			$('#editor_save').text(t('files_texteditor','Saving...'));
			// Get the data
			var filecontents = window.aceEditor.getSession().getValue();
			// Send the data
			$.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
				if(jsondata.status!='success'){
					// Save failed
					$('#editor_save').text(t('files_texteditor','Save'));
					$('#editor_save').after('
Failed to save file
');
					$("#editor_save").live('click',doFileSave);
				} else {
					// Save OK
					// Update mtime
					$('#editor').attr('data-mtime',jsondata.data.mtime);
					$('#editor_save').text(t('files_texteditor','Save'));
					$("#editor_save").live('click',doFileSave);
					// Update titles
					$('#editor').attr('data-edited', 'false');
					$('#breadcrumb_file').text($('#editor').attr('data-filename'));
					document.title = $('#editor').attr('data-filename')+' - ownCloud';
				}
			},'json');
		}
	}
};

// Gives the editor focus
function giveEditorFocus(){
	window.aceEditor.focus();
};

// Loads the file editor. Accepts two parameters, dir and filename.
function showFileEditor(dir,filename){
	if(!editorIsShown()){
		// Loads the file editor and display it.
		$('#content').append('

');
		var data = $.getJSON(
			OC.filePath('files_texteditor','ajax','loadfile.php'),
			{file:filename,dir:dir},
			function(result){
				if(result.status == 'success'){
					// Save mtime
					$('#editor').attr('data-mtime', result.data.mtime);
					// Initialise the editor
					$('.actions,#file_action_panel').fadeOut('slow');
					$('table').fadeOut('slow', function() {
						// Show the control bar
						showControls(filename,result.data.write);
						// Update document title
						document.title = filename+' - ownCloud';
						$('#editor').text(result.data.filecontents);
						$('#editor').attr('data-dir', dir);
						$('#editor').attr('data-filename', filename);
						$('#editor').attr('data-edited', 'false');
						window.aceEditor = ace.edit("editor");
						aceEditor.setShowPrintMargin(false);
						aceEditor.getSession().setUseWrapMode(true);
						if(result.data.write=='false'){
							aceEditor.setReadOnly(true);
						}
						setEditorSize();
						setSyntaxMode(getFileExtension(filename));
						OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
							window.aceEditor.setTheme("ace/theme/clouds");
						});
						window.aceEditor.getSession().on('change', function(){
							if($('#editor').attr('data-edited')!='true'){
								$('#editor').attr('data-edited', 'true');
								$('#breadcrumb_file').text($('#breadcrumb_file').text()+' *');
								document.title = $('#editor').attr('data-filename')+' * - ownCloud';
							}
						});
					});
				} else {
					// Failed to get the file.
					OC.dialogs.alert(result.data.message, t('files_texteditor','An error occurred!'));
				}
			// End success
			}
		// End ajax
		);
		is_editor_shown = true;
	}
}

function closeBtnClick(){
	if($('#editor').attr('data-edited')=='true'){
		// Show confirm
		OC.dialogs.confirm(t('files_texteditor','You have unsaved changes that will be lost! Do you still want to close?'),t('files_texteditor','Really close?'),function(close){
			if(close){
				hideFileEditor();
			}
		});
	} else {
		hideFileEditor();
	}
}

// Fades out the editor.
function hideFileEditor(){
	// Fades out editor controls
	$('#editorcontrols').fadeOut('slow',function(){
		$(this).remove();
		$(".crumb:last").addClass('last');
	});
	// Fade out editor
	$('#editor').fadeOut('slow', function(){
		$(this).remove();
		// Reset document title
		document.title = "ownCloud";
		var editorhtml = '

';
		$('table').after(editorhtml);
		$('.actions,#file_access_panel').fadeIn('slow');
		$('table').fadeIn('slow');
	});
	is_editor_shown = false;
}

// Keyboard Shortcuts
var ctrlBtn = false;

// TODO fix detection of ctrl keyup
// returns true if ctrl+s or cmd+s is being pressed
function checkForSaveKeyPress(e){
	if(e.which == 17 || e.which == 91) ctrlBtn=true;
	if(e.which == 83 && ctrlBtn == true) {
	e.preventDefault();
	$('#editor_save').trigger('click');
	return false;

	}
}

// resizes the editor window
$(window).resize(function() {
	setEditorSize();
});
var is_editor_shown = false;
$(document).ready(function(){
	if(typeof FileActions!=='undefined'){
		FileActions.register('text','Edit','',function(filename){
			showFileEditor($('#dir').val(),filename);
		});
		FileActions.setDefault('text','Edit');
		FileActions.register('application/xml','Edit','',function(filename){
			showFileEditor($('#dir').val(),filename);
		});
		FileActions.setDefault('application/xml','Edit');
	}
	OC.search.customResults.Text=function(row,item){
		var text=item.link.substr(item.link.indexOf('file=')+5);
		var a=row.find('a');
		a.data('file',text);
		a.attr('href','#');
		a.click(function(){
			var file=text.split('/').pop();
			var dir=text.substr(0,text.length-file.length-1);
			showFileEditor(dir,file);
		});
	};
	// Binds the file save and close editor events, and gotoline button
	bindControlEvents();
	$('#editor').remove();
	// Binds the save keyboard shortcut events
	//$(document).unbind('keydown').bind('keydown',checkForSaveKeyPress);

});
<commit_msg>Provide undo when closing editor with unsaved changes<commit_after>function setEditorSize(){
	// Sets the size of the text editor window.
	fillWindow($('#editor'));
}

function getFileExtension(file){
	var parts=file.split('.');
	return parts[parts.length-1];
}

function setSyntaxMode(ext){
	// Loads the syntax mode files and tells the editor
	var filetype = new Array();
	// add file extensions like this: filetype["extension"] = "filetype":
	filetype["h"] = "c_cpp";
	filetype["c"] = "c_cpp";
	filetype["clj"] = "clojure";
	filetype["coffee"] = "coffee"; // coffescript can be compiled to javascript
	filetype["coldfusion"] = "cfc";
	filetype["cpp"] = "c_cpp";
	filetype["cs"] = "csharp";
	filetype["css"] = "css";
	filetype["groovy"] = "groovy";
	filetype["haxe"] = "hx";
	filetype["html"] = "html";
	filetype["java"] = "java";
	filetype["js"] = "javascript";
	filetype["json"] = "json";
	filetype["latex"] = "latex";
	filetype["ly"] = "latex";
	filetype["ily"] = "latex";
	filetype["lua"] = "lua";
	filetype["markdown"] = "markdown";
	filetype["md"] = "markdown";
	filetype["mdown"] = "markdown";
	filetype["mdwn"] = "markdown";
	filetype["mkd"] = "markdown";
	filetype["ml"] = "ocaml";
	filetype["mli"] = "ocaml";
	filetype["pl"] = "perl";
	filetype["php"] = "php";
	filetype["powershell"] = "ps1";
	filetype["py"] = "python";
	filetype["rb"] = "ruby";
	filetype["scad"] = "scad"; // seems to be something like 3d model files printed with e.g. reprap
	filetype["scala"] = "scala";
	filetype["scss"] = "scss"; // "sassy css"
	filetype["sql"] = "sql";
	filetype["svg"] = "svg";
	filetype["textile"] = "textile"; // related to markdown
	filetype["xml"] = "xml";

	if(filetype[ext]!=null){
		// Then it must be in the array, so load the custom syntax mode
		// Set the syntax mode
		OC.addScript('files_texteditor','aceeditor/mode-'+filetype[ext], function(){
			var SyntaxMode = require("ace/mode/"+filetype[ext]).Mode;
			window.aceEditor.getSession().setMode(new SyntaxMode());
		});
	}
}

function showControls(filename,writeperms){
	// Loads the control bar at the top.
	// Load the new toolbar.
	var editorbarhtml = '

'+filename+'

';
	if(writeperms=="true"){
		editorbarhtml += '<button id="editor_save">'+t('files_texteditor','Save')+'</button>

';
	}
	editorbarhtml += 'Go to line:<input stype="text" id="gotolineval">Search:<input type="text" name="editorsearchval" id="editorsearchval">

<button id="editor_close">'+t('files_texteditor','Close')+'</button>
';
	// Change breadcrumb classes
	$('#controls .last').removeClass('last');
	$('#controls').append(editorbarhtml);
	$('#editorcontrols').fadeIn('slow');
}

function bindControlEvents(){
	$("#editor_save").die('click',doFileSave).live('click',doFileSave);
	$('#editor_close').die('click',hideFileEditor).live('click',hideFileEditor);
	$('#gotolineval').die('keyup', goToLine).live('keyup', goToLine);
	$('#editorsearchval').die('keyup', doSearch).live('keyup', doSearch);
	$('#clearsearchbtn').die('click', resetSearch).live('click', resetSearch);
	$('#nextsearchbtn').die('click', nextSearchResult).live('click', nextSearchResult);
}

// returns true or false if the editor is in view or not
function editorIsShown(){
	// Not working as intended. Always returns true.
	return is_editor_shown;
}

// Moves the editor view to the line number speificed in #gotolineval
function goToLine(){
	// Go to the line specified
	window.aceEditor.gotoLine($('#gotolineval').val());

}

//resets the search
function resetSearch(){
	$('#editorsearchval').val('');
	$('#nextsearchbtn').remove();
	$('#clearsearchbtn').remove();
	window.aceEditor.gotoLine(0);
}

// moves the cursor to the next search resukt
function nextSearchResult(){
	window.aceEditor.findNext();
}
// Performs the initial search
function doSearch(){
	// check if search box empty?
	if($('#editorsearchval').val()==''){
		// Hide clear button
		window.aceEditor.gotoLine(0);
		$('#nextsearchbtn').remove();
		$('#clearsearchbtn').remove();
	} else {
		// New search
		// Reset cursor
		window.aceEditor.gotoLine(0);
		// Do search
		window.aceEditor.find($('#editorsearchval').val(),{
			backwards: false,
			wrap: false,
			caseSensitive: false,
			wholeWord: false,
			regExp: false
		});
		// Show next and clear buttons
		// check if already there
		if($('#nextsearchbtn').length==0){
			var nextbtnhtml = '<button id="nextsearchbtn">Next</button>';
			var clearbtnhtml = '<button id="clearsearchbtn">Clear</button>';
			$('#editorsearchval').after(nextbtnhtml).after(clearbtnhtml);
		}
	}
}

// Tries to save the file.
function doFileSave(){
	if(editorIsShown()){
		// Changed contents?
		if($('#editor').attr('data-edited')=='true'){
			// Get file path
			var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
			// Get original mtime
			var mtime = $('#editor').attr('data-mtime');
			// Show saving spinner
			$("#editor_save").die('click',doFileSave);
			$('#save_result').remove();
			$('#editor_save').text(t('files_texteditor','Saving...'));
			// Get the data
			var filecontents = window.aceEditor.getSession().getValue();
			// Send the data
			$.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
				if(jsondata.status!='success'){
					// Save failed
					$('#editor_save').text(t('files_texteditor','Save'));
					$('#editor_save').after('
Failed to save file
');
					$("#editor_save").live('click',doFileSave);
				} else {
					// Save OK
					// Update mtime
					$('#editor').attr('data-mtime',jsondata.data.mtime);
					$('#editor_save').text(t('files_texteditor','Save'));
					$("#editor_save").live('click',doFileSave);
					// Update titles
					$('#editor').attr('data-edited', 'false');
					$('#breadcrumb_file').text($('#editor').attr('data-filename'));
					document.title = $('#editor').attr('data-filename')+' - ownCloud';
				}
			},'json');
		}
	}
};

// Gives the editor focus
function giveEditorFocus(){
	window.aceEditor.focus();
};

// Loads the file editor. Accepts two parameters, dir and filename.
function showFileEditor(dir,filename){
	// Delete any old editors
	$('#editor').remove();
	if(!editorIsShown()){
		// Loads the file editor and display it.
		$('#content').append('

');
		var data = $.getJSON(
			OC.filePath('files_texteditor','ajax','loadfile.php'),
			{file:filename,dir:dir},
			function(result){
				if(result.status == 'success'){
					// Save mtime
					$('#editor').attr('data-mtime', result.data.mtime);
					// Initialise the editor
					$('.actions,#file_action_panel').fadeOut('slow');
					$('table').fadeOut('slow', function() {
						// Show the control bar
						showControls(filename,result.data.write);
						// Update document title
						document.title = filename+' - ownCloud';
						$('#editor').text(result.data.filecontents);
						$('#editor').attr('data-dir', dir);
						$('#editor').attr('data-filename', filename);
						$('#editor').attr('data-edited', 'false');
						window.aceEditor = ace.edit("editor");
						aceEditor.setShowPrintMargin(false);
						aceEditor.getSession().setUseWrapMode(true);
						if(result.data.write=='false'){
							aceEditor.setReadOnly(true);
						}
						setEditorSize();
						setSyntaxMode(getFileExtension(filename));
						OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
							window.aceEditor.setTheme("ace/theme/clouds");
						});
						window.aceEditor.getSession().on('change', function(){
							if($('#editor').attr('data-edited')!='true'){
								$('#editor').attr('data-edited', 'true');
								$('#breadcrumb_file').text($('#breadcrumb_file').text()+' *');
								document.title = $('#editor').attr('data-filename')+' * - ownCloud';
							}
						});
					});
				} else {
					// Failed to get the file.
					OC.dialogs.alert(result.data.message, t('files_texteditor','An error occurred!'));
				}
			// End success
			}
		// End ajax
		);
		is_editor_shown = true;
	}
}

// Fades out the editor.
function hideFileEditor(){
	if($('#editor').attr('data-edited') == 'true'){
		// Hide, not remove
		$('#editorcontrols').fadeOut('slow',function(){
			// Check if there is a folder in the breadcrumb
			if($('.crumb.ui-droppable').length){
				$('.crumb.ui-droppable:last').addClass('last');
			}
		});
		// Fade out editor
		$('#editor').fadeOut('slow', function(){
			// Reset document title
			document.title = "ownCloud";
			$('.actions,#file_access_panel').fadeIn('slow');
			$('table').fadeIn('slow');
		});
		$('#notification').text(t('files_texteditor','There were unsaved changes, click here to go back'));
		$('#notification').data('reopeneditor',true);
		$('#notification').fadeIn();
		is_editor_shown = false;
	} else {
		// Remove editor
		$('#editorcontrols').fadeOut('slow',function(){
			$(this).remove();
			$(".crumb:last").addClass('last');
		});
		// Fade out editor
		$('#editor').fadeOut('slow', function(){
			$(this).remove();
			// Reset document title
			document.title = "ownCloud";
			$('.actions,#file_access_panel').fadeIn('slow');
			$('table').fadeIn('slow');
		});
		is_editor_shown = false;
	}
}

// Reopens the last document
function reopenEditor(){
	$('.actions,#file_action_panel').fadeOut('slow');
	$('table').fadeOut('slow', function(){
		$('#controls .last').not('#breadcrumb_file').removeClass('last');
		$('#editor').fadeIn('fast');
		$('#editorcontrols').fadeIn('fast', function(){

		});
	});
	is_editor_shown  = true;
}

// resizes the editor window
$(window).resize(function() {
	setEditorSize();
});
var is_editor_shown = false;
$(document).ready(function(){
	if(typeof FileActions!=='undefined'){
		FileActions.register('text','Edit','',function(filename){
			showFileEditor($('#dir').val(),filename);
		});
		FileActions.setDefault('text','Edit');
		FileActions.register('application/xml','Edit','',function(filename){
			showFileEditor($('#dir').val(),filename);
		});
		FileActions.setDefault('application/xml','Edit');
	}
	OC.search.customResults.Text=function(row,item){
		var text=item.link.substr(item.link.indexOf('file=')+5);
		var a=row.find('a');
		a.data('file',text);
		a.attr('href','#');
		a.click(function(){
			var file=text.split('/').pop();
			var dir=text.substr(0,text.length-file.length-1);
			showFileEditor(dir,file);
		});
	};
	// Binds the file save and close editor events, and gotoline button
	bindControlEvents();
	$('#editor').remove();
	$('#notification').click(function(){
		if($('#notification').data('reopeneditor'))
		{
			reopenEditor();
		}
		$('#notification').fadeOut();
	});
});
<|endoftext|>


<commit_before>var mongoose = require('mongoose'),
    extend = require('mongoose-schema-extend'),
    log = require('./log'),
    env = process.env.NODE_ENV || 'development',
    config = require('../../config/config')[env],
    util = require('util'),
    md = require('node-markdown').Markdown;

var NamesLogSchema = log.LogSchema.extend({
    nicks: [String]
});

function irssi(namesLog, markdown) {
    markdown = markdown || false;

    var usersChannelPrint = '[Users %s]';
    if (markdown) usersChannel = '[Users **%s**]';
    var usersChannel = util.format(usersChannelPrint, namesLog.channel);

    var users = '';
    var numOps = 0;
    var numHalfops = 0;
    var numVoices = 0;
    var numNormal = 0;
    var numTotal = 0;
    namesLog.nicks.forEach(function(nick) {
	var access = nick.charAt(0);
	switch(access) {
	case '@':
	    numOps++;
	    users += util.format('[%s] ', nick);
	    break;
	case '%':
	    numHalfops++;
	    users += util.format('[%s] ', nick);
	    break;
	case '+':
	    numVoices++;
	    users += util.format('[%s] ', nick);
	    break;
	default:
	    numNormal++;
	    users += util.format('[ %s] ', nick);
	};
	numTotal++;
    });

    var countPrint = '-!- %s: %s: Total of %d nicks [%d ops, %d halfops, %d voices, %d normal]';
    if (markdown) countPrint = '-!- **%s**: **%s**: Total of **%d** nicks [**%d** ops, **%d** halfops, **%d** voices, **%d** normal]';
    var count = util.format(countPrint, config.irc.nick, namesLog.channel, numTotal, numOps, numHalfops, numVoices, numNormal);

    return util.format('%s\n%s\n%s', usersChannel, users, count);
};

NamesLogSchema.virtual('irssi').get(function() {
    return irssi(this);
});

NamesLogSchema.virtual('irssi_markdown').get(function() {
    return md(irssi(this, true), true, 'strong|em');
});

mongoose.model('NamesLog', NamesLogSchema);
<commit_msg>fix nameslog newlines in markdown<commit_after>var mongoose = require('mongoose'),
    extend = require('mongoose-schema-extend'),
    log = require('./log'),
    env = process.env.NODE_ENV || 'development',
    config = require('../../config/config')[env],
    util = require('util'),
    md = require('node-markdown').Markdown;

var NamesLogSchema = log.LogSchema.extend({
    nicks: [String]
});

function irssi(namesLog, markdown) {
    markdown = markdown || false;

    var usersChannelPrint = '[Users %s]';
    if (markdown) usersChannel = '[Users **%s**]';
    var usersChannel = util.format(usersChannelPrint, namesLog.channel);

    var users = '';
    var numOps = 0;
    var numHalfops = 0;
    var numVoices = 0;
    var numNormal = 0;
    var numTotal = 0;
    namesLog.nicks.forEach(function(nick) {
	var access = nick.charAt(0);
	switch(access) {
	case '@':
	    numOps++;
	    users += util.format('[%s] ', nick);
	    break;
	case '%':
	    numHalfops++;
	    users += util.format('[%s] ', nick);
	    break;
	case '+':
	    numVoices++;
	    users += util.format('[%s] ', nick);
	    break;
	default:
	    numNormal++;
	    users += util.format('[ %s] ', nick);
	};
	numTotal++;
    });

    var countPrint = '-!- %s: %s: Total of %d nicks [%d ops, %d halfops, %d voices, %d normal]';
    if (markdown) countPrint = '-!- **%s**: **%s**: Total of **%d** nicks [**%d** ops, **%d** halfops, **%d** voices, **%d** normal]';
    var count = util.format(countPrint, config.irc.nick, namesLog.channel, numTotal, numOps, numHalfops, numVoices, numNormal);

    var result = util.format('%s\n%s\n%s', usersChannel, users, count);
    if (markdown) result = util.format('%s  \n%s  \n%s', usersChannel, users, count);
    return result;
};

NamesLogSchema.virtual('irssi').get(function() {
    return irssi(this);
});

NamesLogSchema.virtual('irssi_markdown').get(function() {
    return md(irssi(this, true), true, 'strong|em|br');
});

mongoose.model('NamesLog', NamesLogSchema);
<|endoftext|>


<commit_before>import request from 'lib/request';
import querystring from 'querystring';
const apiKey = process.env.MOONPAY_API_KEY;
let coins = {};
let isBuyAllowed = false;
let isSellAllowed = false;
let isInited = false;
const envSuffix = `${process.env.NODE_ENV === 'production' ? '' : '-sandbox'}`;
const MOONPAY_WIDGET_BUY_URL = `https://buy${envSuffix}.moonpay.com?apiKey=${apiKey}`;
const MOONPAY_WIDGET_SELL_URL = `https://sell${envSuffix}.moonpay.com?apiKey=${apiKey}`;

async function init() {
  if (isInited) return true;
  isInited = true;
  try {
    const data = await request({
      url: 'https://api.moonpay.com/v4/ip_address',
      params: { apiKey },
      hideFlashError: true,
    });
    ({ isBuyAllowed } = data);
    ({ isSellAllowed } = data);

    if (isBuyAllowed || isSellAllowed) {
      const _coins = await request({
        url: `${process.env.SITE_URL}api/v1/moonpay/coins`,
        params: { country: data.alpha3 },
        id: true,
      });
      if (_coins) coins = _coins;
    }
  } catch (err) {
    if (err.message !== 'Network Error') console.error(err);
  }
}

async function getWidgetUrls(crypto, address) {
  let buy;
  let sell;
  let urls = [];
  const coin = getMoonpayCoin(crypto);

  if (isBuyAllowed && coin && coin.isSupported && address) {
    buy = getBuyUrl(coin.code, address);
    urls.push(buy);
    buy = urls.length - 1;
  }
  if (isSellAllowed && coin && coin.isSellSupported && address) {
    sell = getSellUrl(coin.code, address);
    urls.push(sell);
    sell = urls.length - 1;
  }

  if (urls.length) {
    urls = await signUrls(urls);
    buy = urls[buy];
    sell = urls[sell];
  }

  return {
    buy,
    sell,
  };
}

function getMoonpayCoin(crypto) {
  if (crypto.moonpay) {
    return coins[crypto.moonpay.id];
  }
}

function getBuyUrl(currencyCode, walletAddress) {
  let baseUrl = MOONPAY_WIDGET_BUY_URL + '&';
  const params = {
    currencyCode,
    walletAddress,
    enableRecurringBuys: true,
  };

  baseUrl += querystring.stringify(params);
  return baseUrl;
}

function getSellUrl(baseCurrencyCode, refundWalletAddress) {
  let baseUrl = MOONPAY_WIDGET_SELL_URL + '&';
  const params = {
    baseCurrencyCode,
    refundWalletAddress,
  };
  baseUrl += querystring.stringify(params);
  return baseUrl;
}

async function signUrls(urls) {
  const result = await request({
    url: `${process.env.SITE_URL}api/v3/moonpay/sign`,
    method: 'post',
    data: {
      urls,
    },
    seed: 'public',
  });
  return result.urls;
}

export default {
  init,
  getWidgetUrls,
};
<commit_msg>feat(app): move and improve moonpay logic to client<commit_after>import request from 'lib/request';
import querystring from 'querystring';
const apiKey = process.env.MOONPAY_API_KEY;
const supported = [];
let isInited = false;
const envSuffix = `${process.env.NODE_ENV === 'production' ? '' : '-sandbox'}`;
const MOONPAY_WIDGET_BUY_URL = `https://buy${envSuffix}.moonpay.com?apiKey=${apiKey}`;
const MOONPAY_WIDGET_SELL_URL = `https://sell${envSuffix}.moonpay.com?apiKey=${apiKey}`;

async function init() {
  if (isInited) return true;
  isInited = true;
  try {
    const ip = await request({
      url: 'https://api.moonpay.com/v4/ip_address',
      params: { apiKey },
      hideFlashError: true,
    });

    if (ip.isBuyAllowed || ip.isSellAllowed) {
      const currencies = await request({
        url: 'https://api.moonpay.com/v3/currencies',
        params: { apiKey },
        hideFlashError: true,
      });

      supported.push(...currencies
        .filter((currency) => {
          if (currency.type !== 'crypto') {
            return false;
          }
          if (currency.isSuspended) {
            return false;
          }
          if (ip.alpha3 === 'USA') {
            if (currency.isSupportedInUS === false) {
              return false;
            }
            if (currency.notAllowedUSStates && currency.notAllowedUSStates.includes(ip.state)) {
              return false;
            }
          }
          return true;
        })
        .map((currency) => {
          return {
            ...currency,
            isBuySupported: ip.isBuyAllowed,
            isSellSupported: ip.isSellAllowed && currency.isSellSupported,
          };
        })
      );
    }
  } catch (err) {
    if (err.message !== 'Network Error') {
      console.error(err);
    }
  }
}

async function getWidgetUrls(crypto, address) {
  const coin = getMoonpayCoin(crypto);

  if (!coin) {
    return {};
  }

  if (coin.isBuySupported && coin.isSellSupported) {
    const [buy, sell] = await signUrls([
      getBuyUrl(coin.code, address),
      getSellUrl(coin.code, address),
    ]);
    return {
      buy,
      sell,
    };
  } else if (coin.isBuySupported) {
    const [buy] = await signUrls([
      getBuyUrl(coin.code, address),
    ]);
    return {
      buy,
    };
  } else if (coin.isSellSupported) {
    const [sell] = await signUrls([
      getSellUrl(coin.code, address),
    ]);
    return {
      sell,
    };
  }
  return {};
}

function getMoonpayCoin(crypto) {
  if (crypto.moonpay) {
    return supported.find((item) => item.id === crypto.moonpay.id);
  }
}

function getBuyUrl(currencyCode, walletAddress) {
  let baseUrl = MOONPAY_WIDGET_BUY_URL + '&';
  const params = {
    currencyCode,
    walletAddress,
    enableRecurringBuys: true,
  };

  baseUrl += querystring.stringify(params);
  return baseUrl;
}

function getSellUrl(baseCurrencyCode, refundWalletAddress) {
  let baseUrl = MOONPAY_WIDGET_SELL_URL + '&';
  const params = {
    baseCurrencyCode,
    refundWalletAddress,
  };
  baseUrl += querystring.stringify(params);
  return baseUrl;
}

async function signUrls(urls) {
  const result = await request({
    url: `${process.env.SITE_URL}api/v3/moonpay/sign`,
    method: 'post',
    data: {
      urls,
    },
    seed: 'public',
  });
  return result.urls;
}

export default {
  init,
  getWidgetUrls,
};
<|endoftext|>


<commit_before>// Express
var express = require('express');
var app = express();

// Utility funnctions
var util = require('./util.js');

// Socket.io
var http = require('http');
var httpServer = http.createServer(app);
var io = require('socket.io').listen(httpServer);
io.set('log level', 2);

var port = process.env.PORT || 3000;
httpServer.listen(port);

var welcomeMsg =  '$ man pairjam\n\nWelcome to pair/jam\n\nShare the url to this page to start coding.\n\n' +
                  'You can browse github repos on the top left.\nYou can enable audio/video by clicking on empty blue-ish box on the bottom left.';

// Github
var GitHubApi = require("github");
var gitCred = require('./gitapiSecret');

var github = new GitHubApi({
    // required
    version: "3.0.0",
    // optional
    debug: true,
    protocol: "https",
    timeout: 5000
});

github.authenticate({
    type: "oauth",
    key: gitCred.client_id,
    secret: gitCred.client_secret
});

// A session is a group of users in the same 'room' with a shared document
var Session = require('../lib/ot/serverSession.js');
var sessions = [];
var clients = [];   // Maps clients to rooms

Session.prototype.send = function( clientId, msg, args ) {
    //var room = clients[ clientId ];
    io.sockets.sockets[ clientId ].emit( msg, args );
};

Session.prototype.sendAll = function( clientId, msg, args ) {
    var room = clients[ clientId ];
    io.sockets.in(room).emit( msg, args );
};

//TODO: bug, this matches index.html and prevents a session from being created
app.use(
    express.static(__dirname + '/../client/public')
);

app.get('/', function (req, res) {
            var sessionId = util.generateSessionId(6);
            console.log(sessionId);
            res.redirect('/' + sessionId);
        }
).get('/*', function(req, res) {
            res.sendfile('client/index.html', {'root': __dirname + '/../'} );
        }
);

io.sockets.on('connection', function (socket) {

    var session = undefined;
    var sessionId = 0;

    socket.on('join', function(data) {
        session = sessions[ data.sessionId ];
        if(! sessions[ data.sessionId ] ) {
            session = sessions[ data.sessionId ] = new Session(welcomeMsg);
        }
        sessionId = data.sessionId;
        clients[ socket.id ] = data.sessionId;
        socket.join(sessionId);

        console.log('Client joined \n\t id = ' + socket.id + '\n\t name = ' + data.name + '\n\t session = ' + sessionId);
        session.addClient( socket.id, data.name );
    });

    socket.on('op', function (data) {
        if(session) {
            session.applyOp( socket.id, data );
        }
    });

    socket.on('sel', function (data) {
        if(session) {
            session.applySel( socket.id, data );
        }
    });

    socket.on('reqDocChg', function(data) {
        if(session) {
            github.gitdata.getBlob({
                user: data.user,
                repo: data.repo,
                sha: data.sha
            }, function(err, res) {
                console.log(JSON.stringify(res));
                if(!err) {
                    var b64contents = res.content;
                    var buf = new Buffer(b64contents, 'base64');
                    session.setDoc( data.id, buf.toString(), data.filename );
                } else {
                    console.error(err);
                }
            });

        }
    });

    socket.on('reqRepoTree', function(data) {
        if(session) {
            //TODO: VALIDATE!!
            github.gitdata.getTree({
                user: data.user,
                repo: data.repo,
                sha: data.sha,
                recursive: 1
            }, function(err, res) {
                if(err) {
                    console.error(err);
                } else {
                    var room = clients[ socket.id ];
                    io.sockets.in(room).emit( 'repoTree', { 'user' : data.user,
                                                            'repo' : data.repo,
                                                            'sha' : data.sha,
                                                            'tree' : res.tree  }   );
                }
            });
        }
    });

    socket.on('disconnect', function(data) {
        if(session) {
            socket.leave(sessionId);
            delete clients[ socket.id ];
            session.removeClient( socket.id );

            if( !session.getClients().length ) {
                session = undefined;
                delete sessions[ sessionId ];
            }
        }
    });

});<commit_msg>Refactoring<commit_after>// Express
var express = require('express');
var app = express();

// Utility funnctions
var util = require('./util.js');

// Socket.io
var http = require('http');
var httpServer = http.createServer(app);
var io = require('socket.io').listen(httpServer);
io.set('log level', 2);

var port = process.env.PORT || 3000;
httpServer.listen(port);

var welcomeMsg =  '$ man pairjam\n\nWelcome to pair/jam\n\nShare the url to this page to start coding.\n\n' +
                  'You can browse github repos on the top left.\nYou can enable audio/video by clicking on empty blue-ish box on the bottom left.';

// Github
var GitHubApi = require("github");
var gitCred = require('./gitapiSecret');

var github = new GitHubApi({
    // required
    version: "3.0.0",
    // optional
    debug: true,
    protocol: "https",
    timeout: 5000
});

github.authenticate({
    type: "oauth",
    key: gitCred.client_id,
    secret: gitCred.client_secret
});

// A session is a group of users in the same 'room' with a shared document
var Session = require('../lib/ot/serverSession.js');
var sessions = [];
var clients = [];   // Maps clients to rooms

Session.prototype.send = function( clientId, msg, args ) {
    //var room = clients[ clientId ];
    io.sockets.sockets[ clientId ].emit( msg, args );
};

Session.prototype.sendAll = function( clientId, msg, args ) {
    var room = clients[ clientId ];
    io.sockets.in(room).emit( msg, args );
};

//TODO: bug, this matches index.html and prevents a session from being created
app.use(
    express.static(__dirname + '/../client/public')
);

app.get('/', function (req, res) {
            var sessionId = util.generateSessionId(6);
            console.log(sessionId);
            res.redirect('/' + sessionId);
        }
).get('/*', function(req, res) {
            res.sendfile('client/index.html', {'root': __dirname + '/../'} );
        }
);

io.sockets.on('connection', function (socket) {

    var session = undefined;
    var sessionId = 0;

    socket.on('join', function(data) {
        session = sessions[ data.sessionId ];
        if(! sessions[ data.sessionId ] ) {
            session = sessions[ data.sessionId ] = new Session(welcomeMsg);
        }
        sessionId = data.sessionId;
        clients[ socket.id ] = data.sessionId;
        socket.join(sessionId);

        console.log('Client joined \n\t id = ' + socket.id + '\n\t name = ' + data.name + '\n\t session = ' + sessionId);
        session.addClient( socket.id, data.name );
    });

    socket.on('op', function (data) {
        if(session) {
            session.applyOp( socket.id, data );
        }
    });

    socket.on('sel', function (data) {
        if(session) {
            session.applySel( socket.id, data );
        }
    });

    socket.on('reqDocChg', function(data) {
        if(session) {
            github.gitdata.getBlob({
                user: data.user,
                repo: data.repo,
                sha: data.sha
            }, function(err, res) {
                console.log(JSON.stringify(res));
                if(!err) {
                    var b64contents = res.content;
                    var buf = new Buffer(b64contents, 'base64');
                    session.setDoc( data.id, buf.toString(), data.filename );
                } else {
                    console.error(err);
                }
            });

        }
    });

    socket.on('reqRepoTree', function(data) {
        if(session) {
            //TODO: VALIDATE!!
            github.gitdata.getTree({
                user: data.user,
                repo: data.repo,
                sha: data.sha,
                recursive: 1
            }, function(err, res) {
                if(err) {
                    console.error(err);
                } else {
                    var room = clients[ socket.id ];
                    io.sockets.in(room).emit( 'repoTree', { 'user' : data.user,
                                                            'repo' : data.repo,
                                                            'sha' : data.sha,
                                                            'tree' : res.tree  }   );
                }
            });
        }
    });

    socket.on('disconnect', function(data) {
        if(session) {
            socket.leave(sessionId);
            delete clients[ socket.id ];
            session.removeClient( socket.id );

            if( !session.getClients().length ) {
                session = undefined;
                delete sessions[ sessionId ];
            }
        }
    });

});<|endoftext|>


<commit_before>/*global */
/*jslint browser:true,sloppy:true,nomen:true,unparam:true,plusplus:true */
/*
 | Copyright 2014 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
define([
    "dojo/_base/declare",
    "dojo/_base/array",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dojo/dom-construct",
    "dojo/dom-attr",
    "dojo/dom-style",
    "dojo/dom-class",
    "dojo/dom",
    "dojo/on",
    "dojo/query",
    "dojo/topic",
    "dojo/i18n!nls/localizedStrings",
    "esri/arcgis/Portal",
    "esri/arcgis/utils",
    "esri/config",
    "dojo/cookie",
    "esri/kernel",
    "esri/request",
    "esri/urlUtils",
    "esri/IdentityManager",
    "coreLibrary/OAuthHelper",
    "../alertDialog/alertDialog",
    "dojo/DeferredList",
    "dojo/_base/Deferred",
    "dojo/parser"
], function (declare, array, lang, _WidgetBase, domConstruct, domAttr, domStyle, domClass, dom, on, query, topic, nls, esriPortal, arcgisUtils, config, cookie, kernel, esriRequest, urlUtils, IdentityManager, OAuthHelper, alertBox, DeferredList, Deferred) {
    return declare([_WidgetBase], {
        _portal: null,
        startup: function () {
            var _self = this, deferred;
            _self.alertDialog = new alertBox();
            deferred = new Deferred();

            this._setApplicationTheme();

            topic.subscribe("saveBookHandler", function () {
                _self._saveSelectedBook();
            });

            topic.subscribe("deleteItemHandler", function () {
                _self._deleteBookItem();
            });

            topic.subscribe("copySelectedBookHandler", function () {
                _self._copyBookItem();
            });

            topic.subscribe("getFullUserNameHandler", function (newBook) {
                newBook.author = _self._getFullUserName();
            });

            topic.subscribe("toggleUserLogInHandler", function () {
                if (!domClass.contains(dom.byId("userLogIn"), "esriLogOutIcon")) {
                    _self._displayLoginDialog(false);
                } else {
                    _self._portal.signOut().then(function () {
                        _self._queryOrgItems(false);
                        _self._removeCredentials();
                        domClass.remove(dom.byId("userLogIn"), "esriLogOutIcon");
                        domAttr.set(dom.byId("userLogIn"), "title", nls.signInText);
                    });
                }
            });

            if (dojo.appConfigData.PortalURL) {
                this._portal = new esriPortal.Portal(dojo.appConfigData.PortalURL);
                dojo.connect(_self._portal, 'onLoad', function () {
                    _self._loadCredentials(deferred);
                });
            } else {
                deferred.reject();

            }
            return deferred.promise;
        },

        _displayLoginDialog: function (deferred) {

            var _self = this, queryParams;
            this._portal.signIn().then(function (loggedInUser) {
                if (dom.byId("outerLoadingIndicator")) {
                    domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
                }
                dojo.bookInfo = [];
                queryParams = {
                    q: "tags:" + dojo.appConfigData.ConfigSearchTag,
                    sortField: dojo.appConfigData.SortField,
                    sortOrder: dojo.appConfigData.SortOrder,
                    num: 100
                };
                _self._storeCredentials();
                dojo.appConfigData.AuthoringMode = true;
                if (dom.byId("userLogIn")) {
                    domClass.add(dom.byId("userLogIn"), "esriLogOutIcon");
                    domAttr.set(dom.byId("userLogIn"), "title", nls.signOutText);
                    dojo.currentUser = loggedInUser.username;
                }
                _self._portal.queryItems(queryParams).then(function (response) {
                    dojo.bookInfo = [];
                    topic.publish("destroyWebmapHandler");
                    topic.publish("_getPortal", _self._portal);
                    _self._createConfigurationPanel(response);

                });
            }, function (error) {
                if (error.httpCode === 403) {
                    _self.alertDialog._setContent(nls.validateOrganizationUser, 0);
                    IdentityManager.credentials[0].destroy();
                }
                if (dom.byId("outerLoadingIndicator")) {
                    domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
                }
            });
        },

        _loadCredentials: function (deferred) {
            deferred.resolve();
            var idJson, idObject, isCredAvailable = false;

            // If we've connected via OAuth, we can go ahead with the the behind-the-scenes login
            if (OAuthHelper.isSignedIn()) {
                this._displayLoginDialog(false);

            // Otherwise see if we've cached credentials
            } else {
                if (this._supports_local_storage()) {
                    idJson = window.localStorage.getItem(dojo.appConfigData.Credential);
                } else {
                    if (cookie.isSupported()) {
                        idJson = cookie(dojo.appConfigData.Credential);
                    }
                }
                if (idJson && idJson !== "null" && idJson.length > 4) {
                    idObject = JSON.parse(idJson);
                    if (idObject.credentials[0].expires > Date.now()) {
                        if (dojo.appConfigData.PortalURL === idObject.serverInfos[0].server) {
                            isCredAvailable = true;
                            kernel.id.initialize(idObject);
                            this._displayLoginDialog(deferred);
                        }
                    }
                }
            }

            if (!isCredAvailable) {
                this._queryOrgItems();
            }
        },

        _supports_local_storage: function () {
            try {
                return "localStorage" in window && window["localStorage"] !== null;
            } catch (e) {
                return false;
            }
        },

        _removeCredentials: function () {

            if (this._supports_local_storage()) {
                window.localStorage.setItem(dojo.appConfigData.Credential, null, { expire: -1 });
            } else {
                if (cookie.isSupported()) {
                    dojo.cookie(dojo.appConfigData.Credential, null, { expire: -1 });
                }
            }
        },

        _storeCredentials: function () {
            if (kernel.id.credentials.length === 0) {
                return;
            }
            var idString = JSON.stringify(kernel.id.toJson());
            if (this._supports_local_storage()) {
                window.localStorage.setItem(dojo.appConfigData.Credential, idString, { expires: 1 });
            } else {
                if (cookie.isSupported()) {
                    cookie(dojo.appConfigData.Credential, idString, { expires: 1 });
                }
            }
        },

        _createConfigurationPanel: function (response) {
            var _self = this, deferArray, configData, deferList, bookIndex;
            deferArray = [];
            array.forEach(response.results, function (itemData) {
                var defer = new Deferred();
                deferArray.push(defer);
                configData = esriRequest({
                    url: itemData.itemDataUrl,
                    itemId: itemData.id,
                    handleAs: "json"
                });
                configData.then(function (itemInfo) {
                    itemInfo.BookConfigData.itemId = itemData.id;
                    itemInfo.BookConfigData.owner = itemData.owner;
                    itemInfo.BookConfigData.UnSaveEditsExists = false;
                    defer.resolve(itemInfo);
                }, function (e) {
                    defer.resolve();
                });
                return defer;
            });

            deferList = new DeferredList(deferArray);
            deferList.then(function (results) {
                for (bookIndex = 0; bookIndex < results.length; bookIndex++) {
                    if (results[bookIndex][1]) {
                        if (results[bookIndex][1].BookConfigData && results[bookIndex][1].ModuleConfigData) {
                            dojo.bookInfo.push(results[bookIndex][1]);
                        }
                    }
                }
                topic.publish("authoringModeHandler");
            });
        },

        _queryOrgItems: function () {
            var _self = this, queryParams;
            dojo.appConfigData.AuthoringMode = false;
            queryParams = {
                q: "tags:" + dojo.appConfigData.ConfigSearchTag,
                sortField: dojo.appConfigData.SortField,
                sortOrder: dojo.appConfigData.SortOrder,
                num: 100
            };
            _self._portal.queryItems(queryParams).then(function (response) {
                dojo.bookInfo = [];
                _self._createConfigurationPanel(response);
            }, function (error) {
                _self.alertDialog._setContent(nls.errorMessages.contentQueryError, 0);
                domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
            });
        },

        _saveSelectedBook: function () {
            var configObj, queryParam, currentItemId, requestUrl, requestType;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            dojo.bookInfo[dojo.currentBookIndex].BookConfigData.UnSaveEditsExists = false;
            configObj = JSON.stringify(dojo.bookInfo[dojo.currentBookIndex]);
            queryParam = {
                itemType: "text",
                f: 'json',
                text: configObj,
                overwrite: true,
                url: ''
            };
            currentItemId = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId;
            if (currentItemId === nls.defaultItemId) {
                requestUrl = this._portal.getPortalUser().userContentUrl + '/addItem';
                queryParam.type = 'Web Mapping Application';
                queryParam.title = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.title;
                queryParam.tags = dojo.appConfigData.ConfigSearchTag;
                requestType = "add";

            } else {
                requestUrl = this._portal.getPortalUser().userContentUrl + '/items/' + currentItemId + '/update';
                requestType = "update";
                queryParam.url = this._getAppUrl() + '?bookId=' + currentItemId;
            }
            this._sendEsriRequest(queryParam, requestUrl, requestType);
        },

        _deleteBookItem: function () {
            var queryParam, currentItemId, requestUrl;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            queryParam = {
                f: 'json',
                overwrite: true
            };
            currentItemId = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId;
            requestUrl = this._portal.getPortalUser().userContentUrl + '/items/' + currentItemId + '/delete';
            this._sendEsriRequest(queryParam, requestUrl, "delete", nls.errorMessages.deletingItemError);
        },

        _copyBookItem: function () {
            var configObj, bookTitle, queryParam, copiedConfig, requestUrl, requestType;

            bookTitle = nls.copyKeyword + dojo.bookInfo[dojo.currentBookIndex].BookConfigData.title;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            copiedConfig = lang.clone(dojo.bookInfo[dojo.currentBookIndex]);
            copiedConfig.BookConfigData.copyProtected = false;
            copiedConfig.BookConfigData.UnSaveEditsExists = false;
            copiedConfig.BookConfigData.title = bookTitle;
            copiedConfig.ModuleConfigData.CoverPage.title.text = bookTitle;
            copiedConfig.BookConfigData.author = this._portal.getPortalUser().fullName;
            dojo.bookInfo.push(copiedConfig);
            dojo.currentBookIndex = dojo.bookInfo.length - 1;
            configObj = JSON.stringify(copiedConfig);
            queryParam = {
                itemType: "text",
                f: 'json',
                text: configObj,
                tags: dojo.appConfigData.ConfigSearchTag,
                title: copiedConfig.BookConfigData.title,
                type: 'Web Mapping Application'
            };
            requestUrl = this._portal.getPortalUser().userContentUrl + '/addItem';
            requestType = "copy";
            this._sendEsriRequest(queryParam, requestUrl, requestType);
        },

        _sendEsriRequest: function (queryParam, requestUrl, reqType) {
            var _self = this;
            esriRequest({
                url: requestUrl,
                content: queryParam,
                async: false,
                handleAs: 'json'
            }, { usePost: true }).then(function (result) {
                if (result.success) {
                    if (reqType === "copy" || reqType === "delete") {
                        if (reqType === "copy") {
                            dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId = result.id;
                            _self._saveSelectedBook();
                        }
                        topic.publish("destroyWebmapHandler");
                        setTimeout(function () {
                            _self._displayLoginDialog(false);
                        }, 2000);
                    } else {
                        dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId = result.id;
                        if (reqType === "add") {
                            _self._saveSelectedBook();
                        }
                        domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
                    }
                }
            }, function (err) {
                _self._genrateErrorMessage(reqType, err);
                domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
            });
        },

        _genrateErrorMessage: function (reqType, err) {
            var errorMsg;
            if (err.messageCode === "GWM_0003") {
                errorMsg = nls.errorMessages.permissionDenied;
            } else if (reqType === "add") {
                errorMsg = nls.errorMessages.addingItemError;
            } else if (reqType === "update") {
                errorMsg = nls.errorMessages.updatingItemError;
            } else if (reqType === "delete") {
                errorMsg = nls.errorMessages.deletingItemError;
            } else if (reqType === "copy") {
                errorMsg = nls.errorMessages.copyItemError;
            }
            this.alertDialog._setContent(errorMsg, 0);
        },

        _getFullUserName: function () {
            return this._portal.getPortalUser().fullName;
        },

        _getPortal: function () {
            return this._portal;
        },

        _setApplicationTheme: function () {
            var cssURL;
            switch (dojo.appConfigData.ApplicationTheme) {
                case "blue":
                    cssURL = "themes/styles/theme_blue.css";
                    break;

                case "grey":
                    cssURL = "themes/styles/theme_grey.css";
                    break;

                default:
                    cssURL = "themes/styles/theme_grey.css";
                    break;
            }
            if (dom.byId("appTheme")) {
                domAttr.set(dom.byId("appTheme"), "href", cssURL);
            }
        },

        _getAppUrl: function () {
            var appUrl = parent.location.href.split('?');
            return appUrl[0];
        }
    });
});

<commit_msg>Shielded call to OAuthHelper when we're using it without intending to use OAuth authentication<commit_after>/*global */
/*jslint browser:true,sloppy:true,nomen:true,unparam:true,plusplus:true */
/*
 | Copyright 2014 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
define([
    "dojo/_base/declare",
    "dojo/_base/array",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dojo/dom-construct",
    "dojo/dom-attr",
    "dojo/dom-style",
    "dojo/dom-class",
    "dojo/dom",
    "dojo/on",
    "dojo/query",
    "dojo/topic",
    "dojo/i18n!nls/localizedStrings",
    "esri/arcgis/Portal",
    "esri/arcgis/utils",
    "esri/config",
    "dojo/cookie",
    "esri/kernel",
    "esri/request",
    "esri/urlUtils",
    "esri/IdentityManager",
    "coreLibrary/OAuthHelper",
    "../alertDialog/alertDialog",
    "dojo/DeferredList",
    "dojo/_base/Deferred",
    "dojo/parser"
], function (declare, array, lang, _WidgetBase, domConstruct, domAttr, domStyle, domClass, dom, on, query, topic, nls, esriPortal, arcgisUtils, config, cookie, kernel, esriRequest, urlUtils, IdentityManager, OAuthHelper, alertBox, DeferredList, Deferred) {
    return declare([_WidgetBase], {
        _portal: null,
        startup: function () {
            var _self = this, deferred;
            _self.alertDialog = new alertBox();
            deferred = new Deferred();

            this._setApplicationTheme();

            topic.subscribe("saveBookHandler", function () {
                _self._saveSelectedBook();
            });

            topic.subscribe("deleteItemHandler", function () {
                _self._deleteBookItem();
            });

            topic.subscribe("copySelectedBookHandler", function () {
                _self._copyBookItem();
            });

            topic.subscribe("getFullUserNameHandler", function (newBook) {
                newBook.author = _self._getFullUserName();
            });

            topic.subscribe("toggleUserLogInHandler", function () {
                if (!domClass.contains(dom.byId("userLogIn"), "esriLogOutIcon")) {
                    _self._displayLoginDialog(false);
                } else {
                    _self._portal.signOut().then(function () {
                        _self._queryOrgItems(false);
                        _self._removeCredentials();
                        domClass.remove(dom.byId("userLogIn"), "esriLogOutIcon");
                        domAttr.set(dom.byId("userLogIn"), "title", nls.signInText);
                    });
                }
            });

            if (dojo.appConfigData.PortalURL) {
                this._portal = new esriPortal.Portal(dojo.appConfigData.PortalURL);
                dojo.connect(_self._portal, 'onLoad', function () {
                    _self._loadCredentials(deferred);
                });
            } else {
                deferred.reject();

            }
            return deferred.promise;
        },

        _displayLoginDialog: function (deferred) {

            var _self = this, queryParams;
            this._portal.signIn().then(function (loggedInUser) {
                if (dom.byId("outerLoadingIndicator")) {
                    domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
                }
                dojo.bookInfo = [];
                queryParams = {
                    q: "tags:" + dojo.appConfigData.ConfigSearchTag,
                    sortField: dojo.appConfigData.SortField,
                    sortOrder: dojo.appConfigData.SortOrder,
                    num: 100
                };
                _self._storeCredentials();
                dojo.appConfigData.AuthoringMode = true;
                if (dom.byId("userLogIn")) {
                    domClass.add(dom.byId("userLogIn"), "esriLogOutIcon");
                    domAttr.set(dom.byId("userLogIn"), "title", nls.signOutText);
                    dojo.currentUser = loggedInUser.username;
                }
                _self._portal.queryItems(queryParams).then(function (response) {
                    dojo.bookInfo = [];
                    topic.publish("destroyWebmapHandler");
                    topic.publish("_getPortal", _self._portal);
                    _self._createConfigurationPanel(response);

                });
            }, function (error) {
                if (error.httpCode === 403) {
                    _self.alertDialog._setContent(nls.validateOrganizationUser, 0);
                    IdentityManager.credentials[0].destroy();
                }
                if (dom.byId("outerLoadingIndicator")) {
                    domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
                }
            });
        },

        _loadCredentials: function (deferred) {
            deferred.resolve();
            var idJson, idObject, isCredAvailable = false, signedInViaOAuth = false;

            // If we've connected via OAuth, we can go ahead with the the behind-the-scenes login.
            // We shield the call because it throws an exception if OAuthHelper has not been
            // initialized, but we can only initialize OAuthHelper if we're intending to use it
            // (its initialization alters the Identity Manager, so we don't want to initialize it
            // all the time).
            try {
                signedInViaOAuth = OAuthHelper.isSignedIn();
            } catch (ignore) {
                signedInViaOAuth = false;
            }
            if (signedInViaOAuth) {
                this._displayLoginDialog(false);

            // Otherwise see if we've cached credentials
            } else {
                if (this._supports_local_storage()) {
                    idJson = window.localStorage.getItem(dojo.appConfigData.Credential);
                } else {
                    if (cookie.isSupported()) {
                        idJson = cookie(dojo.appConfigData.Credential);
                    }
                }
                if (idJson && idJson !== "null" && idJson.length > 4) {
                    idObject = JSON.parse(idJson);
                    if (idObject.credentials[0].expires > Date.now()) {
                        if (dojo.appConfigData.PortalURL === idObject.serverInfos[0].server) {
                            isCredAvailable = true;
                            kernel.id.initialize(idObject);
                            this._displayLoginDialog(deferred);
                        }
                    }
                }
            }

            if (!isCredAvailable) {
                this._queryOrgItems();
            }
        },

        _supports_local_storage: function () {
            try {
                return "localStorage" in window && window["localStorage"] !== null;
            } catch (e) {
                return false;
            }
        },

        _removeCredentials: function () {

            if (this._supports_local_storage()) {
                window.localStorage.setItem(dojo.appConfigData.Credential, null, { expire: -1 });
            } else {
                if (cookie.isSupported()) {
                    dojo.cookie(dojo.appConfigData.Credential, null, { expire: -1 });
                }
            }
        },

        _storeCredentials: function () {
            if (kernel.id.credentials.length === 0) {
                return;
            }
            var idString = JSON.stringify(kernel.id.toJson());
            if (this._supports_local_storage()) {
                window.localStorage.setItem(dojo.appConfigData.Credential, idString, { expires: 1 });
            } else {
                if (cookie.isSupported()) {
                    cookie(dojo.appConfigData.Credential, idString, { expires: 1 });
                }
            }
        },

        _createConfigurationPanel: function (response) {
            var _self = this, deferArray, configData, deferList, bookIndex;
            deferArray = [];
            array.forEach(response.results, function (itemData) {
                var defer = new Deferred();
                deferArray.push(defer);
                configData = esriRequest({
                    url: itemData.itemDataUrl,
                    itemId: itemData.id,
                    handleAs: "json"
                });
                configData.then(function (itemInfo) {
                    itemInfo.BookConfigData.itemId = itemData.id;
                    itemInfo.BookConfigData.owner = itemData.owner;
                    itemInfo.BookConfigData.UnSaveEditsExists = false;
                    defer.resolve(itemInfo);
                }, function (e) {
                    defer.resolve();
                });
                return defer;
            });

            deferList = new DeferredList(deferArray);
            deferList.then(function (results) {
                for (bookIndex = 0; bookIndex < results.length; bookIndex++) {
                    if (results[bookIndex][1]) {
                        if (results[bookIndex][1].BookConfigData && results[bookIndex][1].ModuleConfigData) {
                            dojo.bookInfo.push(results[bookIndex][1]);
                        }
                    }
                }
                topic.publish("authoringModeHandler");
            });
        },

        _queryOrgItems: function () {
            var _self = this, queryParams;
            dojo.appConfigData.AuthoringMode = false;
            queryParams = {
                q: "tags:" + dojo.appConfigData.ConfigSearchTag,
                sortField: dojo.appConfigData.SortField,
                sortOrder: dojo.appConfigData.SortOrder,
                num: 100
            };
            _self._portal.queryItems(queryParams).then(function (response) {
                dojo.bookInfo = [];
                _self._createConfigurationPanel(response);
            }, function (error) {
                _self.alertDialog._setContent(nls.errorMessages.contentQueryError, 0);
                domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
            });
        },

        _saveSelectedBook: function () {
            var configObj, queryParam, currentItemId, requestUrl, requestType;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            dojo.bookInfo[dojo.currentBookIndex].BookConfigData.UnSaveEditsExists = false;
            configObj = JSON.stringify(dojo.bookInfo[dojo.currentBookIndex]);
            queryParam = {
                itemType: "text",
                f: 'json',
                text: configObj,
                overwrite: true,
                url: ''
            };
            currentItemId = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId;
            if (currentItemId === nls.defaultItemId) {
                requestUrl = this._portal.getPortalUser().userContentUrl + '/addItem';
                queryParam.type = 'Web Mapping Application';
                queryParam.title = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.title;
                queryParam.tags = dojo.appConfigData.ConfigSearchTag;
                requestType = "add";

            } else {
                requestUrl = this._portal.getPortalUser().userContentUrl + '/items/' + currentItemId + '/update';
                requestType = "update";
                queryParam.url = this._getAppUrl() + '?bookId=' + currentItemId;
            }
            this._sendEsriRequest(queryParam, requestUrl, requestType);
        },

        _deleteBookItem: function () {
            var queryParam, currentItemId, requestUrl;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            queryParam = {
                f: 'json',
                overwrite: true
            };
            currentItemId = dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId;
            requestUrl = this._portal.getPortalUser().userContentUrl + '/items/' + currentItemId + '/delete';
            this._sendEsriRequest(queryParam, requestUrl, "delete", nls.errorMessages.deletingItemError);
        },

        _copyBookItem: function () {
            var configObj, bookTitle, queryParam, copiedConfig, requestUrl, requestType;

            bookTitle = nls.copyKeyword + dojo.bookInfo[dojo.currentBookIndex].BookConfigData.title;
            domStyle.set(dom.byId("outerLoadingIndicator"), "display", "block");
            copiedConfig = lang.clone(dojo.bookInfo[dojo.currentBookIndex]);
            copiedConfig.BookConfigData.copyProtected = false;
            copiedConfig.BookConfigData.UnSaveEditsExists = false;
            copiedConfig.BookConfigData.title = bookTitle;
            copiedConfig.ModuleConfigData.CoverPage.title.text = bookTitle;
            copiedConfig.BookConfigData.author = this._portal.getPortalUser().fullName;
            dojo.bookInfo.push(copiedConfig);
            dojo.currentBookIndex = dojo.bookInfo.length - 1;
            configObj = JSON.stringify(copiedConfig);
            queryParam = {
                itemType: "text",
                f: 'json',
                text: configObj,
                tags: dojo.appConfigData.ConfigSearchTag,
                title: copiedConfig.BookConfigData.title,
                type: 'Web Mapping Application'
            };
            requestUrl = this._portal.getPortalUser().userContentUrl + '/addItem';
            requestType = "copy";
            this._sendEsriRequest(queryParam, requestUrl, requestType);
        },

        _sendEsriRequest: function (queryParam, requestUrl, reqType) {
            var _self = this;
            esriRequest({
                url: requestUrl,
                content: queryParam,
                async: false,
                handleAs: 'json'
            }, { usePost: true }).then(function (result) {
                if (result.success) {
                    if (reqType === "copy" || reqType === "delete") {
                        if (reqType === "copy") {
                            dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId = result.id;
                            _self._saveSelectedBook();
                        }
                        topic.publish("destroyWebmapHandler");
                        setTimeout(function () {
                            _self._displayLoginDialog(false);
                        }, 2000);
                    } else {
                        dojo.bookInfo[dojo.currentBookIndex].BookConfigData.itemId = result.id;
                        if (reqType === "add") {
                            _self._saveSelectedBook();
                        }
                        domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
                    }
                }
            }, function (err) {
                _self._genrateErrorMessage(reqType, err);
                domStyle.set(dom.byId("outerLoadingIndicator"), "display", "none");
            });
        },

        _genrateErrorMessage: function (reqType, err) {
            var errorMsg;
            if (err.messageCode === "GWM_0003") {
                errorMsg = nls.errorMessages.permissionDenied;
            } else if (reqType === "add") {
                errorMsg = nls.errorMessages.addingItemError;
            } else if (reqType === "update") {
                errorMsg = nls.errorMessages.updatingItemError;
            } else if (reqType === "delete") {
                errorMsg = nls.errorMessages.deletingItemError;
            } else if (reqType === "copy") {
                errorMsg = nls.errorMessages.copyItemError;
            }
            this.alertDialog._setContent(errorMsg, 0);
        },

        _getFullUserName: function () {
            return this._portal.getPortalUser().fullName;
        },

        _getPortal: function () {
            return this._portal;
        },

        _setApplicationTheme: function () {
            var cssURL;
            switch (dojo.appConfigData.ApplicationTheme) {
                case "blue":
                    cssURL = "themes/styles/theme_blue.css";
                    break;

                case "grey":
                    cssURL = "themes/styles/theme_grey.css";
                    break;

                default:
                    cssURL = "themes/styles/theme_grey.css";
                    break;
            }
            if (dom.byId("appTheme")) {
                domAttr.set(dom.byId("appTheme"), "href", cssURL);
            }
        },

        _getAppUrl: function () {
            var appUrl = parent.location.href.split('?');
            return appUrl[0];
        }
    });
});

<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var path = require('path');
var fs = require('fs');

var port = process.env.PORT || 9000;
var ip = process.env.IP || 'localhost';
var publicDir = 'client';
var app = express();

var env = process.env.NODE_ENV || 'development';
if ('production' === env) {
    publicDir = 'public';
    ip = process.env.OPENSHIFT_NODEDIY_IP || ip;
    port = process.env.OPENSHIFT_NODEDIY_PORT || port;
}

app.use('/labs/rhlabsangular/', express.static(path.resolve(publicDir)));

app.get('/labs/rhlabsangular/*', function(req, res) {
    res.sendfile(path.resolve(publicDir + '/index.html'));
}).listen(port, ip, function () {
  console.log('Express server listening on %d, in %s mode', port, app.get('env'));
});
<commit_msg>actually needed that...<commit_after>'use strict';

var express = require('express');
var path = require('path');
var fs = require('fs');

var port = process.env.PORT || 9000;
var ip = process.env.IP || 'localhost';
var publicDir = 'client';
var app = express();

var env = process.env.NODE_ENV || 'development';
if ('production' === env) {
    publicDir = 'public';
    ip = process.env.OPENSHIFT_NODEDIY_IP || ip;
    port = process.env.OPENSHIFT_NODEDIY_PORT || port;
} else {
    app.use('/labs/rhlabsangular/', express.static(path.resolve('.tmp')));
}

app.use('/labs/rhlabsangular/', express.static(path.resolve(publicDir)));

app.get('/labs/rhlabsangular/*', function(req, res) {
    res.sendfile(path.resolve(publicDir + '/index.html'));
}).listen(port, ip, function () {
  console.log('Express server listening on %d, in %s mode', port, app.get('env'));
});
<|endoftext|>