Changeset 774

Show
Ignore:
Timestamp:
08/04/10 11:12:06 (18 months ago)
Author:
jmpeduto
Message:

* plugin definitivo ort_editortoolbar.php hecho por:
- Juan M. Peduto
- Gustavo Lamy
- Pablo Lammel
- Diego Tkaczuk
- Damián Ehlert
ORT 2 - 2010

Location:
txp/plugins/trunk/ort_editortoolbar
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • txp/plugins/trunk/ort_editortoolbar/ort_editortoolbar.php

    r760 r774  
    11<?php 
    2 // $Id$ 
     2//$Id$ 
    33 
    44// Generamos el final del numero de version en base a la revision del repositorio subversion 
     
    1818 
    1919// ACA PONER LOS NOMBRES DE LOS AUTORES 
    20 $plugin['author'] = 'Damián Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tkaczuk (Tutor: Mariano Absatz)'; 
     20$plugin['author'] = 'Damian Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tcakzuk - (Tutor: Mariano Absatz)'; 
    2121 
    2222// si comentamos la linea siguiente, el URL va a apuntar a la ultima version del plugin en el subversion 
    23 $plugin['author_uri'] = 'http://semap.baby.com.ar/'; 
     23//$plugin['author_uri'] = '_'; 
    2424 
    2525 
    2626// ACA PONER UNA DESCRIPCION MUY BREVE DEL PLUGIN 
    27 $plugin['description'] = 'Editor de texto enriquecido para artículos y comentarios'; 
     27$plugin['description'] = 'Este plugin reemplaza el editor de texto plano de articulos por uno de texto enriquecido'; 
    2828 
    2929 
     
    3333// 2 = library          : solo se carga cuando se lo invoca expresamente usando include_plugin() o require_plugin() 
    3434// 3 = admin        : solo se carga del lado del administrador del textpattern 
    35 $plugin['type'] = 1; 
     35$plugin['type'] = 3; 
    3636 
    3737 
     
    5252if (!defined('txpinterface')) 
    5353        @include_once('zem_tpl.php'); 
    54  
     54         
    5555if (0) { 
    5656?> 
    5757# --- BEGIN PLUGIN HELP --- 
    58 h1. *ort_editor_toolbar* 
    59  
    60 _Idea and development:_ Damián Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tkaczuk 
     58h3. *ORT_EDITORTOOLBAR* 
     59 
     60__Idea and development__: Damian Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tcakzuk 
    6161_Tutoring:_ Mariano Absatz 
    6262 
    6363"Instituto de Tecnología ORT":http://www.ort.edu.ar - "Seminario de Tecnología y Aplicaciones":http://semap.baby.com.ar 
    6464 
    65 h1. Usage 
    66  
    67 Este plugin cambia el textarea común por un editor de texto enriquecido para escribir los articulos y comentarios. 
    68 Se debe descargar el editor CKEDITOR desde la web http://ckeditor.com/download y extraerlo en el directorio principal de textpattern. 
    69 Para instalar el plugin se debe ingresar el codigo codificado en base_64 en la seccion Administracion/Plugins. 
    70  
     65h5. Uso 
     66Una vez instalado y activado, este plugin reemplaza el editor de texto plano para publicar y editar articulos 
     67por un editor de tipo WYSIWYG (What You See Is What You Get), que permite insertar texto enriquecido   
     68y fue desarrollado por *Yahoo!* como parte de la libreria *YUI* (http://developer.yahoo.com/yui/). 
     69h6 *Para utilizar este plugin es necesaria una conexion a internet, de lo contrario, se mostrara el editor de  
     70texto establecido por default*  
     71 
     72h5. Use 
     73Once installed and activated, this plugin replaces the default plain text editor for publishing and editing articles with  
     74a WYSIWYG (What You See Is What You Get) editor, that allows rich text insert and was developed by *Yahoo!* 
     75as part of *YUI* library (http://developer.yahoo.com/yui/). 
     76h6 *This plugin requires an internet connection, otherwise, the default text editor will be displayed* 
    7177# --- END PLUGIN HELP --- 
    7278<?php 
     
    7480 
    7581# --- BEGIN PLUGIN CODE --- 
    76  
    77 /* Con esta funcion registramos la funcion del plugin. El primer parametro es la funcion del plugin y el segundo es el valor de la variable event */ 
    78 register_callback('ort_text_editor','article'); 
    79  
    80 //Funcion que reemplaza el textares por el editor de texto 
    81 function ort_text_editor(){ 
    82         $editor = ' 
    83                 <script type="text/javascript" src="../ckeditor/ckeditor.js"></script> 
    84                 <script type="text/javascript">' 
    85                 /* En la linea  "CKEDITOR.replace('nombre_textarea'); \n" se ingresa el nombre del textarea que se reemplaza por el editor de texto enriquecido */ 
    86                 . "// <![CDATA[\n" 
    87                 . "CKEDITOR.replace('body'); \n" 
    88                 . '//]]> 
    89                 </script> 
    90         '; 
    91         echo $editor; 
    92 } 
     82if (txpinterface == 'admin') 
     83    { 
     84        // link al codigo javascript 
     85        add_privs('ort_editoolbar_js_load', '1,2,3,4,5,6'); 
     86        register_callback('ort_editoolbar_js_load', 'article', '', 1); 
     87                 
     88                // carga el codigo javascript 
     89        add_privs('ort_editoolbar_js', '1,2,3,4,5,6'); 
     90        register_callback('ort_editoolbar_js', 'ort_editoolbar_js', '', 1); 
     91    } 
     92 
     93// ------------------------------------------------------------- 
     94/* 
     95                Funciones para manejar las opciones necesarias de yui. 
     96                Para mas informacion visitar http://developer.yahoo.com/yui/editor/#using 
     97*/ 
     98 
     99    function ort_editoolbar_js_load() 
     100    { 
     101        ob_start('ort_editoolbar_js_link'); 
     102    } 
     103         
     104    function ort_editoolbar_js_link($buffer) 
     105    { 
     106        $find = '</head>'; 
     107        $replace = ' 
     108                        <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/skin.css"> 
     109                        <script src="http://yui.yahooapis.com/2.8.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>  
     110                        <script src="http://yui.yahooapis.com/2.8.1/build/element/element-min.js"></script>  
     111                        <script src="http://yui.yahooapis.com/2.8.1/build/container/container_core-min.js"></script> 
     112                        <script src="http://yui.yahooapis.com/2.8.1/build/menu/menu-min.js"></script> 
     113                        <script src="http://yui.yahooapis.com/2.8.1/build/button/button-min.js"></script> 
     114                        <script src="http://yui.yahooapis.com/2.8.1/build/editor/editor-min.js"></script> 
     115                        <script type="text/javascript" src="index.php?event=ort_editoolbar_js"></script>'; 
     116 
     117        return str_replace($find, $replace.$find, $buffer); 
     118    } 
     119 
     120// ------------------------------------------------------------- 
     121 
     122    function ort_editoolbar_js() 
     123    { 
     124        while (@ob_end_clean()); 
     125 
     126        header("Content-type: text/javascript"); 
     127                 
     128        echo <<<js 
     129                                 
     130                /*########################### FUNCIONES JAVASCRIPT ##########################*/ 
     131                 
     132                /* 
     133                -------------------------------------------------------------------- 
     134                funcion que asigna la funcion saveHTML a los elementos de la pagina,  
     135                permitiendo conservar el valor de cada textarea luego de un submit 
     136                -------------------------------------------------------------------- 
     137                */ 
     138                 
     139                function ort_yui_asign_li(editorId){ 
     140                 
     141                        $("#page-article").find("li").each(function(i) { 
     142                                YAHOO.util.Event.on($(this), 'click', function() { 
     143                                //Asigna el html enviado de vuelta al textarea 
     144                                editorId.saveHTML(); 
     145         
     146                                }); 
     147                        }); 
     148                } 
     149                 
     150                /* 
     151                -------------------------------------------------------------------- 
     152                funcion que asigna la funcion saveHTML a los botones de la pagina,  
     153                permitiendo conservar el valor de cada textarea luego de un submit 
     154                -------------------------------------------------------------------- 
     155                */ 
     156                function ort_yui_asign_button(buttonId, editorName){ 
     157                 
     158                        YAHOO.util.Event.on(buttonId, 'click', function() { 
     159                                //Asigna el html enviado de vuelta al textarea 
     160                                editorName.saveHTML(); 
     161                          
     162                        }); 
     163                 
     164                } 
     165                 
     166                /* 
     167                -------------------------------------------------------------------- 
     168                funcion que construye un editor yui simple 
     169                -------------------------------------------------------------------- 
     170                */ 
     171                 
     172                function ort_yui_rtf_constructor_simple(elementId){ 
     173                 
     174                        myEditor = new YAHOO.widget.Editor(elementId, { 
     175                                height: '70px', 
     176                                width: '522px', 
     177                                dompath: false, 
     178                                animate: true, 
     179                                        toolbar: { 
     180                                                buttons: [ 
     181                                                        { group: 'textstyle', label: 'Font Style', 
     182                                                                buttons: [ 
     183                                                                        { type: 'push', label: 'Bold', value: 'bold' }, 
     184                                                                        { type: 'push', label: 'Italic', value: 'italic' }, 
     185                                                                        { type: 'push', label: 'Underline', value: 'underline' }, 
     186                                                                        { type: 'separator' }, 
     187                                                                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true, 
     188                                                                                menu: [ 
     189                                                                                        { text: 'Arial', checked: true }, 
     190                                                                                        { text: 'Arial Black' }, 
     191                                                                                        { text: 'Comic Sans MS' }, 
     192                                                                                        { text: 'Courier New' }, 
     193                                                                                        { text: 'Lucida Console' }, 
     194                                                                                        { text: 'Tahoma' }, 
     195                                                                                        { text: 'Times New Roman' }, 
     196                                                                                        { text: 'Trebuchet MS' }, 
     197                                                                                        { text: 'Verdana' } 
     198                                                                                ] 
     199                                                                        }, 
     200                                                                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }, 
     201                                                                        { type: 'separator' }, 
     202                                                                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true }, 
     203                                                                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true } 
     204                                                                ] 
     205                                                        } 
     206                                                ] 
     207                                        }        
     208                        }); 
     209                                         
     210                        myEditor.cmd_fontname('Arial'); 
     211                        myEditor.cmd_fontsize('10'); 
     212                        myEditor.render(); 
     213                         
     214                        return myEditor; 
     215                } 
     216                 
     217                /* 
     218                -------------------------------------------------------------------- 
     219                funcion que construye un editor yui full 
     220                -------------------------------------------------------------------- 
     221                */ 
     222                 
     223                function ort_yui_rtf_constructor_full(elementId){ 
     224                 
     225                        //codigo para instanciar el yui editor   
     226                        myEditor = new YAHOO.widget.Editor(elementId, { 
     227                                height: '300px', 
     228                                width: '522px', 
     229                                dompath: true, //Turns on the bar at the bottom 
     230                                animate: true //Animates the opening, closing and moving of Editor windows 
     231 
     232                        }); 
     233                         
     234                        myEditor.get('toolbar').titlebar = false; 
     235                        myEditor.cmd_fontname('Arial'); 
     236                        myEditor.cmd_fontsize('10'); 
     237                        myEditor.render(); 
     238                         
     239                        return myEditor; 
     240                } 
     241                 
     242                /*########################### FUNCIONES JAVASCRIPT ##########################*/ 
     243                 
     244                /*########################### CODIGO JQUERY ##########################*/ 
     245                 
     246                $(document).ready(function() { 
     247                        // agrega la clase necesaria al body para que yui editor funcione 
     248                        $('#page-article').addClass('yui-skin-sam'); 
     249                         
     250                        //agrega el id save al boton de salvar para poder asignarle eventos con jQuery 
     251                        $('#page-article input[name="save"]').attr("id","save"); 
     252                         
     253                        //variables para instanciar los yui editors 
     254                        var articleEditor; 
     255                        var excerptEditor; 
     256                         
     257                        articleEditor = ort_yui_rtf_constructor_full('body'); 
     258                        excerptEditor = ort_yui_rtf_constructor_simple('excerpt'); 
     259                         
     260                        ort_yui_asign_li(articleEditor); 
     261                        ort_yui_asign_li(excerptEditor); 
     262                        ort_yui_asign_button("save", articleEditor); 
     263                        ort_yui_asign_button("save", excerptEditor); 
     264                 
     265                }); 
     266                 
     267        /*########################### CODIGO JQUERY ##########################*/ 
     268 
     269js; 
     270                exit(0);     
     271    } 
    93272 
    94273# --- END PLUGIN CODE --- 
  • txp/plugins/trunk/ort_editortoolbar/ort_editortoolbar.txt

    r772 r774  
    1 # ort_editortoolbar v0.1-r760 
    2 # Editor de texto enriquecido para artículos y comentarios 
    3 # Damián Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tkaczuk (Tutor: Mariano Absatz) 
    4 # http://semap.baby.com.ar/ 
     1# ort_editortoolbar v0.1-r 
     2# Este plugin reemplaza el editor de texto plano de articulos por uno de texto enriquecido 
     3# Damian Ehlert - Pablo Lammel - Gustavo Lamy - Juan Manuel Peduto - Diego Tcakzuk - (Tutor: Mariano Absatz) 
     4# .txt 
    55 
    66# ...................................................................... 
     
    1010# ...................................................................... 
    1111 
    12 H4sIAAAAAAAAA+1VzW4bNxA+i08xXRSQbTS7ki3JyfoHEGy1cNMiRqKe0mDB5Y4lxlxyQ3Kl 
    13 ykEeJg+QF+jVL9bh7srKX5FLDz3kIonk/HzzfTMjng4P07cuPU6jFVonjY5OXPo4jQbx8JE9 
    14 ngzCcThII177pbFZbWW4ORyn0dL7Kk0ShyWv4pznm1iYMuY2CQajNNK8xMabYhvrMyykp29j 
    15 VM5teJhso7Y5KOQlL+X9ew2zpULr4RFc81wZ+I2XJSo6/lI7z1fNxYaOv9Zcw+9c1/R4jUXt 
    16 DV1eSlwYmN9ycVffwt6cbm1KVlZybWCaO+7v9puMwzQq0AkrK9/VPSaoswYmFAge/6KIqK18 
    17 U6OQhYGKWw7c+vsPolbGwQaoZNSeghvXle03FZUt02GIFyov0IbzOKSkC66UWWdLX6psiaoK 
    18 T4PWsz0SL+NwGMZwsKMt63g7YCy7KpBQ6IIwrlCZKiBIM/jPyWNZQ57UC4r+KYGMRVfaeemD 
    19 G1E1R6GNMov7DxyePZ9Hadcc6/U6piJiik+dQQmiF1hKHfj63G0D00pJwQVpge4hwhftxVig 
    20 5g/HF8jYzHmEStULqUHwMpccqJwgHLdEEnnc/62hIj1rDfgtZZtmyKWFoC3JLL+icsxeIIXI 
    21 w4cT3C6oLErZxb54Oru8mj97Hh4pj+Kwxhy6UsRtaxUKSQqz1srwgqITGMvRqoAoxCqkRRGI 
    22 J1jEvpAVV1vUFfcerY7ZdQAsSQOuWgQdC65DR6pZdO2TMIUkWcPXDTFcNIly7jCbjMJPgulQ 
    23 BOJhWpA80hGgcEyum6Au7nqbImDboTS7LDmAC3JBwgA3tW78LS4a75J4U7vr4gFgDDMVyirR 
    24 NqSX6C3h+RfrwI4icItaF40VnVZctSqSxyp0Za4QaBK0h4OEtQDQZoIGLefidq8fpihw141S 
    25 /6d+o63C/v4JY0nyc5eWeoHwY1kpfvdxH7mmgXYibxuIBbxhdcBnGfb237Lej531GfRZr3fa 
    26 7hkI2+EsCrbJa77i7W0EzoqzKI4fWmTXK69ddH6atHbn3wx0HnKRLrNGVCU1DQFE266MLVJt 
    27 Avf62pS5xWw7KEQE/Kmj0Dxd34RyW6NGjYeJChy5j2n6OjWfzBap0uvFECUJnP7w8uJyOp++ 
    28 pGzt5ZfYclNsOkCNST9JXr1qSt/R0D9hPRRLAx3LJ+wd6/64whbNLF9/36TfN+n/dJMepVFZ 
    29 jJtfh7RUj8SxOH78ZDQZHA1vCiHGYoKTkRBHwyc3owkt3Hf/AHO9AM2mCQAA 
     12YToxMTp7czo3OiJ2ZXJzaW9uIjtzOjU6IjAuMS1yIjtzOjEwOiJhdXRob3JfdXJpIjtzOjQ6 
     13Ii50eHQiO3M6NDoibmFtZSI7czoxNzoib3J0X2VkaXRvcnRvb2xiYXIiO3M6NjoiYXV0aG9y 
     14IjtzOjEwNzoiRGFtaWFuIEVobGVydCAtIFBhYmxvIExhbW1lbCAtIEd1c3Rhdm8gTGFteSAt 
     15IEp1YW4gTWFudWVsIFBlZHV0byAtIERpZWdvIFRjYWt6dWsgLSAgKFR1dG9yOiBNYXJpYW5v 
     16IEFic2F0eikiO3M6MTE6ImRlc2NyaXB0aW9uIjtzOjg4OiJFc3RlIHBsdWdpbiByZWVtcGxh 
     17emEgZWwgZWRpdG9yIGRlIHRleHRvIHBsYW5vIGRlIGFydGljdWxvcyBwb3IgdW5vIGRlIHRl 
     18eHRvIGVucmlxdWVjaWRvIjtzOjQ6InR5cGUiO2k6MztzOjU6Im9yZGVyIjtpOjU7czoxNToi 
     19YWxsb3dfaHRtbF9oZWxwIjtpOjA7czo0OiJoZWxwIjtzOjExNDM6ImgzLiAqT1JUX0VESVRP 
     20UlRPT0xCQVIqCgpfX0lkZWEgYW5kIGRldmVsb3BtZW50X186IERhbWlhbiBFaGxlcnQgLSBQ 
     21YWJsbyBMYW1tZWwgLSBHdXN0YXZvIExhbXkgLSBKdWFuIE1hbnVlbCBQZWR1dG8gLSBEaWVn 
     22byBUY2FrenVrCl9UdXRvcmluZzpfIE1hcmlhbm8gQWJzYXR6CgoiSW5zdGl0dXRvIGRlIFRl 
     23Y25vbG9nw61hIE9SVCI6aHR0cDovL3d3dy5vcnQuZWR1LmFyIC0gIlNlbWluYXJpbyBkZSBU 
     24ZWNub2xvZ8OtYSB5IEFwbGljYWNpb25lcyI6aHR0cDovL3NlbWFwLmJhYnkuY29tLmFyCgpo 
     25NS4gVXNvClVuYSB2ZXogaW5zdGFsYWRvIHkgYWN0aXZhZG8sIGVzdGUgcGx1Z2luIHJlZW1w 
     26bGF6YSBlbCBlZGl0b3IgZGUgdGV4dG8gcGxhbm8gcGFyYSBwdWJsaWNhciB5IGVkaXRhciBh 
     27cnRpY3Vsb3MKcG9yIHVuIGVkaXRvciBkZSB0aXBvIFdZU0lXWUcgKFdoYXQgWW91IFNlZSBJ 
     28cyBXaGF0IFlvdSBHZXQpLCBxdWUgcGVybWl0ZSBpbnNlcnRhciB0ZXh0byBlbnJpcXVlY2lk 
     29bwp5IGZ1ZSBkZXNhcnJvbGxhZG8gcG9yICpZYWhvbyEqIGNvbW8gcGFydGUgZGUgbGEgbGli 
     30cmVyaWEgKllVSSogKGh0dHA6Ly9kZXZlbG9wZXIueWFob28uY29tL3l1aS8pLgpoNiAqUGFy 
     31YSB1dGlsaXphciBlc3RlIHBsdWdpbiBlcyBuZWNlc2FyaWEgdW5hIGNvbmV4aW9uIGEgaW50 
     32ZXJuZXQsIGRlIGxvIGNvbnRyYXJpbywgc2UgbW9zdHJhcmEgZWwgZWRpdG9yIGRlCnRleHRv 
     33IGVzdGFibGVjaWRvIHBvciBkZWZhdWx0KgoKaDUuIFVzZQpPbmNlIGluc3RhbGxlZCBhbmQg 
     34YWN0aXZhdGVkLCB0aGlzIHBsdWdpbiByZXBsYWNlcyB0aGUgZGVmYXVsdCBwbGFpbiB0ZXh0 
     35IGVkaXRvciBmb3IgcHVibGlzaGluZyBhbmQgZWRpdGluZyBhcnRpY2xlcyB3aXRoCmEgV1lT 
     36SVdZRyAoV2hhdCBZb3UgU2VlIElzIFdoYXQgWW91IEdldCkgZWRpdG9yLCB0aGF0IGFsbG93 
     37cyByaWNoIHRleHQgaW5zZXJ0IGFuZCB3YXMgZGV2ZWxvcGVkIGJ5ICpZYWhvbyEqCmFzIHBh 
     38cnQgb2YgKllVSSogbGlicmFyeSAoaHR0cDovL2RldmVsb3Blci55YWhvby5jb20veXVpLyku 
     39Cmg2ICpUaGlzIHBsdWdpbiByZXF1aXJlcyBhbiBpbnRlcm5ldCBjb25uZWN0aW9uLCBvdGhl 
     40cndpc2UsIHRoZSBkZWZhdWx0IHRleHQgZWRpdG9yIHdpbGwgYmUgZGlzcGxheWVkKiI7czo0 
     41OiJjb2RlIjtzOjYxMzQ6ImlmICh0eHBpbnRlcmZhY2UgPT0gJ2FkbWluJykKICAgIHsKICAg 
     42ICAgICAvLyBsaW5rIGFsIGNvZGlnbyBqYXZhc2NyaXB0CiAgICAgICAgYWRkX3ByaXZzKCdv 
     43cnRfZWRpdG9vbGJhcl9qc19sb2FkJywgJzEsMiwzLDQsNSw2Jyk7CiAgICAgICAgcmVnaXN0 
     44ZXJfY2FsbGJhY2soJ29ydF9lZGl0b29sYmFyX2pzX2xvYWQnLCAnYXJ0aWNsZScsICcnLCAx 
     45KTsKCgkJLy8gY2FyZ2EgZWwgY29kaWdvIGphdmFzY3JpcHQKICAgICAgICBhZGRfcHJpdnMo 
     46J29ydF9lZGl0b29sYmFyX2pzJywgJzEsMiwzLDQsNSw2Jyk7CiAgICAgICAgcmVnaXN0ZXJf 
     47Y2FsbGJhY2soJ29ydF9lZGl0b29sYmFyX2pzJywgJ29ydF9lZGl0b29sYmFyX2pzJywgJycs 
     48IDEpOwogICAgfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     49LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovKgoJCUZ1bmNpb25lcyBwYXJhIG1hbmVqYXIgbGFz 
     50IG9wY2lvbmVzIG5lY2VzYXJpYXMgZGUgeXVpLgoJCVBhcmEgbWFzIGluZm9ybWFjaW9uIHZp 
     51c2l0YXIgaHR0cDovL2RldmVsb3Blci55YWhvby5jb20veXVpL2VkaXRvci8jdXNpbmcKKi8K 
     52CiAgICBmdW5jdGlvbiBvcnRfZWRpdG9vbGJhcl9qc19sb2FkKCkKICAgIHsKICAgICAgICBv 
     53Yl9zdGFydCgnb3J0X2VkaXRvb2xiYXJfanNfbGluaycpOwogICAgfQoKICAgIGZ1bmN0aW9u 
     54IG9ydF9lZGl0b29sYmFyX2pzX2xpbmsoJGJ1ZmZlcikKICAgIHsKICAgICAgICAkZmluZCA9 
     55ICc8L2hlYWQ+JzsKICAgICAgICAkcmVwbGFjZSA9ICcKCQkJPGxpbmsgcmVsPSJzdHlsZXNo 
     56ZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0iaHR0cDovL3l1aS55YWhvb2FwaXMuY29tLzIu 
     57OC4xL2J1aWxkL2Fzc2V0cy9za2lucy9zYW0vc2tpbi5jc3MiPgoJCQk8c2NyaXB0IHNyYz0i 
     58aHR0cDovL3l1aS55YWhvb2FwaXMuY29tLzIuOC4xL2J1aWxkL3lhaG9vLWRvbS1ldmVudC95 
     59YWhvby1kb20tZXZlbnQuanMiPjwvc2NyaXB0PgoJCQk8c2NyaXB0IHNyYz0iaHR0cDovL3l1 
     60aS55YWhvb2FwaXMuY29tLzIuOC4xL2J1aWxkL2VsZW1lbnQvZWxlbWVudC1taW4uanMiPjwv 
     61c2NyaXB0PgoJCQk8c2NyaXB0IHNyYz0iaHR0cDovL3l1aS55YWhvb2FwaXMuY29tLzIuOC4x 
     62L2J1aWxkL2NvbnRhaW5lci9jb250YWluZXJfY29yZS1taW4uanMiPjwvc2NyaXB0PgoJCQk8 
     63c2NyaXB0IHNyYz0iaHR0cDovL3l1aS55YWhvb2FwaXMuY29tLzIuOC4xL2J1aWxkL21lbnUv 
     64bWVudS1taW4uanMiPjwvc2NyaXB0PgoJCQk8c2NyaXB0IHNyYz0iaHR0cDovL3l1aS55YWhv 
     65b2FwaXMuY29tLzIuOC4xL2J1aWxkL2J1dHRvbi9idXR0b24tbWluLmpzIj48L3NjcmlwdD4K 
     66CQkJPHNjcmlwdCBzcmM9Imh0dHA6Ly95dWkueWFob29hcGlzLmNvbS8yLjguMS9idWlsZC9l 
     67ZGl0b3IvZWRpdG9yLW1pbi5qcyI+PC9zY3JpcHQ+CgkJCTxzY3JpcHQgdHlwZT0idGV4dC9q 
     68YXZhc2NyaXB0IiBzcmM9ImluZGV4LnBocD9ldmVudD1vcnRfZWRpdG9vbGJhcl9qcyI+PC9z 
     69Y3JpcHQ+JzsKCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCRmaW5kLCAkcmVwbGFjZS4k 
     70ZmluZCwgJGJ1ZmZlcik7CiAgICB9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     71LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZnVuY3Rpb24gb3J0X2Vk 
     72aXRvb2xiYXJfanMoKQogICAgewogICAgICAgIHdoaWxlIChAb2JfZW5kX2NsZWFuKCkpOwoK 
     73ICAgICAgICBoZWFkZXIoIkNvbnRlbnQtdHlwZTogdGV4dC9qYXZhc2NyaXB0Iik7CgogICAg 
     74ICAgIGVjaG8gPDw8anMKCgkJLyojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgRlVOQ0lP 
     75TkVTIEpBVkFTQ1JJUFQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMqLwoKCQkvKgoJCS0t 
     76LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     77LS0tLS0tLS0tLS0tCgkJZnVuY2lvbiBxdWUgYXNpZ25hIGxhIGZ1bmNpb24gc2F2ZUhUTUwg 
     78YSBsb3MgZWxlbWVudG9zIGRlIGxhIHBhZ2luYSwKCQlwZXJtaXRpZW5kbyBjb25zZXJ2YXIg 
     79ZWwgdmFsb3IgZGUgY2FkYSB0ZXh0YXJlYSBsdWVnbyBkZSB1biBzdWJtaXQKCQktLS0tLS0t 
     80LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     81LS0tLS0tLQoJCSovCgoJCWZ1bmN0aW9uIG9ydF95dWlfYXNpZ25fbGkoZWRpdG9ySWQpewoK 
     82CQkJJCgiI3BhZ2UtYXJ0aWNsZSIpLmZpbmQoImxpIikuZWFjaChmdW5jdGlvbihpKSB7CgkJ 
     83CQlZQUhPTy51dGlsLkV2ZW50Lm9uKCQodGhpcyksICdjbGljaycsIGZ1bmN0aW9uKCkgewoJ 
     84CQkJLy9Bc2lnbmEgZWwgaHRtbCBlbnZpYWRvIGRlIHZ1ZWx0YSBhbCB0ZXh0YXJlYQoJCQkJ 
     85ZWRpdG9ySWQuc2F2ZUhUTUwoKTsKCgkJCQl9KTsKCQkJfSk7CgkJfQoKCQkvKgoJCS0tLS0t 
     86LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     87LS0tLS0tLS0tCgkJZnVuY2lvbiBxdWUgYXNpZ25hIGxhIGZ1bmNpb24gc2F2ZUhUTUwgYSBs 
     88b3MgYm90b25lcyBkZSBsYSBwYWdpbmEsCgkJcGVybWl0aWVuZG8gY29uc2VydmFyIGVsIHZh 
     89bG9yIGRlIGNhZGEgdGV4dGFyZWEgbHVlZ28gZGUgdW4gc3VibWl0CgkJLS0tLS0tLS0tLS0t 
     90LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     91LS0KCQkqLwoJCWZ1bmN0aW9uIG9ydF95dWlfYXNpZ25fYnV0dG9uKGJ1dHRvbklkLCBlZGl0 
     92b3JOYW1lKXsKCgkJCVlBSE9PLnV0aWwuRXZlbnQub24oYnV0dG9uSWQsICdjbGljaycsIGZ1 
     93bmN0aW9uKCkgewoJCQkJLy9Bc2lnbmEgZWwgaHRtbCBlbnZpYWRvIGRlIHZ1ZWx0YSBhbCB0 
     94ZXh0YXJlYQoJCQkJZWRpdG9yTmFtZS5zYXZlSFRNTCgpOwoKCQkJfSk7CgoJCX0KCgkJLyoK 
     95CQktLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     96LS0tLS0tLS0tLS0tLS0tLQoJCWZ1bmNpb24gcXVlIGNvbnN0cnV5ZSB1biBlZGl0b3IgeXVp 
     97IHNpbXBsZQoJCS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     98LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkJKi8KCgkJZnVuY3Rpb24gb3J0X3l1aV9ydGZf 
     99Y29uc3RydWN0b3Jfc2ltcGxlKGVsZW1lbnRJZCl7CgoJCQlteUVkaXRvciA9IG5ldyBZQUhP 
     100Ty53aWRnZXQuRWRpdG9yKGVsZW1lbnRJZCwgewoJCQkJaGVpZ2h0OiAnNzBweCcsCgkJCQl3 
     101aWR0aDogJzUyMnB4JywKCQkJCWRvbXBhdGg6IGZhbHNlLAoJCQkJYW5pbWF0ZTogdHJ1ZSwK 
     102CQkJCQl0b29sYmFyOiB7CgkJCQkJCWJ1dHRvbnM6IFsKCQkJCQkJCXsgZ3JvdXA6ICd0ZXh0 
     103c3R5bGUnLCBsYWJlbDogJ0ZvbnQgU3R5bGUnLAoJCQkJCQkJCWJ1dHRvbnM6IFsKCQkJCQkJ 
     104CQkJeyB0eXBlOiAncHVzaCcsIGxhYmVsOiAnQm9sZCcsIHZhbHVlOiAnYm9sZCcgfSwKCQkJ 
     105CQkJCQkJeyB0eXBlOiAncHVzaCcsIGxhYmVsOiAnSXRhbGljJywgdmFsdWU6ICdpdGFsaWMn 
     106IH0sCgkJCQkJCQkJCXsgdHlwZTogJ3B1c2gnLCBsYWJlbDogJ1VuZGVybGluZScsIHZhbHVl 
     107OiAndW5kZXJsaW5lJyB9LAoJCQkJCQkJCQl7IHR5cGU6ICdzZXBhcmF0b3InIH0sCgkJCQkJ 
     108CQkJCXsgdHlwZTogJ3NlbGVjdCcsIGxhYmVsOiAnQXJpYWwnLCB2YWx1ZTogJ2ZvbnRuYW1l 
     109JywgZGlzYWJsZWQ6IHRydWUsCgkJCQkJCQkJCQltZW51OiBbCgkJCQkJCQkJCQkJeyB0ZXh0 
     110OiAnQXJpYWwnLCBjaGVja2VkOiB0cnVlIH0sCgkJCQkJCQkJCQkJeyB0ZXh0OiAnQXJpYWwg 
     111QmxhY2snIH0sCgkJCQkJCQkJCQkJeyB0ZXh0OiAnQ29taWMgU2FucyBNUycgfSwKCQkJCQkJ 
     112CQkJCQl7IHRleHQ6ICdDb3VyaWVyIE5ldycgfSwKCQkJCQkJCQkJCQl7IHRleHQ6ICdMdWNp 
     113ZGEgQ29uc29sZScgfSwKCQkJCQkJCQkJCQl7IHRleHQ6ICdUYWhvbWEnIH0sCgkJCQkJCQkJ 
     114CQkJeyB0ZXh0OiAnVGltZXMgTmV3IFJvbWFuJyB9LAoJCQkJCQkJCQkJCXsgdGV4dDogJ1Ry 
     115ZWJ1Y2hldCBNUycgfSwKCQkJCQkJCQkJCQl7IHRleHQ6ICdWZXJkYW5hJyB9CgkJCQkJCQkJ 
     116CQldCgkJCQkJCQkJCX0sCgkJCQkJCQkJCXsgdHlwZTogJ3NwaW4nLCBsYWJlbDogJzEzJywg 
     117dmFsdWU6ICdmb250c2l6ZScsIHJhbmdlOiBbIDksIDc1IF0sIGRpc2FibGVkOiB0cnVlIH0s 
     118CgkJCQkJCQkJCXsgdHlwZTogJ3NlcGFyYXRvcicgfSwKCQkJCQkJCQkJeyB0eXBlOiAnY29s 
     119b3InLCBsYWJlbDogJ0ZvbnQgQ29sb3InLCB2YWx1ZTogJ2ZvcmVjb2xvcicsIGRpc2FibGVk 
     120OiB0cnVlIH0sCgkJCQkJCQkJCXsgdHlwZTogJ2NvbG9yJywgbGFiZWw6ICdCYWNrZ3JvdW5k 
     121IENvbG9yJywgdmFsdWU6ICdiYWNrY29sb3InLCBkaXNhYmxlZDogdHJ1ZSB9CgkJCQkJCQkJ 
     122XQoJCQkJCQkJfQoJCQkJCQldCgkJCQkJfQoJCQl9KTsKCgkJCW15RWRpdG9yLmNtZF9mb250 
     123bmFtZSgnQXJpYWwnKTsKCQkJbXlFZGl0b3IuY21kX2ZvbnRzaXplKCcxMCcpOwoJCQlteUVk 
     124aXRvci5yZW5kZXIoKTsKCgkJCXJldHVybiBteUVkaXRvcjsKCQl9CgoJCS8qCgkJLS0tLS0t 
     125LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     126LS0tLS0tLS0KCQlmdW5jaW9uIHF1ZSBjb25zdHJ1eWUgdW4gZWRpdG9yIHl1aSBmdWxsCgkJ 
     127LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t 
     128LS0tLS0tLS0tLS0tLS0KCQkqLwoKCQlmdW5jdGlvbiBvcnRfeXVpX3J0Zl9jb25zdHJ1Y3Rv 
     129cl9mdWxsKGVsZW1lbnRJZCl7CgoJCQkvL2NvZGlnbyBwYXJhIGluc3RhbmNpYXIgZWwgeXVp 
     130IGVkaXRvcgoJCQlteUVkaXRvciA9IG5ldyBZQUhPTy53aWRnZXQuRWRpdG9yKGVsZW1lbnRJ 
     131ZCwgewoJCQkJaGVpZ2h0OiAnMzAwcHgnLAoJCQkJd2lkdGg6ICc1MjJweCcsCgkJCQlkb21w 
     132YXRoOiB0cnVlLCAvL1R1cm5zIG9uIHRoZSBiYXIgYXQgdGhlIGJvdHRvbQoJCQkJYW5pbWF0 
     133ZTogdHJ1ZSAvL0FuaW1hdGVzIHRoZSBvcGVuaW5nLCBjbG9zaW5nIGFuZCBtb3Zpbmcgb2Yg 
     134RWRpdG9yIHdpbmRvd3MKCgkJCX0pOwoKCQkJbXlFZGl0b3IuZ2V0KCd0b29sYmFyJykudGl0 
     135bGViYXIgPSBmYWxzZTsKCQkJbXlFZGl0b3IuY21kX2ZvbnRuYW1lKCdBcmlhbCcpOwoJCQlt 
     136eUVkaXRvci5jbWRfZm9udHNpemUoJzEwJyk7CgkJCW15RWRpdG9yLnJlbmRlcigpOwoKCQkJ 
     137cmV0dXJuIG15RWRpdG9yOwoJCX0KCgkJLyojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMg 
     138RlVOQ0lPTkVTIEpBVkFTQ1JJUFQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMqLwoKCQkv 
     139KiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBDT0RJR08gSlFVRVJZICMjIyMjIyMjIyMj 
     140IyMjIyMjIyMjIyMjIyMjKi8KCgkJJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKSB7CgkJ 
     141CS8vIGFncmVnYSBsYSBjbGFzZSBuZWNlc2FyaWEgYWwgYm9keSBwYXJhIHF1ZSB5dWkgZWRp 
     142dG9yIGZ1bmNpb25lCgkJCSQoJyNwYWdlLWFydGljbGUnKS5hZGRDbGFzcygneXVpLXNraW4t 
     143c2FtJyk7CgoJCQkvL2FncmVnYSBlbCBpZCBzYXZlIGFsIGJvdG9uIGRlIHNhbHZhciBwYXJh 
     144IHBvZGVyIGFzaWduYXJsZSBldmVudG9zIGNvbiBqUXVlcnkKCQkJJCgnI3BhZ2UtYXJ0aWNs 
     145ZSBpbnB1dFtuYW1lPSJzYXZlIl0nKS5hdHRyKCJpZCIsInNhdmUiKTsKCgkJCS8vdmFyaWFi 
     146bGVzIHBhcmEgaW5zdGFuY2lhciBsb3MgeXVpIGVkaXRvcnMKCQkJdmFyIGFydGljbGVFZGl0 
     147b3I7CgkJCXZhciBleGNlcnB0RWRpdG9yOwoKCQkJYXJ0aWNsZUVkaXRvciA9IG9ydF95dWlf 
     148cnRmX2NvbnN0cnVjdG9yX2Z1bGwoJ2JvZHknKTsKCQkJZXhjZXJwdEVkaXRvciA9IG9ydF95 
     149dWlfcnRmX2NvbnN0cnVjdG9yX3NpbXBsZSgnZXhjZXJwdCcpOwoKCQkJb3J0X3l1aV9hc2ln 
     150bl9saShhcnRpY2xlRWRpdG9yKTsKCQkJb3J0X3l1aV9hc2lnbl9saShleGNlcnB0RWRpdG9y 
     151KTsKCQkJb3J0X3l1aV9hc2lnbl9idXR0b24oInNhdmUiLCBhcnRpY2xlRWRpdG9yKTsKCQkJ 
     152b3J0X3l1aV9hc2lnbl9idXR0b24oInNhdmUiLCBleGNlcnB0RWRpdG9yKTsKCgkJfSk7Cgog 
     153ICAgICAgIC8qIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIENPRElHTyBKUVVFUlkgIyMj 
     154IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMqLwoKanM7CgkJZXhpdCgwKTsKICAgIH0KIjtzOjM6 
     155Im1kNSI7czozMjoiYzQ1NDkzNzM5MWRlMDk2NTVlNjk5ZWUyMzBkMDU2MTgiO30=