<commit_before>//Dont change it
requirejs(['ext_editor_1', 'jquery_190', 'raphael_210'],
    function (ext, $, TableComponent) {

        var cur_slide = {};

        ext.set_start_game(function (this_e) {
        });

        ext.set_process_in(function (this_e, data) {
            cur_slide["in"] = data[0];
        });

        ext.set_process_out(function (this_e, data) {
            cur_slide["out"] = data[0];
        });

        ext.set_process_ext(function (this_e, data) {
            cur_slide.ext = data;
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_process_err(function (this_e, data) {
            cur_slide['error'] = data[0];
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_animate_success_slide(function (this_e, options) {
            var $h = $(this_e.setHtmlSlide('

'));
            this_e.setAnimationHeight(115);
        });

        ext.set_animate_slide(function (this_e, data, options) {
            var $content = $(this_e.setHtmlSlide(ext.get_template('animation'))).find('.animation-content');
            if (!data) {
                console.log("data is undefined");
                return false;
            }

            //YOUR FUNCTION NAME
            var fname = 'divide_pie';

            var checkioInput = data.in || [2, -1, 3];

            var checkioInputStr = fname + "(" + JSON.stringify(checkioInput).replace("(", "[").replace(")", "]") + ")";

            var failError = function (dError) {
                $content.find('.call').html('Fail: ' + checkioInputStr);
                $content.find('.output').html(dError.replace(/\n/g, ","));

                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
                $content.find('.answer').remove();
                $content.find('.explanation').remove();
                this_e.setAnimationHeight($content.height() + 60);
            };

            if (data.error) {
                failError(data.error);
                return false;
            }

            if (data.ext && data.ext.inspector_fail) {
                failError(data.ext.inspector_result_addon);
                return false;
            }

            var rightResult = data.ext["answer"];
            var rightResultShow = data.ext["show_answer"];
            var userResult = data.out[1];
            var result = data.ext["result"];
            var userResultShow = data.ext["result_addon"];

            //if you need additional info from tests (if exists)
            var explanation = data.ext["explanation"];

            $content.find('.output').html(' Your result: ' + userResultShow);

            if (!result) {
                $content.find('.call').html('Fail: ' + checkioInputStr);
                $content.find('.answer').html('Right result: ' + rightResult);
                $content.find('.answer').addClass('error');
                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
            }
            else {
                $content.find('.call').html('Pass: ' + checkioInputStr);
                $content.find('.answer').remove();
            }

            if (explanation) {
                var canvas = new Canvas($content.find(".explanation")[0]);
                canvas.draw(explanation);
//                canvas.animate(explanation);
            }

            this_e.setAnimationHeight($content.height() + 60);

        });

        //This is for Tryit (but not necessary)
//        var $tryit;
//        ext.set_console_process_ret(function (this_e, ret) {
//            $tryit.find(".checkio-result").html("Result
" + ret);
//        });
//
//        ext.set_generate_animation_panel(function (this_e) {
//            $tryit = $(this_e.setHtmlTryIt(ext.get_template('tryit'))).find('.tryit-content');
//            $tryit.find('.bn-check').click(function (e) {
//                e.preventDefault();
//                this_e.sendToConsoleCheckiO("something");
//            });
//        });
        function Canvas(dom) {

            var colorOrange4 = "#F0801A";
            var colorOrange3 = "#FA8F00";
            var colorOrange2 = "#FAA600";
            var colorOrange1 = "#FABA00";

            var colorBlue4 = "#294270";
            var colorBlue3 = "#006CA9";
            var colorBlue2 = "#65A1CF";
            var colorBlue1 = "#8FC7ED";

            var colorGrey4 = "#737370";
            var colorGrey3 = "#9D9E9E";
            var colorGrey2 = "#C5C6C6";
            var colorGrey1 = "#EBEDED";

            var colorWhite = "#FFFFFF";

            var padding = 10;

            var R = 150;

            var size = padding * 2 + R * 2;

            var center = size / 2;

            var paper = Raphael(dom, size, size);

            var arc;

            var attrShadow = {"stroke": colorBlue4, "fill": colorBlue1, "stroke-width": 3};
            var attrLine = {"stroke": colorBlue4, "stroke-width": 2};
            var attrRem = {"stroke": colorBlue4, "stroke-width": 3, "fill": colorOrange1};

            this.draw = function (parts) {
                paper.circle(size / 2, size / 2, R).attr(attrShadow);
                for (var i = 0; i < parts.length; i++) {
                    var p = parts[i];
                    var angle = 2 * Math.PI * p[0] / p[1];
                    paper.path([
                        ["M", center, center],
                        ["L", center + Math.sin(angle) * R, center - Math.cos(angle) * R]
                    ]).attr(attrLine);
                }
                paper.path([
                    ["M", center, center],
                    ["L", center, padding],
                    ["A", R, R, 0, angle > Math.PI ? 1 : 0, 1, center + Math.sin(angle) * R, center - Math.cos(angle) * R],
                    ["z"]
                ]).attr(attrRem);

            };

//            this.animate = function (parts) {
//                var i = 0;
//                var stepTime = 1000;
//                var delayTime = 300;
//                (function cut() {
//                    i++;
//                    if (i >= parts.length) return false;
//                    setTimeout(function () {
//                        var p = parts[i];
//                        var angle = 2 * Math.PI * p[0] / p[1];
//                        console.log(p, angle);
//                        console.log(arc.attr("path"));
//                        arc.animate({"path": [
//                            ["M", center, center],
//                            ["L", center - 1, padding],
//                            ["A", R, R, 0, angle > Math.PI ? 1 : 0, 1, center + Math.sin(angle) * R, center - Math.cos(angle) * R],
//                            ["z"]
//                        ]}, stepTime, callback = cut);
//                    }, delayTime);
//                })();
//            }
        }

    }
);
<commit_msg>Update init.js<commit_after>//Dont change it please
requirejs(['ext_editor_1', 'jquery_190', 'raphael_210'],
    function (ext, $, TableComponent) {

        var cur_slide = {};

        ext.set_start_game(function (this_e) {
        });

        ext.set_process_in(function (this_e, data) {
            cur_slide["in"] = data[0];
        });

        ext.set_process_out(function (this_e, data) {
            cur_slide["out"] = data[0];
        });

        ext.set_process_ext(function (this_e, data) {
            cur_slide.ext = data;
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_process_err(function (this_e, data) {
            cur_slide['error'] = data[0];
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_animate_success_slide(function (this_e, options) {
            var $h = $(this_e.setHtmlSlide('

'));
            this_e.setAnimationHeight(115);
        });

        ext.set_animate_slide(function (this_e, data, options) {
            var $content = $(this_e.setHtmlSlide(ext.get_template('animation'))).find('.animation-content');
            if (!data) {
                console.log("data is undefined");
                return false;
            }

            //YOUR FUNCTION NAME
            var fname = 'divide_pie';

            var checkioInput = data.in || [2, -1, 3];

            var checkioInputStr = fname + "(" + JSON.stringify(checkioInput).replace("(", "[").replace(")", "]") + ")";

            var failError = function (dError) {
                $content.find('.call').html('Fail: ' + checkioInputStr);
                $content.find('.output').html(dError.replace(/\n/g, ","));

                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
                $content.find('.answer').remove();
                $content.find('.explanation').remove();
                this_e.setAnimationHeight($content.height() + 60);
            };

            if (data.error) {
                failError(data.error);
                return false;
            }

            if (data.ext && data.ext.inspector_fail) {
                failError(data.ext.inspector_result_addon);
                return false;
            }

            var rightResult = data.ext["answer"];
            var rightResultShow = data.ext["show_answer"];
            var userResult = data.out[1];
            var result = data.ext["result"];
            var userResultShow = data.ext["result_addon"];

            //if you need additional info from tests (if exists)
            var explanation = data.ext["explanation"];

            $content.find('.output').html(' Your result: ' + userResultShow);

            if (!result) {
                $content.find('.call').html('Fail: ' + checkioInputStr);
                $content.find('.answer').html('Right result: ' + rightResult);
                $content.find('.answer').addClass('error');
                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
            }
            else {
                $content.find('.call').html('Pass: ' + checkioInputStr);
                $content.find('.answer').remove();
            }

            if (explanation) {
                var canvas = new Canvas($content.find(".explanation")[0]);
                canvas.draw(explanation);
//                canvas.animate(explanation);
            }

            this_e.setAnimationHeight($content.height() + 60);

        });

        //This is for Tryit (but not necessary)
//        var $tryit;
//        ext.set_console_process_ret(function (this_e, ret) {
//            $tryit.find(".checkio-result").html("Result
" + ret);
//        });
//
//        ext.set_generate_animation_panel(function (this_e) {
//            $tryit = $(this_e.setHtmlTryIt(ext.get_template('tryit'))).find('.tryit-content');
//            $tryit.find('.bn-check').click(function (e) {
//                e.preventDefault();
//                this_e.sendToConsoleCheckiO("something");
//            });
//        });
        function Canvas(dom) {

            var colorOrange4 = "#F0801A";
            var colorOrange3 = "#FA8F00";
            var colorOrange2 = "#FAA600";
            var colorOrange1 = "#FABA00";

            var colorBlue4 = "#294270";
            var colorBlue3 = "#006CA9";
            var colorBlue2 = "#65A1CF";
            var colorBlue1 = "#8FC7ED";

            var colorGrey4 = "#737370";
            var colorGrey3 = "#9D9E9E";
            var colorGrey2 = "#C5C6C6";
            var colorGrey1 = "#EBEDED";

            var colorWhite = "#FFFFFF";

            var padding = 10;

            var R = 150;

            var size = padding * 2 + R * 2;

            var center = size / 2;

            var paper = Raphael(dom, size, size);

            var arc;

            var attrShadow = {"stroke": colorBlue4, "fill": colorBlue1, "stroke-width": 3};
            var attrLine = {"stroke": colorBlue4, "stroke-width": 2};
            var attrRem = {"stroke": colorBlue4, "stroke-width": 3, "fill": colorOrange1};

            this.draw = function (parts) {
                paper.circle(size / 2, size / 2, R).attr(attrShadow);
                for (var i = 0; i < parts.length; i++) {
                    var p = parts[i];
                    var angle = 2 * Math.PI * p[0] / p[1];
                    paper.path([
                        ["M", center, center],
                        ["L", center + Math.sin(angle) * R, center - Math.cos(angle) * R]
                    ]).attr(attrLine);
                }
                paper.path([
                    ["M", center, center],
                    ["L", center, padding],
                    ["A", R, R, 0, angle > Math.PI ? 1 : 0, 1, center + Math.sin(angle) * R, center - Math.cos(angle) * R],
                    ["z"]
                ]).attr(attrRem);

            };

//            this.animate = function (parts) {
//                var i = 0;
//                var stepTime = 1000;
//                var delayTime = 300;
//                (function cut() {
//                    i++;
//                    if (i >= parts.length) return false;
//                    setTimeout(function () {
//                        var p = parts[i];
//                        var angle = 2 * Math.PI * p[0] / p[1];
//                        console.log(p, angle);
//                        console.log(arc.attr("path"));
//                        arc.animate({"path": [
//                            ["M", center, center],
//                            ["L", center - 1, padding],
//                            ["A", R, R, 0, angle > Math.PI ? 1 : 0, 1, center + Math.sin(angle) * R, center - Math.cos(angle) * R],
//                            ["z"]
//                        ]}, stepTime, callback = cut);
//                    }, delayTime);
//                })();
//            }
        }

    }
);
<|endoftext|>


<commit_before>/*globals svgEditor */
svgEditor.readLang({
	lang: "it",
	dir : "ltr",
	common: {
		"ok": "Salva",
		"cancel": "Annulla",
		"key_backspace": "backspace",
		"key_del": "Canc",
		"key_down": "giù",
		"key_up": "su",
		"more_opts": "More Options",
		"url": "URL",
		"width": "Width",
		"height": "Height"
	},
	misc: {
		"powered_by": "Powered by"
	},
	ui: {
		"toggle_stroke_tools": "Mostra/nascondi strumenti per il tratto",
		"palette_info": "Fare clic per cambiare il colore di riempimento, shift-click per cambiare colore del tratto",
		"zoom_level": "Cambia il livello di zoom",
		"panel_drag": "Drag left/right to resize side panel"
	},
	properties: {
		"id": "Identifica l'elemento",
		"fill_color": "Cambia il colore di riempimento",
		"stroke_color": "Cambia il colore del tratto",
		"stroke_style": "Cambia lo stile del tratto",
		"stroke_width": "Cambia la larghezza del tratto",
		"pos_x": "Modifica la coordinata x",
		"pos_y": "Modifica la coordinata y",
		"linecap_butt": "Inizio linea: Punto",
		"linecap_round": "Inizio linea: Tondo",
		"linecap_square": "Inizio linea: Quadrato",
		"linejoin_bevel": "Giunzione: smussata",
		"linejoin_miter": "Giunzione: spezzata",
		"linejoin_round": "Giunzione: arrotondata",
		"angle": "Cambia l'angolo di rotazione",
		"blur": "Cambia l'intensità della sfocatura",
		"opacity": "Cambia l'opacità dell'oggetto selezionato",
		"circle_cx": "Cambia la coordinata Cx del cerchio",
		"circle_cy": "Cambia la coordinata Cy del cerchio",
		"circle_r": "Cambia il raggio del cerchio",
		"ellipse_cx": "Cambia la coordinata Cx dell'ellisse",
		"ellipse_cy": "Cambia la coordinata Cy dell'ellisse",
		"ellipse_rx": "Cambia l'asse x dell'ellisse",
		"ellipse_ry": "Cambia l'asse y dell'ellisse",
		"line_x1": "Modifica la coordinata iniziale x della linea",
		"line_x2": "Modifica la coordinata finale x della linea",
		"line_y1": "Modifica la coordinata iniziale y della linea",
		"line_y2": "Modifica la coordinata finale y della linea",
		"rect_height": "Cambia l'altezza rettangolo",
		"rect_width": "Cambia la larghezza rettangolo",
		"corner_radius": "Cambia il raggio dell'angolo",
		"image_width": "Cambia la larghezza dell'immagine",
		"image_height": "Cambia l'altezza dell'immagine",
		"image_url": "Cambia URL",
		"node_x": "Modifica la coordinata x del nodo",
		"node_y": "Modifica la coordinata y del nodo",
		"seg_type": "Cambia il tipo di segmento",
		"straight_segments": "Linea retta",
		"curve_segments": "Curva",
		"text_contents": "Cambia il contenuto del testo",
		"font_family": "Cambia il tipo di Font",
		"font_size": "Modifica dimensione carattere",
		"bold": "Grassetto",
		"italic": "Corsivo"
	},
	tools: {
		"main_menu": "Menù principale",
		"bkgnd_color_opac": "Cambia colore/opacità dello sfondo",
		"connector_no_arrow": "No freccia",
		"fitToContent": "Adatta al contenuto",
		"fit_to_all": "Adatta a tutti i contenuti",
		"fit_to_canvas": "Adatta all'area di disegno",
		"fit_to_layer_content": "Adatta al contenuto del livello",
		"fit_to_sel": "Adatta alla selezione",
		"align_relative_to": "Allineati a ...",
		"relativeTo": "Rispetto a:",
		"Pagina": "Pagina",
		"largest_object": "Oggetto più grande",
		"selected_objects": "Oggetti selezionati",
		"smallest_object": "Oggetto più piccolo",
		"new_doc": "Nuova immagine",
		"open_doc": "Apri immagine",
		"export_img": "Export",
		"save_doc": "Salva",
		"import_doc": "Importa SVG",
		"align_to_page": "Allinea elementi alla pagina",
		"align_bottom": "Allinea in basso",
		"align_center": "Allinea al centro",
		"align_left": "Allinea a sinistra",
		"align_middle": "Allinea al centro",
		"align_right": "Allinea a destra",
		"align_top": "Allinea in alto",
		"mode_select": "Seleziona",
		"mode_fhpath": "Matita",
		"mode_line": "Linea",
		"mode_connect": "Collega due oggetti",
		"mode_rect": "Rectangle Tool",
		"mode_square": "Square Tool",
		"mode_fhrect": "Rettangolo a mano libera",
		"mode_ellipse": "Ellisse",
		"mode_circle": "Cerchio",
		"mode_fhellipse": "Ellisse a mano libera",
		"mode_path": "Spezzata",
		"mode_shapelib": "Shape library",
		"mode_text": "Testo",
		"mode_image": "Immagine",
		"mode_zoom": "Zoom",
		"mode_eyedropper": "Seleziona colore",
		"no_embed": "NOTA: L'immagine non può essere incorporata: dipenderà dal percorso assoluto per essere vista",
		"undo": "Annulla",
		"redo": "Rifai",
		"tool_source": "Modifica sorgente",
		"wireframe_mode": "Contorno",
		"toggle_grid": "Show/Hide Grid",
		"clone": "Clone Element(s)",
		"del": "Delete Element(s)",
		"group_elements": "Raggruppa elementi",
		"make_link": "Make (hyper)link",
		"set_link_url": "Set link URL (leave empty to remove)",
		"to_path": "Converti in tracciato",
		"reorient_path": "Riallinea",
		"ungroup": "Separa gli elementi",
		"docprops": "Proprietà del documento",
		"imagelib": "Image Library",
		"move_bottom": "Sposta in fondo",
		"move_top": "Sposta in cima",
		"node_clone": "Clona nodo",
		"node_delete": "Elimina nodo",
		"node_link": "Collegamento tra punti di controllo",
		"add_subpath": "Aggiungi sotto-percorso",
		"openclose_path": "Apri/chiudi spezzata",
		"source_save": "Salva",
		"cut": "Cut",
		"copy": "Copy",
		"paste": "Paste",
		"paste_in_place": "Paste in Place",
		"Canc": "Delete",
		"group": "Group",
		"move_front": "Bring to Front",
		"move_up": "Bring Forward",
		"move_down": "Send Backward",
		"move_back": "Send to Back"
	},
	layers: {
		"layer":"Livello",
		"layers": "Layers",
		"del": "Elimina il livello",
		"move_down": "Sposta indietro il livello",
		"new": "Nuovo livello",
		"rename": "Rinomina il livello",
		"move_up": "Sposta avanti il livello",
		"dupe": "Duplicate Layer",
		"merge_down": "Merge Down",
		"merge_all": "Merge All",
		"move_elems_to": "Sposta verso:",
		"move_selected": "Sposta gli elementi in un diverso livello"
	},
	config: {
		"image_props": "Proprietà Immagine",
		"doc_title": "Titolo",
		"doc_dims": "Dimensioni dell'area di disegno",
		"included_images": "Immagini incluse",
		"image_opt_embed": "Incorpora dati (file locali)",
		"image_opt_ref": "Usa l'identificativo di riferimento",
		"editor_prefs": "Preferenze",
		"icon_size": "Dimensione Icona",
		"language": "Lingua",
		"background": "Sfondo dell'editor",
		"editor_img_url": "Image URL",
		"editor_bg_note": "Nota: Lo sfondo non verrà salvato con l'immagine.",
		"icon_large": "Grande",
		"icon_medium": "Medio",
		"icon_small": "Piccolo",
		"icon_xlarge": "Molto grande",
		"select_predefined": "Selezioni predefinite:",
		"units_and_rulers": "Units & Rulers",
		"show_rulers": "Show rulers",
		"base_unit": "Base Unit:",
		"grid": "Grid",
		"snapping_onoff": "Snapping on/off",
		"snapping_stepsize": "Snapping Step-Size:",
		"grid_color": "Grid color"
	},
	shape_cats: {
		"basic": "Basic",
		"object": "Objects",
		"symbol": "Symbols",
		"arrow": "Arrows",
		"flowchart": "Flowchart",
		"animal": "Animals",
		"game": "Cards & Chess",
		"dialog_balloon": "Dialog balloons",
		"electronics": "Electronics",
		"math": "Mathematical",
		"music": "Music",
		"misc": "Miscellaneous",
		"raphael_1": "raphaeljs.com set 1",
		"raphael_2": "raphaeljs.com set 2"
	},
	imagelib: {
		"select_lib": "Select an image library",
		"show_list": "Show library list",
		"import_single": "Import single",
		"import_multi": "Import multiple",
		"open": "Open as new document"
	},
	notification: {
		"invalidAttrValGiven":"Valore assegnato non valido",
		"noContentToFitTo":"Non c'è contenuto cui adeguarsi",
		"dupeLayerName":"C'è già un livello con questo nome!",
		"enterUniqueLayerName":"Assegna un diverso nome a ciascun livello, grazie!",
		"enterNewLayerName":"Assegna un nome al livello",
		"layerHasThatName":"Un livello ha già questo nome",
		"QmoveElemsToLayer":"Sposta gli elementi selezionali al livello '%s'?",
		"QwantToClear":"Vuoi cancellare il disegno?\nVerrà eliminato anche lo storico delle modifiche!",
		"QwantToOpen":"Do you want to open a new file?\nThis will also erase your undo history!",
		"QerrorsRevertToSource":"Ci sono errori nel codice sorgente SVG.\nRitorno al codice originale?",
		"QignoreSourceChanges":"Ignoro i cambiamenti nel sorgente SVG?",
		"featNotSupported":"Caratteristica non supportata",
		"enterNewImgURL":"Scrivi un nuovo URL per l'immagine",
		"defsFailOnSave": "NOTA: A causa dlle caratteristiche del tuo browser, l'immagine potrà apparire errata (senza elementi o gradazioni) finché non sarà salvata.",
		"loadingImage":"Sto caricando l'immagine. attendere prego...",
		"saveFromBrowser": "Seleziona \"Salva con nome...\" nel browser per salvare l'immagine con nome %s .",
		"noteTheseIssues": "Nota le seguenti particolarità: ",
		"unsavedChanges": "There are unsaved changes.",
		"enterNewLinkURL": "Enter the new hyperlink URL",
		"errorLoadingSVG": "Error: Unable to load SVG data",
		"URLloadFail": "Unable to load from URL",
		"retrieving": "Retrieving \"%s\"..."
	},
	confirmSetStorage: {
		message: "By default and where supported, SVG-Edit can store your editor "+
		"preferences and SVG content locally on your machine so you do not "+
		"need to add these back each time you load SVG-Edit. If, for privacy "+
		"reasons, you do not wish to store this information on your machine, "+
		"you can change away from the default option below.",
		storagePrefsAndContent: "Store preferences and SVG content locally",
		storagePrefsOnly: "Only store preferences locally",
		storagePrefs: "Store preferences locally",
		storageNoPrefsOrContent: "Do not store my preferences or SVG content locally",
		storageNoPrefs: "Do not store my preferences locally",
		rememberLabel: "Remember this choice?",
		rememberTooltip: "If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again."
	}
});<commit_msg>Update lang.it.js<commit_after>/*globals svgEditor */
svgEditor.readLang({
	lang: "it",
	dir : "ltr",
	common: {
		"ok": "Salva",
		"cancel": "Annulla",
		"key_backspace": "backspace",
		"key_del": "Canc",
		"key_down": "giù",
		"key_up": "su",
		"more_opts": "More Options",
		"url": "URL",
		"width": "Width",
		"height": "Height"
	},
	misc: {
		"powered_by": "Powered by"
	},
	ui: {
		"toggle_stroke_tools": "Mostra/nascondi strumenti per il tratto",
		"palette_info": "Fare clic per cambiare il colore di riempimento, shift-click per cambiare colore del tratto",
		"zoom_level": "Cambia il livello di zoom",
		"panel_drag": "Drag left/right to resize side panel"
	},
	properties: {
		"id": "Identifica l'elemento",
		"fill_color": "Cambia il colore di riempimento",
		"stroke_color": "Cambia il colore del tratto",
		"stroke_style": "Cambia lo stile del tratto",
		"stroke_width": "Cambia la larghezza del tratto",
		"pos_x": "Modifica la coordinata x",
		"pos_y": "Modifica la coordinata y",
		"linecap_butt": "Inizio linea: Punto",
		"linecap_round": "Inizio linea: Tondo",
		"linecap_square": "Inizio linea: Quadrato",
		"linejoin_bevel": "Giunzione: smussata",
		"linejoin_miter": "Giunzione: spezzata",
		"linejoin_round": "Giunzione: arrotondata",
		"angle": "Cambia l'angolo di rotazione",
		"blur": "Cambia l'intensità della sfocatura",
		"opacity": "Cambia l'opacità dell'oggetto selezionato",
		"circle_cx": "Cambia la coordinata Cx del cerchio",
		"circle_cy": "Cambia la coordinata Cy del cerchio",
		"circle_r": "Cambia il raggio del cerchio",
		"ellipse_cx": "Cambia la coordinata Cx dell'ellisse",
		"ellipse_cy": "Cambia la coordinata Cy dell'ellisse",
		"ellipse_rx": "Cambia l'asse x dell'ellisse",
		"ellipse_ry": "Cambia l'asse y dell'ellisse",
		"line_x1": "Modifica la coordinata iniziale x della linea",
		"line_x2": "Modifica la coordinata finale x della linea",
		"line_y1": "Modifica la coordinata iniziale y della linea",
		"line_y2": "Modifica la coordinata finale y della linea",
		"rect_height": "Cambia l'altezza rettangolo",
		"rect_width": "Cambia la larghezza rettangolo",
		"corner_radius": "Cambia il raggio dell'angolo",
		"image_width": "Cambia la larghezza dell'immagine",
		"image_height": "Cambia l'altezza dell'immagine",
		"image_url": "Cambia URL",
		"node_x": "Modifica la coordinata x del nodo",
		"node_y": "Modifica la coordinata y del nodo",
		"seg_type": "Cambia il tipo di segmento",
		"straight_segments": "Linea retta",
		"curve_segments": "Curva",
		"text_contents": "Cambia il contenuto del testo",
		"font_family": "Cambia il tipo di Font",
		"font_size": "Modifica dimensione carattere",
		"bold": "Grassetto",
		"italic": "Corsivo"
	},
	tools: {
		"main_menu": "Menù principale",
		"bkgnd_color_opac": "Cambia colore/opacità dello sfondo",
		"connector_no_arrow": "No freccia",
		"fitToContent": "Adatta al contenuto",
		"fit_to_all": "Adatta a tutti i contenuti",
		"fit_to_canvas": "Adatta all'area di disegno",
		"fit_to_layer_content": "Adatta al contenuto del livello",
		"fit_to_sel": "Adatta alla selezione",
		"align_relative_to": "Allineati a ...",
		"relativeTo": "Rispetto a:",
		"page": "Pagina",
		"largest_object": "Oggetto più grande",
		"selected_objects": "Oggetti selezionati",
		"smallest_object": "Oggetto più piccolo",
		"new_doc": "Nuova immagine",
		"open_doc": "Apri immagine",
		"export_img": "Export",
		"save_doc": "Salva",
		"import_doc": "Importa SVG",
		"align_to_page": "Allinea elementi alla pagina",
		"align_bottom": "Allinea in basso",
		"align_center": "Allinea al centro",
		"align_left": "Allinea a sinistra",
		"align_middle": "Allinea al centro",
		"align_right": "Allinea a destra",
		"align_top": "Allinea in alto",
		"mode_select": "Seleziona",
		"mode_fhpath": "Matita",
		"mode_line": "Linea",
		"mode_connect": "Collega due oggetti",
		"mode_rect": "Rectangle Tool",
		"mode_square": "Square Tool",
		"mode_fhrect": "Rettangolo a mano libera",
		"mode_ellipse": "Ellisse",
		"mode_circle": "Cerchio",
		"mode_fhellipse": "Ellisse a mano libera",
		"mode_path": "Spezzata",
		"mode_shapelib": "Shape library",
		"mode_text": "Testo",
		"mode_image": "Immagine",
		"mode_zoom": "Zoom",
		"mode_eyedropper": "Seleziona colore",
		"no_embed": "NOTA: L'immagine non può essere incorporata: dipenderà dal percorso assoluto per essere vista",
		"undo": "Annulla",
		"redo": "Rifai",
		"tool_source": "Modifica sorgente",
		"wireframe_mode": "Contorno",
		"toggle_grid": "Show/Hide Grid",
		"clone": "Clone Element(s)",
		"del": "Delete Element(s)",
		"group_elements": "Raggruppa elementi",
		"make_link": "Make (hyper)link",
		"set_link_url": "Set link URL (leave empty to remove)",
		"to_path": "Converti in tracciato",
		"reorient_path": "Riallinea",
		"ungroup": "Separa gli elementi",
		"docprops": "Proprietà del documento",
		"imagelib": "Image Library",
		"move_bottom": "Sposta in fondo",
		"move_top": "Sposta in cima",
		"node_clone": "Clona nodo",
		"node_delete": "Elimina nodo",
		"node_link": "Collegamento tra punti di controllo",
		"add_subpath": "Aggiungi sotto-percorso",
		"openclose_path": "Apri/chiudi spezzata",
		"source_save": "Salva",
		"cut": "Cut",
		"copy": "Copy",
		"paste": "Paste",
		"paste_in_place": "Paste in Place",
		"delete": "Delete",
		"group": "Group",
		"move_front": "Bring to Front",
		"move_up": "Bring Forward",
		"move_down": "Send Backward",
		"move_back": "Send to Back"
	},
	layers: {
		"layer":"Livello",
		"layers": "Layers",
		"del": "Elimina il livello",
		"move_down": "Sposta indietro il livello",
		"new": "Nuovo livello",
		"rename": "Rinomina il livello",
		"move_up": "Sposta avanti il livello",
		"dupe": "Duplicate Layer",
		"merge_down": "Merge Down",
		"merge_all": "Merge All",
		"move_elems_to": "Sposta verso:",
		"move_selected": "Sposta gli elementi in un diverso livello"
	},
	config: {
		"image_props": "Proprietà Immagine",
		"doc_title": "Titolo",
		"doc_dims": "Dimensioni dell'area di disegno",
		"included_images": "Immagini incluse",
		"image_opt_embed": "Incorpora dati (file locali)",
		"image_opt_ref": "Usa l'identificativo di riferimento",
		"editor_prefs": "Preferenze",
		"icon_size": "Dimensione Icona",
		"language": "Lingua",
		"background": "Sfondo dell'editor",
		"editor_img_url": "Image URL",
		"editor_bg_note": "Nota: Lo sfondo non verrà salvato con l'immagine.",
		"icon_large": "Grande",
		"icon_medium": "Medio",
		"icon_small": "Piccolo",
		"icon_xlarge": "Molto grande",
		"select_predefined": "Selezioni predefinite:",
		"units_and_rulers": "Units & Rulers",
		"show_rulers": "Show rulers",
		"base_unit": "Base Unit:",
		"grid": "Grid",
		"snapping_onoff": "Snapping on/off",
		"snapping_stepsize": "Snapping Step-Size:",
		"grid_color": "Grid color"
	},
	shape_cats: {
		"basic": "Basic",
		"object": "Objects",
		"symbol": "Symbols",
		"arrow": "Arrows",
		"flowchart": "Flowchart",
		"animal": "Animals",
		"game": "Cards & Chess",
		"dialog_balloon": "Dialog balloons",
		"electronics": "Electronics",
		"math": "Mathematical",
		"music": "Music",
		"misc": "Miscellaneous",
		"raphael_1": "raphaeljs.com set 1",
		"raphael_2": "raphaeljs.com set 2"
	},
	imagelib: {
		"select_lib": "Select an image library",
		"show_list": "Show library list",
		"import_single": "Import single",
		"import_multi": "Import multiple",
		"open": "Open as new document"
	},
	notification: {
		"invalidAttrValGiven":"Valore assegnato non valido",
		"noContentToFitTo":"Non c'è contenuto cui adeguarsi",
		"dupeLayerName":"C'è già un livello con questo nome!",
		"enterUniqueLayerName":"Assegna un diverso nome a ciascun livello, grazie!",
		"enterNewLayerName":"Assegna un nome al livello",
		"layerHasThatName":"Un livello ha già questo nome",
		"QmoveElemsToLayer":"Sposta gli elementi selezionali al livello '%s'?",
		"QwantToClear":"Vuoi cancellare il disegno?\nVerrà eliminato anche lo storico delle modifiche!",
		"QwantToOpen":"Do you want to open a new file?\nThis will also erase your undo history!",
		"QerrorsRevertToSource":"Ci sono errori nel codice sorgente SVG.\nRitorno al codice originale?",
		"QignoreSourceChanges":"Ignoro i cambiamenti nel sorgente SVG?",
		"featNotSupported":"Caratteristica non supportata",
		"enterNewImgURL":"Scrivi un nuovo URL per l'immagine",
		"defsFailOnSave": "NOTA: A causa dlle caratteristiche del tuo browser, l'immagine potrà apparire errata (senza elementi o gradazioni) finché non sarà salvata.",
		"loadingImage":"Sto caricando l'immagine. attendere prego...",
		"saveFromBrowser": "Seleziona \"Salva con nome...\" nel browser per salvare l'immagine con nome %s .",
		"noteTheseIssues": "Nota le seguenti particolarità: ",
		"unsavedChanges": "There are unsaved changes.",
		"enterNewLinkURL": "Enter the new hyperlink URL",
		"errorLoadingSVG": "Error: Unable to load SVG data",
		"URLloadFail": "Unable to load from URL",
		"retrieving": "Retrieving \"%s\"..."
	},
	confirmSetStorage: {
		message: "By default and where supported, SVG-Edit can store your editor "+
		"preferences and SVG content locally on your machine so you do not "+
		"need to add these back each time you load SVG-Edit. If, for privacy "+
		"reasons, you do not wish to store this information on your machine, "+
		"you can change away from the default option below.",
		storagePrefsAndContent: "Store preferences and SVG content locally",
		storagePrefsOnly: "Only store preferences locally",
		storagePrefs: "Store preferences locally",
		storageNoPrefsOrContent: "Do not store my preferences or SVG content locally",
		storageNoPrefs: "Do not store my preferences locally",
		rememberLabel: "Remember this choice?",
		rememberTooltip: "If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again."
	}
});
<|endoftext|>


<commit_before>/**
 * Create a new photon. Takes an initial position X and a 3-velocity V,
 * which will be rescaled to have a magnitude of c.
 */
function photon(X, V, label, options) {
    this.X0 = X;
    this.rPast = 1;
    this.XView = quat4.create();
    this.V = V;

    // Normalize V such that V[3] = 1 and V[3]^2-V[2]^2-V[1]^2-V[0]^2 = 0
    // (i.e. |V| (including the metric) is 0)
    this.V[3] = 1;
    vec3.scale(this.V, this.V[3] / Math.sqrt(quat4.spaceDot(this.V, this.V)));

    this.displace = quat4.create();

    this.tau = 0;

    this.uDisplacement = quat4.create();
    this.viewTime = 0;
    this.radialDist = 0;
    this.radialVPast = 0;
}

photon.prototype.updateX0 = function(timeStep) {
    quat4.scale(this.V, timeStep, this.displace);

    // Bring it to now.
    quat4.add(this.X0, this.displace);

    this.X0[3] = this.X0[3] - timeStep * this.V[3];
};

photon.prototype.changeFrame = function(translation, rotation) {
    // Translate.
    quat4.subtract(this.X0, translation);

    // Boost both velocity and position vectors using the boost matrix.
    mat4.multiplyVec4(rotation, this.X0);
    mat4.multiplyVec4(rotation, this.V);

    // Renormalize this.V.
    this.V[3] = c;
    vec3.scale(this.V, this.V[3] / Math.sqrt(quat4.spaceDot(this.V, this.V)));

    // Point is now at wrong time. Find displacement to current time.
    quat4.scale(this.V, -this.X0[3] / this.V[3], this.uDisplacement);

    // Bring to current time.
    quat4.add(this.X0, this.uDisplacement);
};

photon.prototype.calcPast = function() {
    var vDotv = quat4.spaceDot(this.V, this.V) / Math.pow(this.V[3] / c, 2);
    var xDotx = quat4.spaceDot(this.X0, this.X0);
    var vDotx = quat4.spaceDot(this.X0, this.V) / this.V[3] * c;
    var a = c*c - vDotv;
    if (xDotx === 0 || vDotv === 0) {
        this.XView = quat4.add(this.X0, [0,0,0,0], this.XView); //Kludge 'cos I can't think of a way to do it faster w/o passing by reference.
        this.radialVPast = 0;
        this.radialDist = Math.sqrt(xDotx);
        this.rPast = Math.sqrt(xDotx);
        thisViewTime = this.rPast / c;
        return;
    }

    this.viewTime = -(vDotx - Math.sqrt(Math.pow(vDotx,2) + a * xDotx) ) / a;

    quat4.scale(this.V, this.viewTime / this.V[3] * c, this.uDisplacement);
    quat4.subtract(this.X0, this.uDisplacement, this.XView);

    this.rPast = Math.sqrt(Math.max(quat4.spaceDot(this.XView, this.XView), 1e-10));
    this.radialVPast = (quat4.spaceDot(this.XView, this.V) /
                        Math.max(this.rPast,1e-10) / this.V[3] * c);
};

photon.prototype.draw = function() {
    this.drawNow();
};

photon.prototype.update = function(timeStep) {
    this.updateX0(timeStep);
    this.calcPast();
};

photon.prototype.drawXT = function() {};

photon.prototype.drawNow = function() {
    scene.g.fillStyle = "#fff";
    scene.g.beginPath();
    scene.g.arc(this.X0[0] / scene.zoom + scene.origin[0],
                this.X0[1] / scene.zoom + scene.origin[1],
                2, 0, twopi);
    scene.g.fill();
};
<commit_msg>Removed calcPast from photon as the concept does not apply. Reversed y coordinate in photon.drawNow @capnrefsmmat does this fix what was strange?<commit_after>/**
 * Create a new photon. Takes an initial position X and a 3-velocity V,
 * which will be rescaled to have a magnitude of c.
 */
function photon(X, V, label, options) {
    this.X0 = X;
    this.rPast = 1;
    this.XView = quat4.create();
    this.V = V;

    // Normalize V such that V[3] = 1 and V[3]^2-V[2]^2-V[1]^2-V[0]^2 = 0
    // (i.e. |V| (including the metric) is 0)
    this.V[3] = 1;
    vec3.scale(this.V, this.V[3] / Math.sqrt(quat4.spaceDot(this.V, this.V)));

    this.displace = quat4.create();

    this.tau = 0;

    this.uDisplacement = quat4.create();
    this.viewTime = 0;
    this.radialDist = 0;
    this.radialVPast = 0;
}

photon.prototype.updateX0 = function(timeStep) {
    quat4.scale(this.V, timeStep, this.displace);

    // Bring it to now.
    quat4.add(this.X0, this.displace);

    this.X0[3] = this.X0[3] - timeStep * this.V[3];
};

photon.prototype.changeFrame = function(translation, rotation) {
    // Translate.
    quat4.subtract(this.X0, translation);

    // Boost both velocity and position vectors using the boost matrix.
    mat4.multiplyVec4(rotation, this.X0);
    mat4.multiplyVec4(rotation, this.V);

    // Renormalize this.V.
    this.V[3] = c;
    vec3.scale(this.V, this.V[3] / Math.sqrt(quat4.spaceDot(this.V, this.V)));

    // Point is now at wrong time. Find displacement to current time.
    quat4.scale(this.V, -this.X0[3] / this.V[3], this.uDisplacement);

    // Bring to current time.
    quat4.add(this.X0, this.uDisplacement);
};

photon.prototype.draw = function() {
    this.drawNow();
};

photon.prototype.update = function(timeStep) {
    this.updateX0(timeStep);
};

photon.prototype.drawXT = function() {};

photon.prototype.drawNow = function() {
    scene.g.fillStyle = "#fff";
    scene.g.beginPath();
    scene.g.arc(this.X0[0] / scene.zoom + scene.origin[0],
                -this.X0[1] / scene.zoom + scene.origin[1],
                2, 0, twopi);
    scene.g.fill();
};
<|endoftext|>


<commit_before>'use strict';

define(['Three', 'Scene', 'FirstPersonControls', 'Camera', 'PointerLock', 'ScriptsManager', 'Editor', 'World', 'KeyVR'], function(THREE, scene, controls, camera, pointerLock, scripts, editor, world, keyVR) {
    var isIntersecting = false;
    var lastIntersected;

    // TODO take this from a serious place (e.g. excluded objects could have a flag in scene.json?)
    var excludedObjects = ['Floor', 'Skybox'];
    var mouse = {};

    var init = function() {
        window.addEventListener('mousedown', onMouseDown, false);
        keyVR.onMouseDown(onMouseDown);

        world.onLoop(animate);
    };

    var isEnabled = function() {
        return pointerLock.enabled();
    };

    var animate = function() {
        if (!isEnabled()) {
            return;
        }

        // FIXME This magic vector was taken from https://github.com/neuman/vreticle
        // It probably represents the position of the reticle.
        var vector = new THREE.Vector3(-0.0012499999999999734, -0.0053859964093356805, 0.5);
        vector.unproject(camera);
        var raycaster = new THREE.Raycaster(controls.getPosition(), vector.sub(controls.getPosition()).normalize());
        var intersects = raycaster.intersectObjects(scene.getScene().children);

        isIntersecting = false;

        // TODO refactor below
        if (intersects.length) {
            var obj = intersects[0].object;

            var isNotExcluded = !excludedObjects.some(function(exc) {
                return exc == obj.name;
            });

            if (isNotExcluded) {
                if (lastIntersected != null && lastIntersected != obj) {
                    onStopIntersect(lastIntersected);
                }

                if (obj != lastIntersected) {
                    onIntersect(obj);
                }

                lastIntersected = obj;
                isIntersecting = true;
            }
        }

        if (!isIntersecting) {
            if (lastIntersected != null) {
                onStopIntersect(lastIntersected);
            }

            lastIntersected = null;
        }
    };

    var onMouseDown = function(event) {
        if (isIntersecting) {
            switch (event.button) {
                case 0:
                    onSelect(lastIntersected);
                    break;
                case 2:
                    editor.rightClick(lastIntersected);
                    break;
            }
        }
    };

    var onIntersect = function(obj) {
        lastIntersected = obj;
        scripts.dispatchEvent(scripts.events.starthover, null, obj.uuid);
    };

    var onStopIntersect = function(obj) {
        scripts.dispatchEvent(scripts.events.endhover, null, obj.uuid);
    };

    var onSelect = function(obj) {
        scripts.dispatchEvent(scripts.events.select, null, obj.uuid);
    };

    world.onInit(init);

    return {
        isIntersecting: function() {
            return isIntersecting;
        }
    };
});
<commit_msg>fixing bug with item selector<commit_after>'use strict';

define(['Three', 'Scene', 'FirstPersonControls', 'Camera', 'PointerLock', 'ScriptsManager', 'Editor', 'World', 'KeyVR'], function(THREE, scene, controls, camera, pointerLock, scripts, editor, world, keyVR) {
    var isIntersecting = false;
    var lastIntersected;

    // TODO take this from a serious place (e.g. excluded objects could have a flag in scene.json?)
    var excludedObjects = ['Floor', 'Skybox'];
    var mouse = {};

    var init = function() {
        window.addEventListener('mousedown', onMouseDown, false);
        keyVR.onMouseDown(onMouseDown);

        world.onLoop(animate);
    };

    var isEnabled = function() {
        return pointerLock.enabled();
    };

    var animate = function() {
        if (!isEnabled()) {
            isIntersecting = false;
            return;
        }

        // FIXME This magic vector was taken from https://github.com/neuman/vreticle
        // It probably represents the position of the reticle.
        var vector = new THREE.Vector3(-0.0012499999999999734, -0.0053859964093356805, 0.5);
        vector.unproject(camera);
        var raycaster = new THREE.Raycaster(controls.getPosition(), vector.sub(controls.getPosition()).normalize());
        var intersects = raycaster.intersectObjects(scene.getScene().children);

        isIntersecting = false;

        // TODO refactor below
        if (intersects.length) {
            var obj = intersects[0].object;

            var isNotExcluded = !excludedObjects.some(function(exc) {
                return exc == obj.name;
            });

            if (isNotExcluded) {
                if (lastIntersected != null && lastIntersected != obj) {
                    onStopIntersect(lastIntersected);
                }

                if (obj != lastIntersected) {
                    onIntersect(obj);
                }

                lastIntersected = obj;
                isIntersecting = true;
            }
        }

        if (!isIntersecting) {
            if (lastIntersected != null) {
                onStopIntersect(lastIntersected);
            }

            lastIntersected = null;
        }
    };

    var onMouseDown = function(event) {
        if (isIntersecting) {
            switch (event.button) {
                case 0:
                    onSelect(lastIntersected);
                    break;
                case 2:
                    editor.rightClick(lastIntersected);
                    break;
            }
        }
    };

    var onIntersect = function(obj) {
        lastIntersected = obj;
        scripts.dispatchEvent(scripts.events.starthover, null, obj.uuid);
    };

    var onStopIntersect = function(obj) {
        scripts.dispatchEvent(scripts.events.endhover, null, obj.uuid);
    };

    var onSelect = function(obj) {
        scripts.dispatchEvent(scripts.events.select, null, obj.uuid);
    };

    world.onInit(init);

    return {
        isIntersecting: function() {
            return isIntersecting;
        }
    };
});
<|endoftext|>


<commit_before>import DS from 'ember-data';

export default DS.Model.extend({

  HYTTETYPE_CHOICES: [
    'DNT-hytte',
    'Privat hytte',
    'Privat rabatthytte'
  ],

  BETJENINGSGRAD_CHOICES: [
    'Betjent',
    'Servering',
    'Selvbetjent',
    'Ubetjent',
    'Dagshytte',
    'Nødbu',
    'Utleie',
    'Stengt',
    'Nedlagt'
  ],

  bilder: DS.hasMany('photo', {async: true}),
  beskrivelse: DS.attr('string'),
  betjeningsgrad: DS.attr('string'),
  byggeår: DS.attr('number'),
  description: DS.attr('string'),
  // checksum: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  // endret: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  fasiliteter: DS.attr('object'), // object[]
  fylke: DS.attr('string'),
  geojson: DS.attr('object'),
  grupper: DS.attr('array'),
  hyttetype: DS.attr('string'),
  kart: DS.attr('string'),
  kommune: DS.attr('string'),
  kontaktinfo: DS.attr('array', {defaultValue: [{'tittel': 'I sesong'}, {'tittel': 'Utenom sesong'}]}),
  lenker: DS.attr('array'), // object[]
  // lisens: DS.attr('string', {defaultValue: 'CC BY-NC 4.0'}),
  navn: DS.attr('string'),
  navn_alt: DS.attr('array'),
  navngiving: DS.attr('string'), // TODO: Should be computed by either Hytteadmin API endpoint or Hytteadmin Client
  områder: DS.hasMany('area', {async: true}),
  privat: DS.attr('object'),
  juridisk_eier: DS.belongsTo('group', {async: true}),
  vedlikeholdes_av: DS.belongsTo('group', {async: true}),
  ssr_id: DS.attr('number'),
  status: DS.attr('string', {defaultValue: 'Kladd'}),
  url: DS.attr('string'),
  tilkomst: DS.attr('object', {defaultValue:
    {'privat': {'sommer': undefined, 'vinter': undefined}, 'kollektiv': {'sommer': undefined, 'vinter': undefined}}
  }),
  tags: DS.attr('array', {defaultValue: ['Hytte']}),
  // tilbyder: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  tilrettelagt_for: DS.attr('array'),
  turkart: DS.attr('array'),

  enable_kun_bestilling_kommentar: function () {
    var kun_bestilling = this.get('privat.kun_bestilling');
    return (kun_bestilling === 'Ja' || kun_bestilling === 'Delvis');
  }.property('privat.kun_bestilling'),

  latitude: function (key, value, previousValue) {
    // Setter
    if (arguments.length > 1) {
      this.set('geojson.coordinates.1', parseFloat(value, 10));
    }

    // Getter
    return this.get('geojson.coordinates.1');

  }.property('geojson.coordinates.1'),

  longitude: function (key, value, previousValue) {
    // Setter
    if (arguments.length > 1) {
      this.set('geojson.coordinates.0', parseFloat(value, 10));
    }

    // Getter
    return this.get('geojson.coordinates.0');

  }.property('geojson.coordinates.0')

});
<commit_msg>Update vedlikeholdes_av and juridisk_eier relation objects when their properties in privat changes, to make all the updated group properties accessible<commit_after>import Ember from 'ember';
import DS from 'ember-data';

export default DS.Model.extend({

  HYTTETYPE_CHOICES: [
    'DNT-hytte',
    'Privat hytte',
    'Privat rabatthytte'
  ],

  BETJENINGSGRAD_CHOICES: [
    'Betjent',
    'Servering',
    'Selvbetjent',
    'Ubetjent',
    'Dagshytte',
    'Nødbu',
    'Utleie',
    'Stengt',
    'Nedlagt'
  ],

  bilder: DS.hasMany('photo', {async: true}),
  beskrivelse: DS.attr('string'),
  betjeningsgrad: DS.attr('string'),
  byggeår: DS.attr('number'),
  description: DS.attr('string'),
  // checksum: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  // endret: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  fasiliteter: DS.attr('object'), // object[]
  fylke: DS.attr('string'),
  geojson: DS.attr('object'),
  grupper: DS.attr('array'),
  hyttetype: DS.attr('string'),
  kart: DS.attr('string'),
  kommune: DS.attr('string'),
  kontaktinfo: DS.attr('array', {defaultValue: [{'tittel': 'I sesong'}, {'tittel': 'Utenom sesong'}]}),
  lenker: DS.attr('array'), // object[]
  // lisens: DS.attr('string', {defaultValue: 'CC BY-NC 4.0'}),
  navn: DS.attr('string'),
  navn_alt: DS.attr('array'),
  navngiving: DS.attr('string'), // TODO: Should be computed by either Hytteadmin API endpoint or Hytteadmin Client
  områder: DS.hasMany('area', {async: true}),
  privat: DS.attr('object'),
  juridisk_eier: DS.belongsTo('group', {async: true}),
  vedlikeholdes_av: DS.belongsTo('group', {async: true}),
  ssr_id: DS.attr('number'),
  status: DS.attr('string', {defaultValue: 'Kladd'}),
  url: DS.attr('string'),
  tilkomst: DS.attr('object', {defaultValue: {
    'privat': {'sommer': undefined, 'vinter': undefined},
    'kollektiv': {'sommer': undefined, 'vinter': undefined}
  }}),
  tags: DS.attr('array', {defaultValue: ['Hytte']}),
  // tilbyder: DS.attr('string'), // TODO: Add support for readonly as this is set by NTB
  tilrettelagt_for: DS.attr('array'),
  turkart: DS.attr('array'),

  updateVedlikeholdesAv: function () {
    var vedlikeholdesAvId = this.get('privat.vedlikeholdes_av');
    if (vedlikeholdesAvId) {
      this.store.find('group', vedlikeholdesAvId).then(Ember.run.bind(this, function (group) {
        this.set('vedlikeholdes_av', group);
      }));
    }

  }.observes('privat.vedlikeholdes_av'),

  updateJuridiskEier: function () {
    var updateJuridiskEierId = this.get('privat.juridisk_eier');
    if (updateJuridiskEierId) {
      this.store.find('group', updateJuridiskEierId).then(Ember.run.bind(this, function (group) {
        this.set('juridisk_eier', group);
      }));
    }

  }.observes('privat.juridisk_eier'),

  enable_kun_bestilling_kommentar: function () {
    var kun_bestilling = this.get('privat.kun_bestilling');
    return (kun_bestilling === 'Ja' || kun_bestilling === 'Delvis');
  }.property('privat.kun_bestilling'),

  latitude: function (key, value, previousValue) {
    // Setter
    if (arguments.length > 1) {
      this.set('geojson.coordinates.1', parseFloat(value, 10));
    }

    // Getter
    return this.get('geojson.coordinates.1');

  }.property('geojson.coordinates.1'),

  longitude: function (key, value, previousValue) {
    // Setter
    if (arguments.length > 1) {
      this.set('geojson.coordinates.0', parseFloat(value, 10));
    }

    // Getter
    return this.get('geojson.coordinates.0');

  }.property('geojson.coordinates.0')

});
<|endoftext|>


<commit_before>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */

// loaded already
define('jquery', [], function() {
    'use strict';
    return window.jQuery;
});

// loaded already
define('angular', [], function() {
    'use strict';
    return window.angular;
});

define('main', [
    'gettext',
    'angular',
    'superdesk/superdesk',
    'lodash',
    'moment'
], function(gettext, angular, superdesk, _, moment) {
    'use strict';

    return function bootstrap(config, apps) {

        apps.unshift(superdesk.name);
        superdesk.constant('config', config);
        superdesk.constant('lodash', _);
        superdesk.constant('moment', moment);
        // liveblog list must be the default page
        superdesk.config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/', {redirectTo: '/liveblog'});
        }]);
        superdesk.config(['$provide', function($provide) {
            $provide.decorator('sdItemGlobalsearchDirective', ['$delegate', function($delegate) {
                //remove from Liveblog the SD directive that is doing the ctrl+0 binding
                $delegate.shift();
                return $delegate;
            }]);
        }]);
        // load apps & bootstrap
        var body = angular.element('body');
        body.ready(function() {
            angular.bootstrap(body, apps, {strictDi: true});
            window.superdeskIsReady = true;
        });
    };
});
<commit_msg>It is getting a bit late :)<commit_after>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */

// loaded already
define('jquery', [], function() {
    'use strict';
    return window.jQuery;
});

// loaded already
define('angular', [], function() {
    'use strict';
    return window.angular;
});

define('main', [
    'gettext',
    'angular',
    'superdesk/superdesk',
    'lodash',
    'moment'
], function(gettext, angular, superdesk, _, moment) {
    'use strict';

    return function bootstrap(config, apps) {

        apps.unshift(superdesk.name);
        superdesk.constant('config', config);
        superdesk.constant('lodash', _);
        superdesk.constant('moment', moment);
        // liveblog list must be the default page
        superdesk.config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/', {redirectTo: '/liveblog'});
        }]);
        superdesk.config(['$provide', function($provide) {
            $provide.decorator('sdItemGlobalsearchDirective', ['$delegate', function($delegate) {
                //remove from Liveblog the SD directive that is doing the ctrl+0 binding
                $delegate.shift();
                return $delegate;
            }]);
        }]);
        // load apps & bootstrap
        var body = angular.element('body');
        body.ready(function() {
            angular.bootstrap(body, apps, {strictDi: true});
            window.superdeskIsReady = true;
        });
    };
});
<|endoftext|>


<commit_before>var readJson = require('./readJson')
var Promise = require("bluebird")
var _ = require('lodash')

// get info.json
// for each list in file['info'],
	// check ['hash'] against the db's hash
		// if it matches, return.
		// else, request the file from ['path'],
			// delete the pervious data.
			// and store the new data in the database

function storeItem(item) {
	if (item.type === 'courses') {
		_.map(item.data.courses, function(course) {
			course.sourcePath = item.meta.path
		})
		window.server.courses
			.add.apply(window.server, item.data.courses)
			.done(function() {
				console.log(_.size(item.data.courses) + ' courses have been added')
			})
	}

	else if (item.type === 'areas') {
		item.data.info.sourcePath = item.meta.path
		window.server.areas
			.add(item.data.info)
			.done(function(results) {
				console.log('an area has been added')
		})
	}
}

function deleteItems(type, path, key) {
	console.log('deleting ' + type + ' from ' + path)

	var itemsToDelete = window.server[type]
		.query('sourcePath')
		.only(path)
		.execute()
		.done()

	itemsToDelete.then(function(items) {
		var keysToDelete = _.pluck(items, key)
		var numberToDelete = _.size(keysToDelete)
		if (numberToDelete) {
			_.each(keysToDelete, function(key) {
				window.server[type]
					.remove(key)
					.done()
			})
		}
		console.log(numberToDelete + ' ' + type + ' have been removed')
	})

	return new Promise(function(resolve, reject) {
		itemsToDelete.then(resolve)
	})
}

function cleanPriorData(item) {
	var path = item.meta.path
	var hash = item.meta.hash

	// get rid of old items
	var deleteItemsPromise;
	if (item.type === 'areas') {
		deleteItemsPromise = deleteItems('areas', path, 'sourcePath')
	} else if (item.type === 'courses') {
		deleteItemsPromise = deleteItems('courses', path, 'clbid')
	} else {
		deleteItemsPromise = Promise.reject(new Error('Unknown item type' + item.type))
	}

	deleteItemsPromise.then(function() {
		localStorage.removeItem(path)
		localStorage.setItem(path, hash)
	})

	return deleteItemsPromise
}

function updateDatabase(itemType, infoFromServer) {
	infoFromServer.path = '/data/' + itemType + '/' + infoFromServer.path
	var oldHash = localStorage.getItem(infoFromServer.path)
	var newHash = infoFromServer.hash
	var itemPath = infoFromServer.path

	return new Promise(function(resolve, reject) {
		if (newHash !== oldHash) {
			console.log('have to add', itemPath)
			readJson(itemPath)
				.then(function(data) {
					console.log('read', itemPath)
					var item = {
						data: data,
						meta: infoFromServer,
						type: itemType
					}
					cleanPriorData(item).then(function() {
						storeItem(item)
					})
				})
				.catch(function(err) {
					reject(err.stack)
				})
				.done(function() {
					resolve('had to add ' + itemPath)
				})
		} else {
			resolve('bypassed adding ' + itemPath)
		}
	})
}

function loadDataFiles(info) {
	console.log('load data files', info)
	return Promise.all(_.map(info.info, function(files) {
		return Promise.all(_.map(files, function(file) {
			return updateDatabase(info.type, file)
		}))
	}))
}

function loadInfoFile(url) {
	console.log('loading', url)
	readJson(url)
		.then(loadDataFiles)
		.done()
}

function loadData() {
	var infoFiles = [
		'/data/areas/info.json',
		'/data/courses/info.json',
	]
	return Promise.all(_.map(infoFiles, loadInfoFile))
}

module.exports = loadData
<commit_msg>resolve only logs the message if you log it<commit_after>var readJson = require('./readJson')
var Promise = require("bluebird")
var _ = require('lodash')

// get info.json
// for each list in file['info'],
	// check ['hash'] against the db's hash
		// if it matches, return.
		// else, request the file from ['path'],
			// delete the pervious data.
			// and store the new data in the database

function storeItem(item) {
	if (item.type === 'courses') {
		_.map(item.data.courses, function(course) {
			course.sourcePath = item.meta.path
		})
		window.server.courses
			.add.apply(window.server, item.data.courses)
			.done(function() {
				console.log(_.size(item.data.courses) + ' courses have been added')
			})
	}

	else if (item.type === 'areas') {
		item.data.info.sourcePath = item.meta.path
		window.server.areas
			.add(item.data.info)
			.done(function(results) {
				console.log('an area has been added')
		})
	}
}

function deleteItems(type, path, key) {
	console.log('deleting ' + type + ' from ' + path)

	var itemsToDelete = window.server[type]
		.query('sourcePath')
		.only(path)
		.execute()
		.done()

	itemsToDelete.then(function(items) {
		var keysToDelete = _.pluck(items, key)
		var numberToDelete = _.size(keysToDelete)
		if (numberToDelete) {
			_.each(keysToDelete, function(key) {
				window.server[type]
					.remove(key)
					.done()
			})
		}
		console.log(numberToDelete + ' ' + type + ' have been removed')
	})

	return new Promise(function(resolve, reject) {
		itemsToDelete.then(resolve)
	})
}

function cleanPriorData(item) {
	var path = item.meta.path
	var hash = item.meta.hash

	// get rid of old items
	var deleteItemsPromise;
	if (item.type === 'areas') {
		deleteItemsPromise = deleteItems('areas', path, 'sourcePath')
	} else if (item.type === 'courses') {
		deleteItemsPromise = deleteItems('courses', path, 'clbid')
	} else {
		deleteItemsPromise = Promise.reject(new Error('Unknown item type' + item.type))
	}

	deleteItemsPromise.then(function() {
		localStorage.removeItem(path)
		localStorage.setItem(path, hash)
	})

	return deleteItemsPromise
}

function updateDatabase(itemType, infoFromServer) {
	infoFromServer.path = '/data/' + itemType + '/' + infoFromServer.path
	var oldHash = localStorage.getItem(infoFromServer.path)
	var newHash = infoFromServer.hash
	var itemPath = infoFromServer.path

	return new Promise(function(resolve, reject) {
		if (newHash !== oldHash) {
			console.log('have to add', itemPath)
			readJson(itemPath)
				.then(function(data) {
					console.log('read', itemPath)
					var item = {
						data: data,
						meta: infoFromServer,
						type: itemType
					}
					cleanPriorData(item).then(function() {
						storeItem(item)
					})
				})
				.catch(function(err) {
					reject(err.stack)
				})
				.done(function() {
					console.log('had to add ' + itemPath)
					resolve()
				})
		} else {
			console.log('bypassed adding ' + itemPath)
			resolve()
		}
	})
}

function loadDataFiles(info) {
	console.log('load data files', info)
	return Promise.all(_.map(info.info, function(files) {
		return Promise.all(_.map(files, function(file) {
			return updateDatabase(info.type, file)
		}))
	}))
}

function loadInfoFile(url) {
	console.log('loading', url)
	readJson(url)
		.then(loadDataFiles)
		.done()
}

function loadData() {
	var infoFiles = [
		'/data/areas/info.json',
		'/data/courses/info.json',
	]
	return Promise.all(_.map(infoFiles, loadInfoFile))
}

module.exports = loadData
<|endoftext|>


<commit_before>import React from 'react';
import Path from 'path';

import { Files } from '../model/';
import { BreadCrumb, Bundle, NgIf, Loader, Container, EventReceiver, EventEmitter } from '../components/';
import { debounce, opener, screenHeight, notify } from '../helpers/';
import { AudioPlayer, FileDownloader, ImageViewer, PDFViewer } from './viewerpage/';

const VideoPlayer = (props) => (
    <Bundle loader={import(/* webpackChunkName: "video" */"../pages/viewerpage/videoplayer")} symbol="VideoPlayer">
      {(Comp) => <Comp {...props}/>}
    </Bundle>
);
const IDE = (props) => (
    <Bundle loader={import(/* webpackChunkName: "ide" */"../pages/viewerpage/ide")} symbol="IDE">
      {(Comp) => <Comp {...props}/>}
    </Bundle>
);

@EventReceiver
export class ViewerPage extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            path: props.match.url.replace('/view', ''),
            url: null,
            filename: Path.basename(props.match.url.replace('/view', '')) || 'untitled.dat',
            opener: null,
            content: null,
            needSaving: false,
            isSaving: false,
            loading: true,
            height: 0
        };
        this.props.subscribe('file.select', this.onPathUpdate.bind(this));
        this.resetHeight = debounce(this.resetHeight.bind(this), 100);
    }

    componentWillMount(){
        const metadata = () => {
            return new Promise((done, err) => {
                let app_opener = opener(this.state.path);
                Files.url(this.state.path).then((url) => {
                    this.setState({
                        url: url,
                        opener: app_opener
                    }, () => done(app_opener));
                }).catch(err => {
                    notify.send(err, 'error');
                    err(err);
                });
            });
        };
        const data_fetch = (app) => {
            if(app === 'editor'){
                Files.cat(this.state.path).then((content) => {
                    this.setState({content: content || "", loading: false});
                }).catch(err => {
                    if(err && err.code === 'CANCELLED'){ return; }
                    if(err.code === 'BINARY_FILE'){
                        this.setState({opener: 'download', loading: false});
                    }else{
                        notify.send(err, 'error');
                    }
                });
            }else{
                this.setState({loading: false});
            }
        };
        return metadata()
            .then(data_fetch);
    }

    componentWillUnmount() {
        this.props.unsubscribe('file.select');
        window.removeEventListener("resize", this.resetHeight);
    }

    componentDidMount(){
        this.resetHeight();
        window.addEventListener("resize", this.resetHeight);
    }

    save(file){
        this.setState({isSaving: true});
        return Files.save(this.state.path, file)
            .then(() => {
                this.setState({isSaving: false, needSaving: false});
                return Promise.resolve();
            })
            .catch((err) => {
                if(err && err.code === 'CANCELLED'){ return; }
                this.setState({isSaving: false});
                notify.send(err, 'error');
                return Promise.reject();
            });
    }

    onPathUpdate(path){
        this.props.history.push('/files'+path);
    }

    needSaving(bool){
        this.setState({needSaving: bool});
    }

    resetHeight(){
        this.setState({
            height: screenHeight()
        });
    }

    render() {
        let style = {height: '100%'};
        return (

              <BreadCrumb needSaving={this.state.needSaving} className="breadcrumb" path={this.state.path} />

                <NgIf cond={this.state.loading === false} style={style}>
                  <NgIf cond={this.state.opener === 'editor'} style={style}>
                    <IDE needSavingUpdate={this.needSaving.bind(this)}
                         needSaving={this.state.needSaving}
                         isSaving={this.state.isSaving}
                         onSave={this.save.bind(this)}
                         content={this.state.content}
                         url={this.state.url}
                         filename={this.state.filename}/>
                  </NgIf>
                  <NgIf cond={this.state.opener === 'image'} style={style}>
                    <ImageViewer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'pdf'} style={style}>
                    <PDFViewer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'video'} style={style}>
                    <VideoPlayer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'audio'} style={style}>
                    <AudioPlayer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'download'} style={style}>
                    <FileDownloader data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                </NgIf>
                <NgIf cond={this.state.loading === true}>
                  <Loader/>
                </NgIf>

        );
    }
}
<commit_msg>fix (#36): edge case<commit_after>import React from 'react';
import Path from 'path';

import { Files } from '../model/';
import { BreadCrumb, Bundle, NgIf, Loader, Container, EventReceiver, EventEmitter } from '../components/';
import { debounce, opener, screenHeight, notify } from '../helpers/';
import { AudioPlayer, FileDownloader, ImageViewer, PDFViewer } from './viewerpage/';

const VideoPlayer = (props) => (
    <Bundle loader={import(/* webpackChunkName: "video" */"../pages/viewerpage/videoplayer")} symbol="VideoPlayer">
      {(Comp) => <Comp {...props}/>}
    </Bundle>
);
const IDE = (props) => (
    <Bundle loader={import(/* webpackChunkName: "ide" */"../pages/viewerpage/ide")} symbol="IDE">
      {(Comp) => <Comp {...props}/>}
    </Bundle>
);

@EventReceiver
export class ViewerPage extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            path: props.match.url.replace('/view', ''),
            url: null,
            filename: Path.basename(props.match.url.replace('/view', '')) || 'untitled.dat',
            opener: null,
            content: null,
            needSaving: false,
            isSaving: false,
            loading: true,
            height: 0
        };
        this.props.subscribe('file.select', this.onPathUpdate.bind(this));
        this.resetHeight = debounce(this.resetHeight.bind(this), 100);
    }

    componentWillMount(){
        const metadata = () => {
            return new Promise((done, err) => {
                let app_opener = opener(this.state.path);
                Files.url(this.state.path).then((url) => {
                    this.setState({
                        url: url,
                        opener: app_opener
                    }, () => done(app_opener));
                }).catch(err => {
                    notify.send(err, 'error');
                    err(err);
                });
            });
        };
        const data_fetch = (app) => {
            if(app === 'editor'){
                Files.cat(this.state.path).then((content) => {
                    this.setState({content: content || "", loading: false});
                }).catch(err => {
                    if(err && err.code === 'CANCELLED'){ return; }
                    if(err.code === 'BINARY_FILE'){
                        this.setState({opener: 'download', loading: false});
                    }else{
                        notify.send(err, 'error');
                    }
                });
            }else{
                this.setState({loading: false});
            }
        };
        return metadata()
            .then(data_fetch);
    }

    componentWillUnmount() {
        this.props.unsubscribe('file.select');
        window.removeEventListener("resize", this.resetHeight);
    }

    componentDidMount(){
        this.resetHeight();
        window.addEventListener("resize", this.resetHeight);
    }

    save(file){
        this.setState({isSaving: true});
        return Files.save(this.state.path, file)
            .then(() => {
                this.setState({isSaving: false, needSaving: false});
                return Promise.resolve();
            })
            .then(() => {
                return new Promise((done, err) => {
                    const reader = new FileReader();
                    reader.onload = () => {
                        this.setState({content: reader.result});
                        done();
                    };
                    reader.onerror = (e) => {
                        err({message: 'Internal error 500'});
                    };
                    reader.readAsText(file);
                });
            })
            .catch((err) => {
                if(err && err.code === 'CANCELLED'){ return; }
                this.setState({isSaving: false});
                notify.send(err, 'error');
                return Promise.reject();
            });
    }

    onPathUpdate(path){
        this.props.history.push('/files'+path);
    }

    needSaving(bool){
        this.setState({needSaving: bool});
    }

    resetHeight(){
        this.setState({
            height: screenHeight()
        });
    }

    render() {
        let style = {height: '100%'};
        return (

              <BreadCrumb needSaving={this.state.needSaving} className="breadcrumb" path={this.state.path} />

                <NgIf cond={this.state.loading === false} style={style}>
                  <NgIf cond={this.state.opener === 'editor'} style={style}>
                    <IDE needSavingUpdate={this.needSaving.bind(this)}
                         needSaving={this.state.needSaving}
                         isSaving={this.state.isSaving}
                         onSave={this.save.bind(this)}
                         content={this.state.content}
                         url={this.state.url}
                         filename={this.state.filename}/>
                  </NgIf>
                  <NgIf cond={this.state.opener === 'image'} style={style}>
                    <ImageViewer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'pdf'} style={style}>
                    <PDFViewer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'video'} style={style}>
                    <VideoPlayer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'audio'} style={style}>
                    <AudioPlayer data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                  <NgIf cond={this.state.opener === 'download'} style={style}>
                    <FileDownloader data={this.state.url} filename={this.state.filename} />
                  </NgIf>
                </NgIf>
                <NgIf cond={this.state.loading === true}>
                  <Loader/>
                </NgIf>

        );
    }
}
<|endoftext|>


<commit_before>window.CodeArea = (function() {
    "use strict";

    // static variables should go here
    var codeAreaId = 0;

    function CodeArea(place,options) {

	codeAreaId++;
	this.filemanager = null;
	this.tabsId = "CATab-"+codeAreaId;
	this.tabCounter = 0;         // used to track the tabs ids
	this.tabs = null;            // the jquery tabs widget
	this.tabsHolder = place;     // the DOM element where the tabs are placed
	this.tabsOptions = options;  // the list of options passed to the constructor
	this.tabInfoByPos = new Array();
	this.tabInfoById  = new Array();
	this.currTabId = null;

	this.setOptions();
	this.initTabs();

	// close icon: removing the tab on click
	var self = this;
	this.tabs.delegate( "span.ui-icon-close", "click",
			    function() {
				var panelId = $( this ).closest( "li" ).attr( "aria-controls" );
				self.hideTab( self.tabTag_to_tabId(panelId) );
			    });

	this.tabs.delegate( "span.ui-icon-extlink", "click",
			    function() {
				var panelId = $( this ).closest( "li" ).attr( "aria-controls" );
				self.expandTab( self.tabTag_to_tabId(panelId) );
			    });
    };

    CodeArea.prototype = {
	constructor: CodeArea,

	// id -> tabs-id
	tabId_to_tabTag:
	function( id ) {
	    return "tabs-"+id;
	},

	// tabs-id -> id
	tabTag_to_tabId:
	function( tabTag ) {
	    return tabTag.substr(5,tabTag.length-5);
	},

	//
	addFileManager:
	function(FM){
	  this.filemanager = FM;
	},
	//
	setOptions:
	function() {
	},

	//
	initTabs:
	function() {
	    var self = this;
	    this.tabs = $(this.tabsHolder).append("

").find("#"+this.tabsId);
	    this.tabs.tabs({
		activate: function( event, ui ) {
		    var tabTag = ui.newTab.attr( "aria-controls" );
		    self.switchTab( self.tabTag_to_tabId(tabTag) );
		}
	    });

	},

	//
	switchTab:
	function(id) {
	    var tabInfo = this.tabInfoById[id];
	    this.tabs.tabs( "option", "active", tabInfo.pos );

	    tabInfo.editor.refresh();

	    // this is done in a timeout environment because some other
	    // object might take the focus after exiting this method
	    setTimeout(function() { tabInfo.editor.focus(); }, 0);

	    this.currTabId = id;
	},

	//
	createTab:
	function(label,id,tabContent) {

	    var tabTag = this.tabId_to_tabTag(id);

	    // TBD --- later verify that there is no other Tab with the
	    // same id

	    // create the panel
	    var panel = $("
"+label+
			  "
");
	    this.tabs.find( ".ui-tabs-nav" ).append( panel );

	    // create the tab content
        var content = $("

");
        this.tabs.append( content );

	    // var content = $("

");
	    // content.append("

");
	    // this.tabs.append( content );
	    // create a CodeMirror for this tab
	    var ed = CodeMirror( content.find("#"+tabTag+"-ed").get(0), {
 	        lineNumbers: true,
 		mode: "text/abs",//x-java",
 		value: tabContent,
		gutters: ["actionGutter","CodeMirror-linenumbers","infoGutter"],
		highlightSelectionMatches: {showToken: /\w/}
 	    });

	    var currTabInfo = {
	        id: id,
		pos: this.tabCounter,
	        label: label,
	        editor: ed,
	        edArea: this.tabs.find("#"+tabTag+"-ed")[0],
	        visible: true,
		panel: panel,
		content: content
	    };

	    this.tabInfoByPos[currTabInfo.pos] = currTabInfo;
	    this.tabInfoById[id] = currTabInfo;
	    this.tabCounter++;
	    this.tabs.tabs( "refresh" );
	    this.switchTab(id);
	},

	//
	hideTab:
        function(id) {

	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    // TBD -- check if the tab is not hidden already

	    // if we are hiding the current tab, then switch to the next
	    // or previous one first
	    if ( this.tabs.tabs( "option", "active" ) == tabInfo.pos ) {
		if ( this.tabInfoByPos[tabInfo.pos+1] )
		    this.switchTab( this.tabInfoByPos[tabInfo.pos+1].id );
		else if ( this.tabInfoByPos[tabInfo.pos-1] )
		    this.switchTab( this.tabInfoByPos[tabInfo.pos-1].id );
	    }

	    tabInfo.visible = false;

	    tabInfo.panel.detach()
	    tabInfo.content.detach()

	    this.tabs.tabs( "refresh" );

	    this.tabInfoByPos.splice(tabInfo.pos,1);

	    for(var i=tabInfo.pos; i<this.tabInfoByPos.length; i++)
		this.tabInfoByPos[i].pos--;

	    this.tabCounter--;
	    if ( this.tabCounter == 0 ) this.currTabId = null;
	},
	updateContent:
	function(id,content) {
	  var tabInfo = this.tabInfoById[id];
	  tabInfo.content = content;
	  tabInfo.editor.setValue(content);
	  this.tabInfoByPos[tabInfo.pos] = tabInfo;
	},
	updateTitle:
	function(id,title) {
	  var tabInfo = this.tabInfoById[id];
	  var tabTag = this.tabId_to_tabTag(id);
	  tabInfo.label = title;
	  $("li#tablabel-"+tabTag+"> a ").html(title);
	  this.tabInfoByPos[tabInfo.pos] = tabInfo;
	},
	//
	showTab:
        function(id) {
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];
	    if ( tabInfo.visible ) {
		this.switchTab(id);    // just switch when the tab is visible
	    } else {

		this.tabs.find( ".ui-tabs-nav" ).append( tabInfo.panel  );
		this.tabs.append( tabInfo.content );

		tabInfo.panel.show();
		tabInfo.content.show();

		tabInfo.visible = true;
		tabInfo.pos = this.tabCounter;
		this.tabInfoByPos[tabInfo.pos] = tabInfo;
		this.tabCounter++;
		this.tabs.tabs( "refresh" );

		this.switchTab(id);
	    }
	},

	//
	expandTab:
	function(id) {
	    var self = this;
	    this.hideTab(id);
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    $("

").append($(tabInfo.content))
		.dialog({
		    title: tabInfo.label,
		    height: $(document).height()*0.8,
		    maxHeight: $(document).height()*0.8,
		    beforeClose: function( event, ui ) {
		      //tabInfo.content.find(".CodeMirror").removeClass("ei-codearea-content-expanded");
		      tabInfo.content.removeClass("ei-codearea-content-expanded");
		      self.showTab(id);
		    }
		});
	    //tabInfo.content.find(".CodeMirror").addClass("ei-codearea-content-expanded");
	    tabInfo.content.addClass("ei-codearea-content-expanded");

	    tabInfo.content.show();
	},

	     //
	getTabContent:
	function(id) {
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    return tabInfo.editor.getValue();
	},

	//
	highlightLines:
        function(id, hInfo ) {

	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "highlightLines: invalid file name";
	    }

	    var tabInfo = this.tabInfoById[id];

	    return new HighlightLinesWidget({
		lines: hInfo.lines,
		color: hInfo.color,
		outclass: hInfo.outclass,
		editor: tabInfo.editor
	    });
	},

	//
	marker:
	function(id, markerInfo) {
	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "marker: invalid file name";
	    }

	    // open the file, i.e., make the tab available if it is closed
	    this.filemanager.openFile(id);

	    // get the tab information
	    var tabInfo = this.tabInfoById[id];

	    var markerWidgetInfo = {
		lines    : markerInfo.lines,
		content  : markerInfo.content,
		outclass : markerInfo.outclass,
		onclick  : markerInfo.onclick,
		gutter   : markerInfo.gutter,
		editor   : tabInfo.editor
	    };

	    return new MarkerWidget( markerWidgetInfo );
	},

	//
	linewidget:
	function(id, widgetInfo) {
	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "linewidget: invalid file name";
	    }

	    var tabInfo = this.tabInfoById[id];

	    return new InlinedMarkerWidget({
		lines: widgetInfo.lines,
		content: widgetInfo.content,
		outclass: widgetInfo.outclass,
		editor: tabInfo.editor
	    });
	},

	//
	getCurrentTabId:
	function() {
	    return this.currTabId;
	}

    };

    return CodeArea;

})();

<commit_msg>codearea fixed, I believe.<commit_after>window.CodeArea = (function() {
    "use strict";

    // static variables should go here
    var codeAreaId = 0;

    function CodeArea(place,options) {

	codeAreaId++;
	this.filemanager = null;
	this.tabsId = "CATab-"+codeAreaId;
	this.tabCounter = 0;         // used to track the tabs ids
	this.tabs = null;            // the jquery tabs widget
	this.tabsHolder = place;     // the DOM element where the tabs are placed
	this.tabsOptions = options;  // the list of options passed to the constructor
	this.tabInfoByPos = new Array();
	this.tabInfoById  = new Array();
	this.currTabId = null;

	this.setOptions();
	this.initTabs();

	// close icon: removing the tab on click
	var self = this;
	this.tabs.delegate( "span.ui-icon-close", "click",
			    function() {
				var panelId = $( this ).closest( "li" ).attr( "aria-controls" );
				self.hideTab( self.tabTag_to_tabId(panelId) );
			    });

	this.tabs.delegate( "span.ui-icon-extlink", "click",
			    function() {
				var panelId = $( this ).closest( "li" ).attr( "aria-controls" );
				self.expandTab( self.tabTag_to_tabId(panelId) );
			    });
    };

    CodeArea.prototype = {
	constructor: CodeArea,

	// id -> tabs-id
	tabId_to_tabTag:
	function( id ) {
	    return "tabs-"+id;
	},

	// tabs-id -> id
	tabTag_to_tabId:
	function( tabTag ) {
	    return tabTag.substr(5,tabTag.length-5);
	},

	//
	addFileManager:
	function(FM){
	  this.filemanager = FM;
	},
	//
	setOptions:
	function() {
	},

	//
	initTabs:
	function() {
	    var self = this;
	    this.tabs = $(this.tabsHolder).append("

").find("#"+this.tabsId);
	    this.tabs.tabs({
		activate: function( event, ui ) {
		    var tabTag = ui.newTab.attr( "aria-controls" );
		    self.switchTab( self.tabTag_to_tabId(tabTag) );
		}
	    });

	},

	//
	switchTab:
	function(id) {
	    var tabInfo = this.tabInfoById[id];
	    this.tabs.tabs( "option", "active", tabInfo.pos );

	    tabInfo.editor.refresh();

	    // this is done in a timeout environment because some other
	    // object might take the focus after exiting this method
	    setTimeout(function() { tabInfo.editor.focus(); }, 0);

	    this.currTabId = id;
	},

	//
	createTab:
	function(label,id,tabContent) {

	    var tabTag = this.tabId_to_tabTag(id);

	    // TBD --- later verify that there is no other Tab with the
	    // same id

	    // create the panel
	    var panel = $("
"+label+
			  "
");
	    this.tabs.find( ".ui-tabs-nav" ).append( panel );

	    // create the tab content
        var content = $("
<textarea id='"+tabTag+"-ed'></textarea>
");
        this.tabs.append( content );

	    // var content = $("

");
	    // content.append("

");
	    // this.tabs.append( content );
	    // create a CodeMirror for this tab
	    var ed = CodeMirror.fromTextArea( content.find("#"+tabTag+"-ed").get(0), {
 	        lineNumbers: true,
 		mode: "text/abs",//x-java",
 		value: tabContent,
		gutters: ["actionGutter","CodeMirror-linenumbers","infoGutter"],
		scrollbarStyle: "overlay",
		highlightSelectionMatches: {showToken: /\w/}
 	    });

	    var currTabInfo = {
	        id: id,
		pos: this.tabCounter,
	        label: label,
	        editor: ed,
	        edArea: this.tabs.find("#"+tabTag+"-ed")[0],
	        visible: true,
		panel: panel,
		content: content
	    };

	    this.tabInfoByPos[currTabInfo.pos] = currTabInfo;
	    this.tabInfoById[id] = currTabInfo;
	    this.tabCounter++;
	    this.tabs.tabs( "refresh" );
	    this.switchTab(id);
	},

	//
	hideTab:
        function(id) {

	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    // TBD -- check if the tab is not hidden already

	    // if we are hiding the current tab, then switch to the next
	    // or previous one first
	    if ( this.tabs.tabs( "option", "active" ) == tabInfo.pos ) {
		if ( this.tabInfoByPos[tabInfo.pos+1] )
		    this.switchTab( this.tabInfoByPos[tabInfo.pos+1].id );
		else if ( this.tabInfoByPos[tabInfo.pos-1] )
		    this.switchTab( this.tabInfoByPos[tabInfo.pos-1].id );
	    }

	    tabInfo.visible = false;

	    tabInfo.panel.detach()
	    tabInfo.content.detach()

	    this.tabs.tabs( "refresh" );

	    this.tabInfoByPos.splice(tabInfo.pos,1);

	    for(var i=tabInfo.pos; i<this.tabInfoByPos.length; i++)
		this.tabInfoByPos[i].pos--;

	    this.tabCounter--;
	    if ( this.tabCounter == 0 ) this.currTabId = null;
	},
	updateContent:
	function(id,content) {
	  var tabInfo = this.tabInfoById[id];
	  tabInfo.content = content;
	  tabInfo.editor.setValue(content);
	  this.tabInfoByPos[tabInfo.pos] = tabInfo;
	},
	updateTitle:
	function(id,title) {
	  var tabInfo = this.tabInfoById[id];
	  var tabTag = this.tabId_to_tabTag(id);
	  tabInfo.label = title;
	  $("li#tablabel-"+tabTag+"> a ").html(title);
	  this.tabInfoByPos[tabInfo.pos] = tabInfo;
	},
	//
	showTab:
        function(id) {
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];
	    if ( tabInfo.visible ) {
		this.switchTab(id);    // just switch when the tab is visible
	    } else {

		this.tabs.find( ".ui-tabs-nav" ).append( tabInfo.panel  );
		this.tabs.append( tabInfo.content );

		tabInfo.panel.show();
		tabInfo.content.show();

		tabInfo.visible = true;
		tabInfo.pos = this.tabCounter;
		this.tabInfoByPos[tabInfo.pos] = tabInfo;
		this.tabCounter++;
		this.tabs.tabs( "refresh" );

		this.switchTab(id);
	    }
	},

	//
	expandTab:
	function(id) {
	    var self = this;
	    this.hideTab(id);
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    $("

").append($(tabInfo.content))
		.dialog({
		    title: tabInfo.label,
		    height: $(document).height()*0.8,
		    maxHeight: $(document).height()*0.8,
		    beforeClose: function( event, ui ) {
		      //tabInfo.content.find(".CodeMirror").removeClass("ei-codearea-content-expanded");
		      tabInfo.content.removeClass("ei-codearea-content-expanded");
		      self.showTab(id);
		    }
		});
	    //tabInfo.content.find(".CodeMirror").addClass("ei-codearea-content-expanded");
	    tabInfo.content.addClass("ei-codearea-content-expanded");

	    tabInfo.content.show();
	},

	     //
	getTabContent:
	function(id) {
	    var tabTag = this.tabId_to_tabTag(id);
	    var tabInfo = this.tabInfoById[id];

	    return tabInfo.editor.getValue();
	},

	//
	highlightLines:
        function(id, hInfo ) {

	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "highlightLines: invalid file name";
	    }

	    var tabInfo = this.tabInfoById[id];

	    return new HighlightLinesWidget({
		lines: hInfo.lines,
		color: hInfo.color,
		outclass: hInfo.outclass,
		editor: tabInfo.editor
	    });
	},

	//
	marker:
	function(id, markerInfo) {
	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "marker: invalid file name";
	    }

	    // open the file, i.e., make the tab available if it is closed
	    this.filemanager.openFile(id);

	    // get the tab information
	    var tabInfo = this.tabInfoById[id];

	    var markerWidgetInfo = {
		lines    : markerInfo.lines,
		content  : markerInfo.content,
		outclass : markerInfo.outclass,
		onclick  : markerInfo.onclick,
		gutter   : markerInfo.gutter,
		editor   : tabInfo.editor
	    };

	    return new MarkerWidget( markerWidgetInfo );
	},

	//
	linewidget:
	function(id, widgetInfo) {
	    if ( !Number(id) )
		id = this.filemanager.getIdByPath(id);

	    if(id < 0 ) {
		throw "linewidget: invalid file name";
	    }

	    var tabInfo = this.tabInfoById[id];

	    return new InlinedMarkerWidget({
		lines: widgetInfo.lines,
		content: widgetInfo.content,
		outclass: widgetInfo.outclass,
		editor: tabInfo.editor
	    });
	},

	//
	getCurrentTabId:
	function() {
	    return this.currTabId;
	}

    };

    return CodeArea;

})();

<|endoftext|>