From 0fb1f8a9850cb526daa92009afc6cffa12c8a7ca Mon Sep 17 00:00:00 2001 From: bruno Date: Wed, 20 Sep 2023 15:29:39 -0400 Subject: [PATCH] =?UTF-8?q?Excluir=20v=C3=A1rios=20arquivos=20desnecess?= =?UTF-8?q?=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Desktop.ini | Bin 191 -> 0 bytes admin/index_teste.php | 13 - admin/limpaGruposAtendimento.php | 136 -- agente/trash/agentert.php | 2745 ------------------------------ agente/trash/index.php | 9 - agente/trash/trash.php | 1 - composer.json | 6 - composer.lock | 1837 -------------------- conf/authz | 32 - conf/bd | 9 - conf/bd.bak | 9 - conf/passwd | 8 - conf/svnserve.conf | 61 - info.php | 8 - queues_filas.conf | 0 seguranca/php.ini | 1221 ------------- sip_ramais.conf | 0 sip_register.conf | 0 voicemail.conf | 4 - 19 files changed, 6099 deletions(-) delete mode 100644 Desktop.ini delete mode 100644 admin/index_teste.php delete mode 100644 admin/limpaGruposAtendimento.php delete mode 100644 agente/trash/agentert.php delete mode 100644 agente/trash/index.php delete mode 100644 agente/trash/trash.php delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100644 conf/authz delete mode 100644 conf/bd delete mode 100644 conf/bd.bak delete mode 100644 conf/passwd delete mode 100644 conf/svnserve.conf delete mode 100644 info.php delete mode 100644 queues_filas.conf delete mode 100644 seguranca/php.ini delete mode 100644 sip_ramais.conf delete mode 100644 sip_register.conf delete mode 100644 voicemail.conf diff --git a/Desktop.ini b/Desktop.ini deleted file mode 100644 index 119d4b0fb34c27cef31fb81bf7bbb749168eb78f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmYj~OA3QP5JcZv$Q^P5@dB;_0at>$lPnS)Q7|fMg5KV0gBY4&`tzzP$0w!6(W-8G zPbO7FM@7$ri>GzJj}0Sl?li(2F#{oi0TIQH9H&qYUrBtScKJihxRiQ1wZEiHtQn?! YcuDOPHfd+kR}#&GdfUwUM^ - - - Untitled Document - - - - - Ramais - - - diff --git a/admin/limpaGruposAtendimento.php b/admin/limpaGruposAtendimento.php deleted file mode 100644 index c73bac87..00000000 --- a/admin/limpaGruposAtendimento.php +++ /dev/null @@ -1,136 +0,0 @@ - ''); - $pick = strtr($pick,$filtro); - } - $filtro = array($id => 'xx'); - $pick = strtr($pick, $filtro); - if(strstr($pick,"xx,")) - { - $filtro = array("xx," => ''); - $pick = strtr($pick, $filtro); - } - - $query = "UPDATE PBX_SIP_RAMAIS set PICKUPGROUP='$pick' WHERE nome='$nome'"; - pg_query($dbcon,$query); - } - - if(strstr($pick,"".$id."")) - { - $ultimoCa = substr($pick,(strlen($pick)-3),strlen($pick));; - if($ultimoCa == ",".$id."") - { - $filtro = array(",".$id."" => ''); - $pick = strtr($pick,$filtro); - } - $filtro = array('$id' => 'xx'); - $pick = strtr($pick, $filtro); - if(strstr($pick,"xx,")) - { - $filtro = array("xx," => ''); - $pick = strtr($pick, $filtro); - } - - $query = "UPDATE PBX_SIP_RAMAIS set PICKUPGROUP='$pick' WHERE nome='$nome' "; - pg_query($dbcon,$query); - - } - } */ - - - - - - - - - - -/* - - //pesquisa por maior registro no banco , se for maior que 65 realiza a limpeza da tabela! - $sql = "SELECT MAX(id) FROM pbx_grupos_atendimento WHERE id > 65"; - $result = pg_query($dbcon,$sql); - if(pg_num_rows($result) >= 1) - { - - //pega registro do banco - $sql = "SELECT id,nome FROM pbx_grupos_atendimento ORDER BY id ASC"; - $result = pg_query($dbcon,$sql); - while($row = pg_fetch_array($result)) - { - $id = ""; - $nome = ""; - //da valores a variaveis - $id = $row['id']; - $nome = $row['nome']; - $numero = $numero; - $cond = true; - if($cond == true){$numero = $numero + 1;} - //update status do grupo - $sql2 = "SELECT b.ramal FROM pbx_grupos_atendimento a,pbx_grupos_atendimento_ramais b WHERE b.id_grupo=a.id AND b.id_grupo='$id'"; - $result2 = pg_query($dbcon,$sql2); - if(pg_num_rows($result2) < 1) - { - $update = "UPDATE pbx_grupos_atendimento SET status='f' WHERE id='$id'"; - pg_query($dbcon,$update); - $numero = $numero -2; - } - else - { - $update = "UPDATE pbx_grupos_atendimento SET status='t' WHERE id='$id'"; - pg_query($dbcon,$update); - } - - //update em pickupgroup - $sql3 = "SELECT a.nome,a.pickupgroup,a.callgroup FROM pbx_sip_ramais a,pbx_grupos_atendimento_ramais b WHERE a.nome=b.ramal AND b.id_grupo='$id'"; - $result3 = pg_query($dbcon,$sql3); - while($row3 = pg_fetch_array($result3)) - { - $pickup = $row3['pickupgroup']; - $callgroup = $row3['callgroup']; - $nome = $row3['nome']; - //se o callgroup for igual ao id do grupo que sera alterado, altera! - if(strstr($callgroup,$id)) - { - $filtro = array($id => $numero); - $callgroup = strtr($callgroup, $filtro); - $updateCall = "UPDATE pbx_sip_ramais SET callgroup='$callgroup' WHERE nome='$nome'"; - pg_query($dbcon,$updateCall); - } - //se o pickupgroup for igual ao id do grupo que sera alterado, altera! - if(strstr($pickup,$id)) - { - $filtro = array($id => $numero); - $pickup = strtr($pickup, $filtro); - } - $updatePick = "UPDATE pbx_sip_ramais SET pickupgroup='$pickup' WHERE nome='$nome'"; - pg_query($dbcon,$updatePick); - } - - $update = "UPDATE pbx_grupos_atendimento_ramais SET id_grupo='$numero' WHERE id_grupo='$id'"; - pg_query($dbcon,$update); - $updateGroup = "UPDATE pbx_grupos_atendimento SET id='$numero' WHERE id='$id'"; - pg_query($dbcon,$updateGroup); - - - - } - - } */ -?> \ No newline at end of file diff --git a/agente/trash/agentert.php b/agente/trash/agentert.php deleted file mode 100644 index 20cff686..00000000 --- a/agente/trash/agentert.php +++ /dev/null @@ -1,2745 +0,0 @@ - Quantidade de chamadas em fila - duracao -> Duração da chamada corrente - fone -> Numere de origem ou destino - - Informacoes de chamadas do agente - abandonadas -> Chamadads Abandonadas na fila - tme -> Tempo médio de espera na fila - tma -> tempo médio de atendimento - atendidasPa -> Número de chamadas atendidas pelo agente - - Infoemacoes gerais - motivoPausa -> Combo com os motivos de pausa disponiveis - numProtocolo -> Número do protocolo de atendimento - dacs -> Lista com os dacs Disponiveis - valueBtConectar -> Label refletindo o status do agente no botao conecar ao dac - msg_sis -> Mensagens para o usuarios - ramalAgente -> Ramal do Agente - dacLogado -> Dispositivo ou Dac que o agente se logou - statusAgente -> Status atual do agente - horaAtu -> Hora Atual - tempoLogado -> Tempo que o agente esta conectado ao dac - - Classificação - useClassifica -> Mostra controles para classificação de chamadas qdo verdadeiro - useContrib -> Mostra controles para identificaçao de clientes qdo verdadeiro - classifica -> Lista com classificacoes cadastradas para o dac - clasItem -> Listas com itens relacioanados a classificaçao da chamada - */ - -/* - * Constantes para sesssao do agente, - * definidas em constantes.php sessao AgenteRT - */ -$dadosMonitor = array("qtde_fila" => 0, "duracao" => '00:00:00', "fone" => '-', "abandonadas" => '0', "tme" => '0', "tma" => '0', - "atendidas_pa" => '0', "num_protocolo" => '-', "ramal_monitor" => '', "dac_logado" => '-', - "status_agente" => 'OFF', "tempo_logado" => '-', "uniqueid2" => 0, "tempo_atualiza" => 0, "pausa_motivo_rt" => '-', "pausa_motivo_ausente" => 0, - "uniqueid" => 0, 'matricula' => '-', "disponivel_atendimento" => 1, "disponivelFila" => '1', "originadas_pa" => '0', "agente_anota_key" => "", - "txt_cliente" => "", "chamada_classificado" => '2', "chamada_classificado_txt" => '...', "chamada_classificado_exige" => '0', "prm_obs_pausaprod" => '0', - "exibePesquisa" => '0', 'canal_transfer' => '', "abandonadasRet" => '0', "tipo_ligacao" => '', "cont_identificador" => '', "status_discador" => 0, "vendido" => 0); - -$dadosMonitorCompl = array("use_contrib" => '0', "classifica" => '', "dacs" => '-', "clas_item" => '', "value_bt_conectar" => 'Conectar', - "msg_sis" => 'Sistema de Atendimento', "motivo_pausa" => '', "use_lassifica" => '0', "value_bt_pausa" => "Entrar", - "use_proto" => "1", "habilitaConectar" => 0, "habilita_pausa" => 0, "disab_modo_atend" => "", "modu_auto" => '', - "modu_manual" => 'checked="checked"', "hora_atu" => '-', "apelido" => "", "ufs" => '', - "modo_auto_permite" => '0', "modo_manu_permite" => '1', "pausa_detalhes" => "", "lst_pesquisa" => "", "exige_clas", 'prm_cadastro_atendidos' => 'Clientes', - "habilitaDiscador" => '0'); - -$dadosDiscador = array('cmpo_id' => '0', 'cmp_id' => '0', 'list_id' => '0', 'cont_id' => '', 'conf_id' => '', 'cmp_descricao' => '', 'list_nome' => '-', 'cont_identificador' => '-', - 'cont_param1' => '-', 'cont_param2' => '-', 'cont_param3' => '-', 'cont_param4' => '-', 'cont_param5' => '-', - 'disp_param1' => '-', 'disp_param2' => '-', 'disp_param3' => '-', 'disp_param4' => '-', 'disp_param5' => '-', - 'conf_fone' => '', 'lista_fones_discador' => '', 'matricula' => '', 'cmpo_status' => '-1', 'carrega_fone' => '1', 'discagem_inicial' => '1'); - -/* - * Funcoes especificas do agente - */ -require("agente/funcoesAgente.php"); -include("util/funcoesSsupervisor.php"); -include("util/sharedMem.php"); -/* - * Define mensagens para o usuário. - */ -$vl_msgAgente = ''; -$wAlineMaster = "center"; -$tpLayout = AgenteNovaJanela(); //Indica o template para esata pagina - - -$styleAdd = ''; -$sZw = '170px'; -$sZh = '26px'; -$sZHeadTh = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '75px', $sZh, $styleAdd); - -//Dac Pausa -$styleAdd = "border:1px solid #bbb;background-color: #eee;"; -$sZlistaDacs = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '60%', $sZh, $styleAdd); -$sZbtConDac = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '35%', $sZh, $styleAdd); -$sZlistaMotivo = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '72%', $sZh, $styleAdd); -$sZbtPausa = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '23%', $sZh, $styleAdd); - - -$sZw = '100%'; -// Classificacao. -$styleAdd = "border:1px solid #bbb;background-color: #eee;"; -$sZtxtCliente = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '80%', $sZh, $styleAdd); -$sZbtCliente = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '16%', $sZh, $styleAdd); -$sZlistaClas = sprintf("width: %s;height: %s;padding:0;margin:0;%s", $sZw, $sZh, $styleAdd); -$sZlistaClasItem = sprintf("width: %s;height: %s;padding:0;margin:0;%s", $sZw, $sZh, $styleAdd); -$sZbt_classifica = sprintf("width: %s;height: %s;padding:0;margin:0;%s", UseModVendas() ? '80%' : '100%', $sZh, $styleAdd); - -// Pesquisa -$sZw = '170px'; -$sZlst_pesquisa = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '80%', $sZh, $styleAdd); -$sZbtPesquisa = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '16%', $sZh, $styleAdd); - -// Discagem -$sZtxtDiscar = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '47%', $sZh, $styleAdd); -$sZbtLigar = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '20%', $sZh, $styleAdd); -$sZbtDesligar = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '20%', $sZh, $styleAdd); -$sZListaFones = sprintf("width: %s;height: %s;padding:0;margin:0;%sdisplay: none", '47%', $sZh, $styleAdd); -$sZbtIncluiFoneDiscador = sprintf("width: %s;height: %s;padding:0;margin:0;%sdisplay: none", '10%', $sZh, $styleAdd); - -// Discador -$sZListaStatus = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '90%', $sZh, $styleAdd); -$sZbtRegStatus = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '42%', $sZh, $styleAdd); -$sZbtEncerraLibera = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '43%', $sZh, $styleAdd); -$sZbtEncerra = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '43%', $sZh, $styleAdd); -$sZinfContatosRestantes = sprintf("width: %s;height: %s;padding:0;margin:0;%stext-align:center;font-weight: bold", '30%', $sZh, $styleAdd); - -$styleAdd = "border:0"; -$sZcmp_descricao = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '99%', $sZh, $styleAdd); -$sZcont_identificador = sprintf("width: %s;height: %s;padding:0;margin:0;%s", '99%', $sZh, $styleAdd); - -$sZw = '100%'; -$sZh = '50px'; -$styleAdd = ''; -$sZmsg_discador = sprintf("width: %s;height: %s;padding:0;margin:0;%s", $sZw, $sZh, $styleAdd); - -/* - * Ativa log ami. - */ -$debugAmi = true; // true para ativar. - -/* - * Informações sobre alerta para agente que ainda não classificou o chamado. - */ -$alertaAgente = array(); - - -$matricula = GetMatricula(); -$clasAtende = ''; -//$dac = IsPostBack() ? (AgenteON() ? $_SESSION[SS_DAC_CODIGO] : $_POST["listaDacs"] ) : ( AgenteON() ? $_SESSION[SS_DAC_CODIGO] : (isset($_GET["dac"]) ? $_GET["dac"] : GetIdDacPadrao($dbcon, $_SESSION["SSidUser"])) ); - -if (AgenteON()) { - $dac = $_SESSION[SS_DAC_CODIGO]; -} else if (IsPostBack()) { - $dac = isset($_POST["listaDacs"]) ? $_POST["listaDacs"] : ''; - $_SESSION[SS_DAC_CODIGO] = $dac; -} else if (isset($_GET["dac"])) { - $dac = $_GET["dac"]; -} else { - $dac = GetIdDacPadrao($dbcon, GetIdUser()); - $_SESSION[SS_DAC_PADRAO_ID] = $dac; -} - -if (!$dac) { - $dac = SetIdDacPadrao($dbcon, GetIdUser()); - $_SESSION[SS_DAC_CODIGO] = $dac; -} - -$ufForm = ""; //IsPostBack() ? $_POST["listaUfs"] : ""; -/* - * Mostra erros na aplicação - */ -$displayError = 0; -//$heightMasterContent = 265; - - -if (!IsAjax()) { - $footerDisplay = 0; - $useAguarde = 0; - $tplAgente = 'callcenter/agente/agentert.tpl'; - $cssBlock = ""; - - if (IsPostBack()) { - $tpAtende = isset($_POST["modoAtendimento"]) ? $_POST["modoAtendimento"] : $_SESSION[SS_MODO_ATENDIMENTO_COD]; - - if (ConectarDac()) { - if (!$dac) { - SetMsgAgente("Selecione um DAC!"); - $jsStartup[] = "alert('Selecione um DAC!')"; - } else { - if (AgenteON()) - DesConectaAgenteRt($dbcon); - ConnectaAgenteRt($dbcon, $dac, $tpAtende); - } - } - else if (DesconectarDac()) { - DesConectaAgenteRt($dbcon); - /* - $jaConnectado = strtoupper($_POST["btConDac"]) == 'CONECTAR'; - if($jaConnectado) - { - $msg = "Este usuário já esta conectado!"; - $jsStartup[] = sprintf("alert('%s');", $msg); - SetMsgAgente($msg); - } - else - { - DesConectaAgenteRt($dbcon); - } */ - } else if (SairDePausa()) { - SairPausa($dbcon); - } else if (EntrarPausa()) { - if (!isset($_POST["listaMotivo"]) || !$_POST["listaMotivo"]) { - $dadosMonitorCompl["msg_sis"] = "Selecione uma Pausa!"; - $jsStartup[] = "alert('Selecione uma Pausa!')"; - } else if (VerificaMaxAgentePausa($dac)) { - $dadosMonitorCompl["msg_sis"] = "Número Máximo de Agente/Pausa Excedido, Aguarde!"; - $jsStartup[] = "alert('Número Máximo de Agente/Pausa Excedido, Aguarde!')"; - } else { - $codMotivo = explode('|', $_POST["listaMotivo"]); - EntraPausa($dbcon, $codMotivo[0]); - } - } - DadosAtualiza($dbcon); - $_SESSION[RAMAL_DESTINO] = GetAnotacoesKey() ? $dadosMonitor["fone"] : $dadosMonitor["num_protocolo"]; - } else { - /* - * Chamada get na inicializacao - */ - $_SESSION[SS_STATUS_AGENTE] = "OFF"; - - $ramalTmp = trim(GetRamalMonitorar(RAMAL_MONITOR_AGENTE)); - if (!$ramalTmp) { - $_SESSION['SSconfRamal'] = 1; - $jsStartup[] = sprintf("RegistraRamalMonitorApl('99','%s','%s');", RAMAL_MONITOR_AGENTE, CANAL_MONITOR_AGENTE); - } - } - /* - * Inicializacao do sistema - */ - if (AgenteON()) { - DadosAtualiza($dbcon); - - if ($_SESSION[SS_PRM_AGENTE_CLASSIFICA]) { - $clasAtende = CarregaClassificacao($dbcon, $dac); - } - } - - $jsStartup[] = "window.setInterval(\"GetAgenteRt()\", " . GetTempoAgente() . ");"; - $jsStartup[] = "window.setInterval(\"SetDataAtual()\", 1000);"; - - // $jsJQuery[] = "\$(document).bind(\"keydown keypress\", function (event) { if (event.which == 116 || event.which == 8) { return false; }});"; - $jsJQuery[] = "\$(document).bind(\"keydown keypress\", function (event) { if (!ativaBackspace && (event.which == 8)) { return false; }});"; - $jsJQuery[] = "\$('#txtDiscar').focus(function(){ ativaBackspace = true; }) "; - $jsJQuery[] = "\$('#txtDiscar').blur(function(){ ativaBackspace = false; }) "; - $jsJQuery[] = "\$('#msg_discador').focus(function(){ ativaBackspace = true; }) "; - $jsJQuery[] = "\$('#msg_discador').blur(function(){ ativaBackspace = false; }) "; - if ($tpLayout) { - $jsJQuery[] = " \$('#contentAgente').height($(document).height());"; - $jsJQuery[] = "\$(window).resize( function(){ ResizeAgente(); } ); "; - } - //$jsJQuery[] = "\$(document).ajaxStart(function(){\$('#loading').show();}).ajaxStop(function(){\$('#loading').hide();});"; - - if ($clasAtende) { - $GLOBALS["jsStartup"][] = $clasAtende; - } - //$GLOBALS["jsStartup"][] = "\$(window).bind('beforeunload', function() { return SaidaPausaLogoffRt();});"; - $useContribuinte = $_SESSION[SS_PRM_AGENTE_CONTRIBUINTE]; - $useClassificacao = $_SESSION[SS_PRM_AGENTE_CLASSIFICA]; - $dadosMonitorCompl["habilitaConectar"] = true; - $dadosMonitorCompl["dacs"] = GetDac($dbcon, $dac, AgenteON() ? "disabled=\"disabled\"" : "", 0, 1, 0, 0, 1); - $dadosMonitorCompl["motivo_pausa"] = GetMotivo($dbcon, AgenteON() ? $_SESSION[SS_PAUSA_AGENTE_MOTIVO] : 0, DisablePausa(), true, 1); - $dadosMonitorCompl["value_bt_pausa"] = AgentePausa() ? "Sair" : "Entrar"; - $dadosMonitorCompl["habilita_pausa"] = AgenteON(); - $dadosMonitorCompl["use_proto"] = $_SESSION[SS_PRM_AGENTE_PROTO]; - $dadosMonitorCompl["use_contrib"] = $useContribuinte; - $dadosMonitorCompl["use_classifica"] = $useClassificacao; - $dadosMonitorCompl["classifica"] = GetHtmlSelect("listaClas", $useClassificacao ? '' : 'Desabilitado', "style=\"$sZlistaClas\" onchange=\"GetAgtClasItem(this.value);\"", $useClassificacao ? 0 : 1); - $dadosMonitorCompl["clas_item"] = GetHtmlSelect("listaClasItem", '', "style=\"$sZlistaClasItem\""); - $dadosMonitorCompl["value_bt_conectar"] = AgenteON() ? "Desconectar" : "Conectar"; - $dadosMonitor["status_agente"] = AgenteON() ? $_SESSION[SS_STATUS_AGENTE] : 'OFF'; - $dadosMonitor["ramal_monitor"] = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $dadosMonitorCompl["modu_auto"] = (($_SESSION[SS_MODO_ATENDIMENTO_COD] == '**60') ) ? 'checked="checked"' : ""; - $dadosMonitorCompl["modu_manual"] = (($_SESSION[SS_MODO_ATENDIMENTO_COD] == '**50')) ? 'checked="checked"' : ""; - $dadosMonitorCompl["disab_modo_atend"] = AgenteON() ? "disabled=\"disabled\"" : ""; - $dadosMonitorCompl["hora_atu"] = date("H:i:s"); - $dadosMonitor["matricula"] = GetMatricula(); - $dadosMonitorCompl["apelido"] = GetLogin(); - $dadosMonitorCompl["ufs"] = AgenteON() ? GetUfs($dbcon, $ufForm) : GetHtmlSelect("", "---------------", "", 1); - $dadosMonitorCompl["modo_auto_permite"] = GetPermitAtendAuto(); - $dadosMonitorCompl["modo_manu_permite"] = GetPermitAtendManual(); - $dadosMonitor["disponivelFila"] = GetDisponivelFila(); - $dadosMonitorCompl["lst_pesquisa"] = AgenteON() ? GetPesquisaDisponivel($dbcon, $dac) : GetHtmlSelect("", "---------------", "", 1); - $dadosMonitorCompl["exige_clas"] = GetExigeClas(); - $dadosMonitor["chamada_classificado_txt"] = GetExigeClassStatusTxt($dadosMonitor["chamada_classificado"]); - $dadosMonitor["chamada_classificado_exige"] = GetExigeClas() ? 1 : 0; - $dadosMonitor["prm_obs_pausaprod"] = GetObsProdAgente(); - $dadosMonitorCompl["exibePesquisa"] = ExibePesquisa(); - $dadosMonitorCompl["prm_cadastro_atendidos"] = GetNomeCadCli(); - $dadosMonitor["dac_logado"] = isset($_SESSION[SS_DAC_DESCRICAO]) ? $_SESSION[SS_DAC_DESCRICAO] : ''; - $dadosMonitor["abandonadasRet"] = !AgenteON() ? '0' : RetornaAbandon($dbcon, $dadosMonitor["dac_logado"], GetRamalMonitorar(RAMAL_MONITOR_AGENTE), '', '', $dadosMonitor["abandonadasRet"]); - $var = $dadosMonitor["abandonadasRet"]; - $dadosMonitorCompl["msg_sis"] = GetMsgAgente(); - $dadosMonitorCompl["habilitaDiscador"] = HabilitaDiscador(); - - $imgPausa = 'Pausas'; - $dadosMonitorCompl["pausa_detalhes"] = sprintf("%s", GetMatricula(), $imgPausa); - - GetMunOrigem($dadosMonitor); - - $arTemp = array_merge($dadosMonitor, $dadosMonitorCompl); - - foreach ($arTemp as $key => $value) { - $smarty->assign($key, $value); - } - - $ListaStatus = isset($_REQUEST['ListaStatus']) ? $_REQUEST['ListaStatus'] : '0'; - $smarty->assign('nomeRamalMonitor', RAMAL_MONITOR_AGENTE); - $smarty->assign('canalRamallMonitor', CANAL_MONITOR_AGENTE); - $smarty->assign('ListaStatus', AgenteON() ? GetStatusDiscador($ListaStatus) : ''); - $smarty->assign('sZtxtCliente', $sZtxtCliente); - $smarty->assign('sZbtCliente', $sZbtCliente); - $smarty->assign('sZlst_pesquisa', $sZlst_pesquisa); - $smarty->assign('sZbtPesquisa', $sZbtPesquisa); - $smarty->assign('sZbtConDac', $sZbtConDac); - $smarty->assign('sZListaFones', $sZListaFones); - // $smarty->assign('sZbtDiscador',$sZbtDiscador); - $smarty->assign('sZListaStatus', $sZListaStatus); - $smarty->assign('sZbtRegStatus', $sZbtRegStatus); - $smarty->assign('sZbtPausa', $sZbtPausa); - $smarty->assign('sZtxtDiscar', $sZtxtDiscar); - $smarty->assign('sZtxtDiscar', $sZtxtDiscar); - $smarty->assign('sZbtLigar', $sZbtLigar); - $smarty->assign('sZbtDesligar', $sZbtDesligar); - $smarty->assign('sZbt_classifica', $sZbt_classifica); - $smarty->assign('sZbtIncluiFoneDiscador', $sZbtIncluiFoneDiscador); - $smarty->assign('sZHeadTh', $sZHeadTh); - $smarty->assign('sZmsg_discador', $sZmsg_discador); - $smarty->assign('sZbtEncerraLibera', $sZbtEncerraLibera); - $smarty->assign('sZbtEncerra', $sZbtEncerra); - $smarty->assign('sZcont_identificador', $sZcont_identificador); - $smarty->assign('sZcmp_descricao', $sZcmp_descricao); - $smarty->assign('sZinfContatosRestantes', $sZinfContatosRestantes); - $smarty->assign('janH', $_REQUEST['janH']); - $smarty->assign('tpLayout', $tpLayout); - $smarty->assign('versao', GetVersao()); - $smarty->assign('labelProtocolo', $_SESSION['prm_label_protoco_pesquisa']); - $smarty->assign("prm_label_protoco_texto", $_SESSION['prm_label_protoco_texto']); - $smarty->assign('useModVendas', UseModVendas()); - $smarty->assign('exigeProtoExt', (ExigeProtoVendas() ? '1' : '0')); - $smarty->assign('vendido', GetVendasAgente($dac, $matricula)); - $smarty->assign('ativa_integracao', GetAtivaIntegracao()); - $smarty->assign('linkaudio', '...'); - - $clienteOperacao = GetClientOperacao($matricula)['cont_identificador']; - if ($clienteOperacao) { - $smarty->assign('clienteoperacao', sprintf("\"Ir", $clienteOperacao)); - } - - - /* - $dados = RetornaAbandon($dbcon); - $linkAbandonadas = !$dados ? $dados : sprintf("abandonadasRet%s", $dados); - $smarty->assign('abandonadasRet',$linkAbandonadas); - * - */ - GetTemplate($smarty, $tplAgente); -} else { - /* - * Chamadas em Ajax para atualizar Interface. - */ - $acao = $_GET["acao"]; - - $audioFone = isset($_GET['audioFone']) ? $_GET['audioFone'] : ''; - - if ($audioFone) { - echo ClassificacaoAudioEscuta($audioFone); - exit(); - } - - if ($acao == 'avisodesconnect') { - DesConectaAgenteRt($dbcon, 'DESCONNECT'); - exit; - } - - if ($acao == 'atualiza') { - $dadosMonitor["pausa_motivo_ausente"] = 0; - $dadosMonitor["dac_padrao"] = $_SESSION["SS_ultimo_dac_agente"] ? $_SESSION["SS_ultimo_dac_agente"] : $_SESSION[SS_DAC_PADRAO_ID]; - - /* - * O agente deslogou ou foi desconectado. - */ - if (!GetStatusAgente()) { - $dadosMonitor["ramal_monitor"] = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $dadosMonitor["tempo_logado"] = '00:00:00'; - $dadosMonitor["matricula"] = GetMatricula(); - $dadosMonitor["abandonadasRet"] = '0'; - $dadosMonitor["status_agente"] = "OFF"; - $dadosMonitor = array_merge($dadosMonitor, $dadosDiscador); - echo FormataDadosRt($dadosMonitor); - } else { - $oldStatus = $_SESSION[SS_STATUS_AGENTE]; - DadosAtualiza($dbcon); - $chamadaValida = trim($dadosMonitor["uniqueid2"]); - $statusAtual = $dadosMonitor["status_agente"]; - // - // Limpa link de audio. - // - if (($oldStatus != $statusAtual) && ($statusAtual == 'CHAMANDO')) { - $dadosMonitor["linkaudio"] = "..."; - } - - if ($statusServer) - $dadosMonitor["tempo_logado"] = sprintf('%s', $dadosMonitor["tempo_logado"]); - - $dadosMonitor["dac_logado"] = $_SESSION[SS_DAC_DESCRICAO]; - $_SESSION[SS_STATUS_AGENTE] = $dadosMonitor["status_agente"] ? $dadosMonitor["status_agente"] : "OFF"; - $statusAtual = $dadosMonitor["status_agente"]; - if (($oldStatus != $statusAtual) && ($statusAtual == 'OCUPADO')) { - SetaClassificaChamado($dbcon, 0, 0); - // - // Cria um link para audio. - // - $dadosMonitor["linkaudio"] = sprintf("http://%s/ad/?%s", GetLinkAudio(), base64_encode($dadosMonitor["uniqueid2"])); - } - $dadosMonitor["chamada_classificado_txt"] = GetExigeClassStatusTxt($dadosMonitor["chamada_classificado"]); - $dadosMonitor["chamada_classificado_exige"] = GetExigeClas() ? 1 : 0; - $dadosMonitor["prm_obs_pausaprod"] = GetObsProdAgente(); - $_SESSION[RAMAL_DESTINO] = GetAnotacoesKey() ? $dadosMonitor["fone"] : $dadosMonitor["num_protocolo"]; - - $clienteOperacao = GetClientOperacao($matricula)['cont_identificador']; - if ($clienteOperacao) { - $dadosMonitor['clienteoperacao'] = sprintf("\"Ir", $clienteOperacao); - } - - // - // ALERTA CLASSIFICACAO: INICIO - // - - // - // ALERTA CLASSIFICACAO: INICIO - // - /* - * Controla alerta sonoro para agente quando o chamado não é classificado. - */ - - $exigeClass = $dadosMonitor["chamada_classificado_exige"]; - $naoClass = $dadosMonitor["chamada_classificado"]; - $startAlert = ($statusAtual == 'LIVRE'); - - if (($oldStatus != $statusAtual) && ($statusAtual == 'LIVRE')) { - SetAlertTempo(false); - SetAlertAgente(false); - } - - - if ($chamadaValida && $exigeClass && !$naoClass && $startAlert && !GetAlertAgente()) { - SetAlertAgente(true); - SetAlertTempo(time()); - } - - $alertTEmpo = GetAlertTempo(); - - $alerta = (GetAlertTempo() !== false) && ((time() - GetAlertTempo())) > GetTempoAlertClas(); - if (!$naoClass && GetAlertAgente() && $alerta && $startAlert) { - GetUrl(AST_ALERTA_AGENTE); - SetAlertAgente(false); - SetAlertTempo(false); - } - - /* - * Controla alerta sonoro para agente quando o chamado não é classificado. - - $exigeClass = $dadosMonitor["chamada_classificado_exige"]; - $statusLivre = ($statusAtual == 'LIVRE'); - if ($chamadaValida && (GetAlertOcupado() === false) && ($statusAtual == 'OCUPADO')) { - SetAlertOcupado(true); - SetAlertAgente(false); - SetAlertTempo(false); - } - $naoClass = $dadosMonitor["chamada_classificado"]; - - - if ($chamadaValida && $exigeClass && $statusLivre && !$naoClass && !GetAlertAgente() && GetAlertOcupado()) { - SetAlertAgente(true); - SetAlertTempo(time()); - } - - - $alerta = (GetAlertTempo() !== false) && ((time() - GetAlertTempo())) > GetTempoAlertClas(); - if ($chamadaValida && $statusLivre && GetAlertAgente() && !$naoClass && $alerta && GetAlertOcupado()) { - GetUrl(AST_ALERTA_AGENTE); - SetAlertAgente(false); - SetAlertTempo(false); - } - */ - if (($_SESSION[SS_STATUS_AGENTE] != 'OCUPADO') && ($_SESSION[SS_STATUS_AGENTE] != 'ORIGINANDO')) { - $dadosMonitor["duracao"] = '00:00:00'; - } - if (($_SESSION[SS_STATUS_AGENTE] != 'OCUPADO') || ($_SESSION[SS_STATUS_AGENTE] != 'CHAMANDO')) { - $_SESSION["txt_cliente"] = ""; - } - if (($_SESSION[SS_STATUS_AGENTE] != 'PAUSA')) { - $_SESSION[SS_PAUSA_AGENTE] = 0; - } else { - $nomePausa = $dadosMonitor["pausa_motivo_rt"]; - if (strtoupper($nomePausa) == 'AUSENTE') { - /* - * Pausa ausente é setada pela central toda vez que o agente não atende a uma chamada. - */ - $dadosMonitor["pausa_motivo_ausente"] = 1; - } else if (strtoupper($nomePausa) == 'RECUSADA') { - $dadosMonitor["pausa_motivo_ausente"] = 2; - } - } - - /* - * Ajusta o status dispnivel_atendimento com base na variavel de sessao SS_CK_DISPO, que tem seu valor modificado - * na funçao DisponivelAtendimento(). - */ - if ($_SESSION["SS_CK_DISPO"] && !$dadosMonitor["disponivel_atendimento"]) { - $dadosMonitor["disponivel_atendimento"] = 1; - } - $dadosMonitor["fone"] = ocultarTelefone($dadosMonitor["fone"]); - $pref = ''; - //GetMunOrigem($dadosMonitor); - $statusAgente = trim($_SESSION[SS_STATUS_AGENTE]); - $dadosFone = trim($dadosMonitor["fone"]); - $txtCliente = trim($_SESSION["txt_cliente"]); - $statusDiscador = $dadosMonitor["status_discador"]; - $dispIntegracao = false; - if (!$statusDiscador) { - $dadosIntegracao = GetDadosIntegracao($dadosMonitor["cont_identificador"]); //dado alimento pelo agente_fila com orgem na tabela pbx_integracao_reg - $dispIntegracao = $dadosIntegracao !== false; - if ($dispIntegracao) { - $dadosMonitor = array_merge($dadosMonitor, $dadosIntegracao); - } - - if (($dadosFone != "") && (($statusAgente === 'OCUPADO') || ($statusAgente === 'CHAMANDO') ) && (!$dispIntegracao)) { - $cliente = GetClienteClassifica($dbcon, $dadosFone); - $dadosMonitor["txt_cliente"] = $cliente; - $_SESSION["txt_cliente"] = trim($dadosMonitor["txt_cliente"]); - } - } - $dadosMonitor["abandonadasRet"] = RetornaAbandon($dbcon, $dadosMonitor["dac_logado"], GetRamalMonitorar(RAMAL_MONITOR_AGENTE), "", "", $dadosMonitor["abandonadasRet"]); - - - /* - * $dispIntegracao -> Indica que dados obtidos de uma integração serão mostrados no campo do discador. - */ - if (!$dispIntegracao) { - $dadosMonitor['disp_param0'] = 'Identificador'; - /* - * Verifica se existe uma campanha ativa para o dac/agente. - */ - $dadosDiscador__ = GetDadosDiscador($dac, 0); - $idCampanha = GetCampanhaDiscador($dac); - if ($statusDiscador) { - $idCampanha = GetCampanhaDiscador($dac); - if ($idCampanha !== false) { - $dadosDiscador__ = GetDadosDiscador($dac, $idCampanha); - } - } - $ContatosRestantes = 0; - if ($dadosDiscador__ !== false) { - $dadosDiscador = $dadosDiscador__; - } - - if (HabilitaDiscador()) { - $infoContatos = GetDiscadorRestantes($dac, $matricula, $idCampanha); - $dadosMonitor['quantidade_contatos'] = $infoContatos['quantidade_contatos']; - $dadosMonitor['quantidade_discados'] = $infoContatos['quantidade_discados']; - $dadosMonitor['contatos_restantes'] = $infoContatos['contatos_restantes']; - $dadosMonitor = array_merge($dadosMonitor, $dadosDiscador); - } - } - - if (!$dadosMonitor['tma']) - $dadosMonitor['tma'] = '0'; - if (!$dadosMonitor['tme']) - $dadosMonitor['tme'] = '0'; - $dadosMonitor['vendido'] = !UseModVendas() ? '0' : GetVendasAgente($dac, $matricula); - - - echo FormataDadosRt($dadosMonitor); - - //if($dadosMonitor["tempo_atualiza"] >= 30){ UpdateLogoffRt($dbcon); } - UpdateLogoffRt($dbcon); - } - } - else { - /* - * Tratamento de ações invocadas pelo agente. - */ - $obStart = ob_start(); - $obClean = ob_clean(); - - if ($acao == 'classifica') { - SetAlertOcupado(false); - SetAlertAgente(false); - SetAlertTempo(false); - ClassificaChamada($dbcon); - } else if ($acao == 'discar') { - $acaoDiscar = $_GET["acaoDiscar"]; - if ($acaoDiscar == 2) { - IniciaTransferenciaConsultaRt(); - } else { - AgtCallRt($dbcon); - } - } else if ($acao == 'pesquisa') { - TransfPesquisa($dbcon); - } else if ($acao == 'finalizar') { - FinalizaTransferenciaConsultaRt(); - } else if ($acao == 'dispAtendimento') { - DisponivelAtendimento(); - } else if ($acao == 'liberaDiscador') { - LiberaDiscador($dbcon); - } else if ($acao == 'dispDiscador') { - AtivaDiscador($dbcon); - } else if ($acao == 'incluiDiscador') { - IncluiDiscador($dbcon); - } else if ($acao == 'statusFoneDiscador') { - StatusFoneDiscador($dbcon); - } else if ($acao == 'operaDiscador') { - FuncoesOperacao(); - } else if ($acao == 'protoExterno') { - GravaProtocoloExterno(); - } else if ($acao == 'integracao' && GetStatusAgente() && GetAtivaIntegracao()) { - RealizaConsultaIntegracao(); - } - } - /* - * Fim área comum das ações. - */ - ob_flush(); - exit; -} - -function TransfPesquisa($db) { - $plId = $_GET["plId"]; - $numeroTransf = "psq-" . $plId . "-ini"; - $matricula = GetMatricula(); - $_SESSION[AGT_NUM_DISC] = $numeroTransf; - $idProgPesquisa = __GetIdProgPesquisa(); - $GLOBALS["PESQUISA_MATRICULA"] = $matricula; - try { - /* - * Pega o canal do agente - */ - $query = "select canal, uniqueid, dac from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - if (!$result || !pg_num_rows($result)) { - GeraExcept("Não foi possível obter informações da chamada!"); - } - - $row = @pg_fetch_row($result); - $canal = $row[0]; - $uid = $row[1]; - $dac = $row[2]; - - /* - * Registra que o agente clicou em transferir a pesquisa - */ - GravaFull($idProgPesquisa, $uid, 'O agente clicou em transferir pesquisa!'); - if (!$canal) { - GeraExcept("Não foi possível recuperar o canal para realizar a transferencia!"); - } - $_SESSION[AGT_CHANNEL_TRANSF] = $canal; - - - if (!GetUrl(AST_TRANSF_PESQUISA)) { - GeraExcept("Não foi possível realizar a transferencia!"); - } - - $sql = sprintf("INSERT INTO pbx_pesquisa_log (uniqueid, id_dac, fila, matricula, pl_id, plog_log) VALUES (%s, %s, %s, %s, %s, %s);", QuotedStr($uid), QuotedStr(GetDacCod($db, $dac)), QuotedStr($dac), QuotedStr($matricula), QuotedStr($plId), QuotedStr('MANUAL')); - $rst = pg_query($db, $sql); - - if (!$rst) { - GeraExcept("Não foi possível registrar o envio para a pesquisa!"); - } - - /* - * Transferencia realizada com sucesso limpa o status do agente. - */ - $query = "update pbx_supervisor_agentes - set status = 'LIVRE', - protocolo = '', - origem_destino = '', - duracao = now(), - canal = '', - canal_agente = '', - canal_transfer = '', - uniqueid = '' - where matricula = '$matricula'"; - pg_query($db, $query); - - /* - * Notifica o agente que a chamada foi encaminhada para a pesquisa com sucesso. - */ - echo "OK;Transferência realizada com sucesso!"; - } catch (Exception $exc) { - - echo "ERRO;" . $exc->getMessage(); - /* - * Registra erro ao tentar tranferir a pesquisa. - */ - if (!$uid) { - RegistroInc(false, "select uniqueid from pbx_supervisor_agentes where matricula = '$matricula'"); - } - GravaFull($idProgPesquisa, $uid, $exc->getMessage()); - } -} - -function __GetIdProgPesquisa() { - return RegistroInc(false, "select id_prog from pbx_funcoes_internas where arquivo like '%pesquisa.php'"); -} - -function FechaRegistroDiscaor($db) { - try { - $matricula = GetMatricula(); - /* - * Libera o registro para nova discagem. - */ - $query = sprintf("update pbx_campanha_operacao set cmpo_status = 1 where cmpo_status = 2 and matricula = %s", QuotedStr($matricula)); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Erro ao alterar o status da operação!"); - }; - - return true; - } catch (Exception $ex) { - RegistraLogAgente("FechaRegistroDiscaor", $ex->getMessage(), $ex); - return false; - } -} - -function GetPendenciaDiscador($db, $silent = false) { - - $matricula = GetMatricula(); - $query = "select count(*) as num_reg - from pbx_campanha_contato_fone a, pbx_campanha_operacao b - where b.cont_id = a.cont_id - and b.matricula = '$matricula' - and b.cmpo_status in(0, 2) - and a.conf_discado = 1 - and a.conf_status = '0'"; - if (RegistroInc($db, $query)) { - if ($silent) { - return true; - } - GeraExcept("Para realizar esta operação é necessário informar um status para o contato discado!"); - } - - return false; -} - -function AtivoDiscador($db) { - $matricula = GetMatricula(); - $query = "select status_discador from pbx_supervisor_agentes where matricula = '$matricula'"; - return RegistroInc($db, $query); -} - -function LiberaDiscador($db) { - global $dac; - $liberar = $_REQUEST['liberar']; - $msg = $_REQUEST['msg']; - $status = $_REQUEST['status']; - $confId = $_REQUEST['conf_id']; - $contId = $_REQUEST['cont_id']; - $inTran = 0; - $matricula = GetMatricula(); - $uid = trim($_REQUEST['uniqueid']); - $uid = $uid ? QuotedStr($uid) : 'null'; - try { - if ((GetDadosDiscador($dac, 0) === false)) { - GeraExcept("ERRO;Não há atendimento pendente!"); - } - /* - * se a classificação ogrigatória estiver configurada, - * garante que o discador não será liberado até que a - * chamada seja classificada. - - if(GetExigeClas()) - { - $liberar = 0; - } - */ - - if ($_SESSION[SS_STATUS_AGENTE] == 'OCUPADO') { - GeraExcept("ERRO; Não é possível encerrar o atendimento quando \"Ocupado\"!"); - }; - if (GetExigeClas() && !ChamdaClassificadaAgente($db, $matricula)) { - GeraExcept("ERRO;Para gravar o atendimento a chamda deve estar classificada!"); - } - - $result = pg_query($db, 'begin'); - if (!$result) { - GeraExcept("ERRO;Não foi iniciar uma transação!"); - } - $inTran = 1; - - $query = "update pbx_supervisor_agentes set status_discador = '1' where matricula = '$matricula'"; - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Erro ao liberar o agente!"); - }; - - /* - * Marca o telefone com o ultimo staus - */ - // "update pbx_campanha_contato_fone set conf_status = %s, conf_agente_matricula = %s, conf_uid = %s where conf_id = %s"; - $query = "update pbx_campanha_contato_fone set conf_discado = %s, conf_status = %s, conf_agente_matricula = %s, conf_uid = %s where conf_id = %s"; - - $query = sprintf($query, QuotedStr($liberar), QuotedStr($status), QuotedStr($matricula), $uid, QuotedStr($confId)); - $result = pg_query($db, $query); - if (!$result || !pg_affected_rows($result)) { - GeraExcept("ERRO;Não foi possível atualizar o número informado!"); - } - - /* - * Marca o contato da lista com discado. - */ - $query = sprintf("update pbx_campanha_contato set cont_discado = 1, cont_status = %s, cont_fechamento = now(), cont_msg = %s where cont_id = %s", QuotedStr($status), QuotedStr($msg), QuotedStr($contId)); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Erro ao alterar o contato do número discado!"); - }; - - /* - * Libera o registro para nova discagem. - */ - GetContidClient($contId, $uid); - $query = sprintf("update pbx_campanha_operacao set cmpo_status = %s, cmpo_fim = now() where cont_id = %s and cmpo_status in(0,2) and matricula = %s", QuotedStr($liberar ? '1' : '2'), QuotedStr($contId), QuotedStr($matricula)); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Erro ao alterar o status da operação! Query: " . $query); - }; - - -// if (!$liberar) { -// if (GetDispoDiscador()) { -// DisponivelAtendimento(); -// SetDispoDiscador(false); -// } -// } - - $result = pg_query($db, 'commit'); - if (!$result) { - GeraExcept("ERRO;Não foi finalizar a transação!"); - } - - echo sprintf("OK;Liberação executada com sucesso!;%s", ($liberar ? 'S' : 'N')); - } catch (Exception $ex) { - RegistraLogAgente("LiberaDiscador", $ex->getMessage(), $ex); - if ($inTran) { - pg_query($db, 'rollback'); - } - echo $ex->getMessage(); - } -} - -function AtivaDiscador($db) { - global $dac; - try { - $dispo = $_REQUEST['dispo']; - $matricula = GetMatricula(); - - - if (!AgenteON()) { - GeraExcept("ERRO;Para ativar o discador o agente deve estar conectado!"); - } - - FechaRegistroDiscaor($db); - - if ((GetDadosDiscador($dac, 0) !== false)) { - GeraExcept("ERRO;Para desativar o discador é necessario encerrar o atendimento!"); - } - - if ($dispo && !AgenteLivre()) { - GeraExcept("ERRO;Para ativar o discador o agente deve estar com status \"LIVRE\"!"); - } - - if ($dispo && GetExigeClas() && !ChamdaClassificadaAgente($db, $matricula)) { - GeraExcept("ERRO;Para ativar o discador a chamada deve ser classificada!"); - } - - $inTran = 0; - $result = pg_query($db, 'begin'); - if (!$result) { - GeraExcept("ERRO;Não foi possível iniciar a transação!"); - } - $inTran = 1; - - - - $query = "update pbx_supervisor_agentes set status_discador = '$dispo', cont_identificador = '' where matricula = '$matricula'"; - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Não foi possível realizar a operação!"); - } - - if ($dispo && GetAgenteDisponivelFila()) { - DisponivelAtendimento(0); - SetDispoDiscador(true); - } else if (GetDispoDiscador()) { - DisponivelAtendimento(0); - SetDispoDiscador(false); - } - - $result = pg_query($db, 'commit'); - if (!$result) { - GeraExcept("ERRO;Não foi possível finalizar a transação!"); - } - - echo "OK;Operação realizada com sucesso!"; - } catch (Exception $ex) { - RegistraLogAgente("AtivaDiscador", $ex->getMessage(), $ex); - echo $ex->getMessage(); - } -} - -function IncluiDiscador($db) { - try { - global $dadosMonitor, $dac; - $inTran = 0; - $numero = soNumero($_REQUEST['numero']); - $matricula = GetMatricula(); - $dadosDiscador = GetDadosDiscador($dac, 0); - if ($dadosDiscador === false) { - GeraExcept('ERRO@Não foi possível acessar os dados da campanha'); - } - - $result = pg_query($db, 'begin'); - if (!$result) { - GeraExcept('ERRO@Não foi possível iniciar uma transação!'); - } - $inTran = 1; - - /* - * Verifica se o telefone já existe na base. - */ - $query = sprintf("select '' from pbx_campanha_contato_fone where cont_id = '%s' and conf_fone = '%s'", $dadosDiscador['cont_id'], $numero); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept('ERRO@Não foi possível verificar a lista do contato!'); - } - if (pg_num_rows($result)) { - GeraExcept('ERRO@Número já cadastrado para este contato!'); - } - - /* - * insere o telefone para o contato. - */ - $query = "insert into pbx_campanha_contato_fone(cmp_id, list_id, cont_id, conf_fone)values(%s, %s, %s, %s)"; - $query = sprintf($query, QuotedStr($dadosDiscador['cmp_id']), QuotedStr($dadosDiscador['list_id']), QuotedStr($dadosDiscador['cont_id']), QuotedStr($numero)); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept('ERRO@Não foi possível gravar o número informado!'); - } - - /* - * Recupera o id do telefone; - */ - $confId = GetCurrVal('pbx_campanha_contato_fone'); - - /* - * Exige que telefones já discados estejam com o status atualizado. - */ - $statusDiscado = GetNumDiscadoStatus($confId); - if ($statusDiscado !== false) { - GeraExcept(sprintf("ERRO@Antes de incluir um novo número(%s), você de gravar o status do número já discado%s!", $numero, $statusDiscado['conf_fone'])); - } - - /* - * Carrega a lista de telefones para ataulizar a operacao com o fone origianal selecionado. - */ - $listaFones = GetFonesContato($dadosDiscador['cont_id'], $dadosDiscador['conf_fone']); - $query = "update pbx_campanha_operacao set lista_fones_discador = %s where cmpo_id = %s"; - $query = sprintf($query, QuotedStr($listaFones), QuotedStr($dadosDiscador['cmpo_id'])); - $result = pg_query($db, $query); - if (!$result) { - GeraExcept('ERRO@Não foi possível atualizar a lista do contato!'); - } - - /* - * Selediona o numero recem informado; - */ - $listaFones = GetFonesContato($dadosDiscador['cont_id'], $numero); - - $result = pg_query($db, 'commit'); - if (!$result) { - GeraExcept('ERRO@Não foi possível finalizar a transação!'); - } - - /* - * sucesso retorna a lista de telefones. - */ - echo "OK@Operação realizada com sucesso!@$listaFones"; - } catch (Exception $ex) { - if ($inTran) - pg_query($db, 'rollback'); - RegistraLogAgente("IncluiDiscador", $ex->getMessage(), $ex); - echo sprintf("%s", $ex->getMessage()); - } -} - -function StatusFoneDiscador($db, $silent = 0) { - try { - $status = soNumero($_REQUEST['status']); - $confId = soNumero($_REQUEST['conf_id']); - $uid = trim($_REQUEST['uniqueid']); - $uid = $uid ? QuotedStr($uid) : 'null'; - - $query = "update pbx_campanha_contato_fone set conf_status = %s, conf_agente_matricula = %s, conf_uid = %s where conf_id = %s"; - $query = sprintf($query, QuotedStr($status), QuotedStr(GetMatricula()), $uid, QuotedStr($confId)); - $result = pg_query($db, $query); - if (!$result || !pg_affected_rows($result)) { - GeraExcept("ERRO;Não foi possível atualizar o número informado!;$confId;0"); - } - - if ($silent) { - return true; - } - echo "OK;Operação realizada com sucesso!;$confId;$status"; - } catch (Exception $ex) { - RegistraLogAgente("StatusFoneDiscador", $ex->getMessage(), $ex); - if ($silent) { - return false; - } - echo $ex->getMessage(); - } -} - -function FuncoesOperacao() { - try { - if (isset($_REQUEST['carregaFones'])) { - $query = "update pbx_campanha_operacao set carrega_fone = 1 where cmpo_id = %s"; - $query = sprintf($query, QuotedStr($_REQUEST['carregaFones'])); - $result = pg_query($query); - if (!$result) { - GeraExcept("ERRO;Não foi possível carregar a lista de telefones!"); - } - - echo "OK;Operação realizada com sucesso!"; - } - - if (isset($_REQUEST['discagemInicial'])) { - $query = "update pbx_campanha_operacao set discagem_inicial = 1 where cmpo_id = %s"; - $query = sprintf($query, QuotedStr($_REQUEST['discagemInicial'])); - $result = pg_query($query); - if (!$result) { - GeraExcept("ERRO;Não foi possível realizar a discagem!"); - } - - echo "OK;Operação realizada com sucesso!"; - } - } catch (Exception $ex) { - RegistraLogAgente("FuncoesOperacao", $ex->getMessage(), $ex); - echo $ex->getMessage(); - } -} - -function GravaProtocoloExterno($dispMsg = true) { - try { - /* - * O protocolo do paraceiro deve ser informado com 12 numeros. - */ - $protoExterno = soNumero($_REQUEST['proto']); - if (!ValidaProtoParceiro($protoExterno)) { - GeraExcept("Protocolo Inválido!"); - } - - $matricula = GetMatricula(); - $query = sprintf("select uniqueid2, protocolo from pbx_supervisor_agentes where matricula = '%s'", $matricula); - $result = pg_query($query); - if (!$result) { - GeraExcept("Erro consultar banco de dados!"); - } - if (!pg_num_rows($result)) { - GeraExcept("Não foi possível concluir a operação, \"Agente não Conectado\" registro não localizado!!"); - } - - $dados = pg_fetch_array($result); - $uid2 = trim($dados['uniqueid2']); - if (!$uid2) { - GeraExcept("Não foi possível concluir a operação, \"Registro não Localizado\"!"); - } - - $query = sprintf("update pbx_protocolo_reg set protoparceiro = %s where uniqueid = %s", QuotedStr($protoExterno), QuotedStr($uid2)); - $result = pg_query($query); - if (!$result || !pg_affected_rows($result)) { - GeraExcept("Não foi possível registrar a informação!"); - } - - if ($dispMsg) { - echo "Operação concluida com sucesso!"; - } - return true; - } catch (Exception $ex) { - RegistraLogAgente("GravaProtocoloExterno", $ex->getMessage(), $ex); - if ($dispMsg) { - echo $ex->getMessage(); - } - return false; - } -} - -function DadosAtualiza($dbcon) { - global $statusServer; - - $statusServer = false; - $arControle = GetInfoControle(); - // print_r($arControle); exit; - /* - * Verifica o tempo de atuzlização do servidor, - * se for inferior a 10s usa o servidor do su- - * pervisor para obter os dados, do contrário - * utiliza o acesso direto ao banco de dados. - */ - - $ultAtu = time() - $arControle['ultAtulizacao']; - - if ($ultAtu < 10) { - $statusServer = true; - $matricula = GetMatricula(); - /* - * Tenta obter os dados do supervisor atraves do acesso ao servico - * do supervisor - */ - $dados = RetornaDadosAgt($arControle); - //if(!IsAjax()) print_r($dados); - - /* - * Se a função retornar dados retorna para aplicação, caso - * contrario continua com o banco de dados; - */ - if (count($dados) && isset($dados[$matricula])) { - $dadoAgt = $dados[$matricula]; - foreach ($dadoAgt as $key => $value) { - $GLOBALS['dadosMonitor'][$key] = $value; - - if (($key == 'status_agente') && ($value == 'PAUSA')) { - $_SESSION[SS_PAUSA_AGENTE] = 1; - } else if ($key == 'chamadas_atendidas') { - $GLOBALS['dadosMonitor']['atendidas_pa'] = $value; - } else if ($key == 'chamadas_originadas') { - $GLOBALS['dadosMonitor']['originadas_pa'] = $value; - } - } - - return; - } - } - - /* - * Recupera chamadas abandonadas sem retorno. - */ - SetAbandonasFila(); - - $query = GetQueryAgenteRt(1); - $result = pg_query($dbcon, $query); - $agenteLogado = $result && (pg_num_rows($result) > 0); - if ($agenteLogado) { - /* - * Dados da tablea pbx_supervisor_agentes - */ - $dados = pg_fetch_array($result); - foreach ($dados as $key => $value) { - if (!is_numeric($key)) { - $GLOBALS['dadosMonitor'][$key] = $value; - - if (($key == 'status_agente') && ($value == 'PAUSA')) { - $_SESSION[SS_PAUSA_AGENTE] = 1; - } - } - } - - /* - * Informacoes sobre o atendimento do agente - */ - $query = GetQueryAgenteRt(2); - $result = pg_query($dbcon, $query); - if ($result && (pg_num_rows($result) > 0)) { - $dados = pg_fetch_array($result, null, PGSQL_ASSOC); - - foreach ($dados as $key => $value) { - $GLOBALS['dadosMonitor'][$key] = $value; - } - } - } else { - SetStatusAgente(); - } -} - -function DisablePausa() { - return AgenteON() && !AgentePausa() ? "" : 'disabled="disabled"'; -} - -function EntraPausa($db, $codMotivo) { - $regProc = QuotedStr(sprintf("AddPausa: Login: %s Scrp: %s Func: %s ", GetLogin(), 'agentert.php', 'EntradaPausa')); - $matricula = GetMatricula(); - $dac = $_SESSION[SS_DAC_CODIGO]; - $ramal = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $motivoPausa = @GetPausaDescricao($db, $codMotivo); - $pausa_produtiva_obs = NullDb(trim($_POST['pausa_produtiva_obs'])); - - $emPausa = GetPausa($db, $matricula, true); - $inTran = 0; - try { - if ($emPausa) { - GetExcept("O agente já esta em pausa!"); - } - - GetPendenciaDiscador($db); - - /* - * Coloca o agente em pausa no asterisk. - */ - if (!GetUrl(AST_ADD_PAUSA)) { - GetExcept("Falha ao colocar o agente em pausa na central!"); - } - - $query = "select canal, canal_transfer, canal_agente, ramal, nome, dac, uniqueid, status from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - if ($result) { - $row = @pg_fetch_array($result); - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row["canal_agente"]; - @GetUrl(AST_DESLIGAR_LIGACAO); - } - - /* - * Inicia a transação. - */ - $result = pg_query($db, "begin"); - if (!$result) { - GetExcept("Erro ao iniciar o procedimento de pausa!"); - } - - /* - * Atualiza dados no superviosr. - */ - $query = "update pbx_supervisor_agentes - set status = 'PAUSA', motivo_pausa = '$motivoPausa', duracao = now(), origem_destino = '' - where matricula = '$matricula' and status <> 'PAUSA' "; - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - if (!$result) { - GetExcept("Falha ao atualizar registro de pausa na supervisão!"); - } - - - $relEvt = '0'; - $query = "insert into pbx_eventos_agentes(matricula, ramal, id_dac, id_motivo_pausa, entrada_pausa, flag, relaciona_eventos, saida_pausa, pausa_produtiva, pausa_produtiva_obs, reg_proc) - values('$matricula', '$ramal', $dac, $codMotivo, now(), 0, $relEvt, now(), (select produtiva from pbx_motivos_pausas where id = '$codMotivo'), $pausa_produtiva_obs, $regProc)"; - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - if (!$result) { - GetExcept("Falha ao inserir registro de pausa no sistema!"); - } - - $result = pg_query($db, "commit"); - if (!$result) { - GeraExcept("Nao foi concluir a remoçao da pausa!"); - } - - $_SESSION[SS_PAUSA_AGENTE] = 1; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO] = $codMotivo; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO_DESCRICAO] = $motivoPausa; - $_SESSION[SS_STATUS_AGENTE] = 'PAUSA'; - SetMsgAgente("O agente foi colocado em pausa!"); - return true; - } catch (Exception $ex) { - pg_query($db, "rollback"); - SetMsgAgente($ex->getMessage()); - RegistraLogAgente("EntraPausa", $ex->getMessage(), $ex); - return false; - } -} - -function SairPausa($db) { - global $jsStartup; - $regProc = QuotedStr(sprintf("|RemPausa: Login: %s Scrp: %s Func: %s ", GetLogin(), 'agentert.php', 'SairPausa')); - $matricula = GetMatricula(); - $ramal = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $login = GetLogin(); - $dac = $_SESSION[SS_DAC_CODIGO]; - $inTran = 0; - $emPausa = GetPausa($db, $matricula, true); - - try { - - if (!$emPausa) { - GeraExcept("O agente não esta em pausa!"); - } - - if (GetExigeClas() && !GetChamadaClassificada()) { - GeraExcept("Para sair de pausa é necessário Classificar a chamada!"); - } - - $audio = GetStatusChamadaClassificada($dac); - if ($audio) { - $audio = substr($audio, 0, -4); - GetAudioClassificacaoRamal($audio); - $modo = GetModoAtende() == ATENDIMENTO_AUTOMATICO ? ',1' : ''; - $jsStartup[] = sprintf("GetAlertConfirmAudio('$audio'%s)", $modo); - $_SESSION['SSClassificaPendente'] = 1; - if ($modo) { - GeraExcept('Para escutar a chamada clique no botão ao lado.' . " " . "" . ""); - } else { - GeraExcept('Para escutar a chamada clique no botão ao lado.' . " " . "" . ""); - } - } - - /* - * Remove da pausa do asterisk somente se a opçao disponivel atendimento nao - * estiver marcada, - */ - if (IsAgenteDisponivel($db, $matricula)) { - @GetUrl(AST_REM_PAUSA); - } - - $result = pg_query($db, "begin"); - if (!$result) { - GeraExcept("Nao foi possivel iniciar o procedimento de retirada da pausa!"); - } - - /* - * atualiza dados do supervisor - */ - $query = "update pbx_supervisor_agentes - set status = 'LIVRE', - motivo_pausa = '', - protocolo = '', - origem_destino = '', - duracao = now() - where matricula = '$matricula' - and status = 'PAUSA'"; - $result = pg_query($db, $query); - $result = $result && @pg_affected_rows($result); - - if (!$result) { - GeraExcept("Nao foi possivel atualizar as informaçoes de pausa na supervisao!"); - } - - - /* - * Registra a pausa no sistema. - */ - $query = "update pbx_eventos_agentes - set saida_pausa = now(), - flag = 2, - reg_proc = coalesce(reg_proc, '') || $regProc - where matricula = '$matricula' - and id_dac = $dac - and entrada_pausa = (select max(entrada_pausa) from pbx_eventos_agentes where matricula = '$matricula' and id_dac = $dac)"; - $result = pg_query($db, $query); - $result = $result && @pg_affected_rows($result); - - if (!$result) { - GeraExcept("Nao foi possivel atualizar as informaçoes de pausa no sistema!"); - } - - $result = pg_query($db, "commit"); - if (!$result) { - GeraExcept("Nao foi concluir a remoçao da pausa!"); - } - - SetMsgAgente("O agente foi retirado da pausa!"); - $_SESSION[SS_PAUSA_AGENTE] = 0; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO] = 0; - $_SESSION[SS_STATUS_AGENTE] = 'LIVRE'; - return true; - } catch (Exception $ex) { - pg_query($db, "rollback"); - SetMsgAgente($ex->getMessage()); - RegistraLogAgente("SairPausa", $ex->getMessage(), $ex); - return false; - } -} - -function ConnectaAgenteRt($db, $dac, $tpAtend) { - global $jsStartup; - $regProc = QuotedStr(sprintf("AddPausa: Login: %s Scrp: %s Func: %s ", GetLogin(), 'agentert.php', 'ConnectaAgenteRt')); - /* - * Se o agente já estiver logado aborta a operação de login - */ - $ramal = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $ramalEst = VerificaRamalEstatico($db, $ramal, $dac); - $dacCheck = ''; - $agtCheck = ''; - SetStatusAgente(); - - try { - if (!$ramal) { - $msg = "Não há ramal configurado!"; - GeraExcept($msg); - } - - - if (VerficaAgenteLogado($db)) { - $ramalCon = GetRamalAgenteLogado($db); - $msg = "Não é possível conectar ao servidor, o Agente já está Conectado no Ramal: $ramalCon!"; - GeraExcept($msg); - } - - /* - * Remove conexoes do usuario corrente. - */ - LimpaConexao($db); - - if (VerificaRamalLogado($db, $dacCheck, $agtCheck)) { - $msg = "Não é possível conectar ao servidor, Ramal: \"$ramal\" já conectado! Dac: \"$dacCheck\" Agente: \"$agtCheck\""; - GeraExcept($msg); - } - - if ($ramalEst) { - $msg = "Não é possível conectar ao servidor, Ramal: \"$ramal\" estático na(s) fila(s): \"[$ramalEst]\"!"; - GeraExcept($msg); - } - - if (VerificaMaxAgenteLogado($db)) { - $msg = "Não é possível conectar o Agente! O número máximo de \"PAs\" simultaneos já foi atingido!"; - GeraExcept($msg); - } - - if (VerificaRamalSigame($db, $ramal)) { - $msg = "Não é possível conectar ao servidor, Ramal: \"$ramal\" possui siga-me ativado"; - GeraExcept($msg); - } - - if (VerificaClassObrigatoria($db, $dac)) { - $msg = "Está configurado \"Classificação Obrigatória\", mas não há clssificações disponiveis para este Dac!"; - GeraExcept($msg); - } - - /* - * Seleciona a descricao do dac escolhido; - */ - $query = "select nome from pbx_dacs where id = '$dac'"; - $result = pg_query($db, $query); - - if (!$result) { - $msg = "Não foi possível consultar o DAC!"; - GeraExcept($msg); - } - $row = pg_fetch_row($result); - $_SESSION[SS_DAC_DESCRICAO] = $row[0]; - - $modoAtendimento = VerificaModoAtendimento($db, $dac); - - if ($modoAtendimento != "default") { - $_SESSION[SS_MODO_ATENDIMENTO] = $modoAtendimento == 'manual' ? "Manual" : "Automático"; - $_SESSION[SS_MODO_ATENDIMENTO_COD] = $modoAtendimento == 'manual' ? ATENDIMENTO_MANUAL : ATENDIMENTO_AUTOMATICO; - $tpAtend != $_SESSION[SS_MODO_ATENDIMENTO_COD] ? $jsStartup[] = "alert('Você foi conectado no modo atendimento {$_SESSION[SS_MODO_ATENDIMENTO]}');" : ''; - } else { - $_SESSION[SS_MODO_ATENDIMENTO] = $tpAtend == ATENDIMENTO_MANUAL ? "Manual" : "Automático"; - $_SESSION[SS_MODO_ATENDIMENTO_COD] = $tpAtend; - } - - $moduAtendDesc = $_SESSION[SS_MODO_ATENDIMENTO]; - $_SESSION[SS_DAC_CODIGO] = $dac; - $matricula = GetMatricula(); - $ramal = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $login = GetLogin(); - $conAst = false; - $_SESSION[SS_AGT_CONTEXTO_RAMAL] = GetContextoRamal($db, $ramal); - - /* - * loga o agente no asterisk - */ - - if (!GetUrl(AST_LOGIN_AGENTE)) { - $msg = "Não foi possível logar o agente!"; - GeraExcept($msg); - } - - /* - * Verifica se o login foi executado com sucesso. - */ - $verConexao = 0; - $i = 0; - while ($i++ < 10) { - $query = "select count(*) from pbx_supervisor_agentes where matricula = '$matricula' and upper(status) = 'PAUSA' "; - $result = pg_query($db, $query); - - if (!$result) { - $msg = "Não foi possível verificar a conexão do agente!"; - GeraExcept($msg); - } - - $row = pg_fetch_row($result); - /* - * Se a verificação foi efetuada com sucesso, retorna para a função. - */ - if ($row[0]) { - $verConexao = true; - break; - } - usleep(500000); - } - - if (!$verConexao) { - $msg = "O registro do agente não está disponível!"; - GeraExcept($msg); - } - - /* - * Registra login no banco de dados. - */ - $dacDesc = $_SESSION[SS_DAC_DESCRICAO]; - $result = pg_query($db, "begin"); - - if (!$result) { - $msg = "Não foi possível iniciar uma transação para registrar o login do agente!"; - GeraExcept($msg); - } - - /* - * Registra o agente na supervisão. - */ - $query = "update pbx_supervisor_agentes - set ramal = '$ramal', nome = '$login', dac = '$dacDesc', modo_atendimento = '$moduAtendDesc', duracao = now(), chamada_classificado = '2' - where matricula = '$matricula'"; - - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - - if (!$result) { - $msg = "Não foi possível registrar o login do agente na supervisão!"; - GeraExcept($msg); - } - - /* - * Registra o login do agente no sistema. - * - */ - $query = "insert into pbx_eventos_agentes(matricula,ramal,id_dac,\"login\", logoff, flag) values('$matricula', '$ramal',$dac, now(),now(),0)"; - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - if (!$result) { - $msg = "Não foi possível registrar o login do agente no sistema!"; - GeraExcept($msg); - } - - /* - * Registra pausa de Login. - */ - $idMotivoPausa = GetMotivoLogin($db); - $relEvt = '0'; - $query = "insert into pbx_eventos_agentes(matricula,ramal,id_dac,id_motivo_pausa,entrada_pausa,flag,relaciona_eventos, reg_proc) values('$matricula', '$ramal',$dac,$idMotivoPausa,now(),0,$relEvt, $regProc)"; - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - if (!$result) { - $msg = "Não foi possível registrar a pausa do login!"; - GeraExcept($msg); - } - - $result = pg_query($db, "commit"); - if (!$result) { - $msg = "Não foi possível finalizar o registro de login do agente!"; - GeraExcept($msg); - } - /* - * Tem a simples função de ativar os numeros de discagem, - * qdo o agente desloga sem encerrar uma operação de dis- - * gem; - */ - @AtivaNumeroDiscagem($db, $matricula); - - SetMsgAgente("Operação realizada com sucesso!"); - SetStatusAgente(1); - $_SESSION[SS_PAUSA_AGENTE] = 1; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO] = $idMotivoPausa; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO_DESCRICAO] = 'login'; - $_SESSION[SS_STATUS_AGENTE] = 'PAUSA'; - $_SESSION[SS_EXIGE_CLASSIFICACAO] = GetExigeClas($db, $dac); - $_SESSION[SS_JUSTIFICATIVA_PAUSA] = GetObsProdAgente($db, $dac); - $_SESSION["SSPausaAtomatica"] = GetPausaAutomatica($db, $dac); - $_SESSION["SS_CK_DISPO"] = 1; - $_SESSION["SS_ultimo_dac_agente"] = $dac; - $_SESSION['SSClassificaPendente'] = 0; - return true; - } catch (Exception $ex) { - //APRESENTA POPUP COM A MENSAGEM DE ERRO - $jsStartup[] = sprintf("alert('%s');", $ex->getMessage()); - SetMsgAgente($ex->getMessage()); - SetStatusAgente(); - $_SESSION[SS_PAUSA_AGENTE] = 0; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO] = ''; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO_DESCRICAO] = ''; - $_SESSION[SS_STATUS_AGENTE] = 'OFF'; - $_SESSION[SS_EXIGE_CLASSIFICACAO] = NULL; - $_SESSION[SS_JUSTIFICATIVA_PAUSA] = NULL; - pg_query($db, "rollback"); - RegistraLogAgente("ConnectaAgenteRt", $ex->getMessage(), $ex); - return false; - } -} - -function DesConectaAgenteRt($db, $type = '') { - global $jsStartup; - $matricula = GetMatricula(); - $ramal = GetRamalMonitorar(RAMAL_MONITOR_AGENTE); - $login = GetLogin(); - $dac = $_SESSION[SS_DAC_CODIGO]; - - try { - if (GetExigeClas() && !GetChamadaClassificada()) { - GeraExcept("Para efetuar o logoff é necessário Classificar a chamada!"); - } - - GetPendenciaDiscador($db); - - if ($_SESSION['prm_aviso_desconnect'] == 'yes' && empty($type)) { - $jsStartup[] = "GetAvisoDesconnect()"; - return false; - } - - /* - * Se o agente estiver em pausa é removido antes de deslogar. - */ - if ($_SESSION[SS_PAUSA_AGENTE]) { - @SairPausa($db); - } - - /* - * Se o tipo de atendimento for manual remove agente da fila. - */ - if ($_SESSION[SS_MODO_ATENDIMENTO_COD] == ATENDIMENTO_MANUAL) { - @GetUrl(AST_REM_FILA); - } - - /* - * Desliga a chamada corrente - * e desconecta o usuario do asterisk - */ - $query = "select canal, canal_transfer, canal_agente, ramal, nome, dac, uniqueid, status from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - if ($result) { - $row = @pg_fetch_array($result); - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row["canal_agente"]; - @GetUrl(AST_DESLIGAR_LIGACAO); - } - @GetUrl(AST_LOGOFF_AGENTE); - - - $result = pg_query($db, "begin"); - if (!$result) { - GeraExcept("Não foi possível iniciar a desconexão do agente!"); - } - - //atualiza dados do supervisor - /* - * Quando este parametro for 0 nao mais ha dados do agennte nesta tabela - */ - - $query = "delete from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - - if (!$result) { - GeraExcept("Não foi possível remover o agente da supervisão!"); - } - - - $query = "update pbx_eventos_agentes - set logoff = now(), flag = 2 - where matricula = '$matricula' - and id_dac = '$dac' - and login = (select max(login) from pbx_eventos_agentes where matricula = '$matricula' and id_dac = '$dac') "; - $result = pg_query($db, $query); - - $result = $result && pg_affected_rows($result); - if (!$result) { - GeraExcept("Falha ao registrar o logoff do agente no sistema!"); - } - - $result = pg_query($db, "commit"); - if (!$result) { - GeraExcept("Não foi possível finalizar o registro de logoff do agente!"); - } - - SetMsgAgente("Agente desconectado com sucesso!"); - AgenteDesconectRt(); - return true; - } catch (Exception $ex) { - pg_query($db, "rollback"); - SetMsgAgente($ex->getMessage()); - RegistraLogAgente("DesConectaAgenteRt", $ex->getMessage(), $ex); - return false; - } -} - -function GetQueryAgenteRt($qr) { - $matricula = GetMatricula(); - $dac = isset($_SESSION[SS_DAC_CODIGO]) ? $_SESSION[SS_DAC_CODIGO] : 0; - $fila = isset($_SESSION[SS_DAC_DESCRICAO]) ? $_SESSION[SS_DAC_DESCRICAO] : ''; - if ($qr == 1) { //substring(now()::time, 1, 8) as hora_atu, ( (EXTRACT(EPOCH FROM (now() - a.duracao)) / 60)) as status_time, - return "select (LOCALTIMESTAMP(0) - tempo_login) as tempo_logado, origem_destino as fone, - trim(status) as status_agente, (LOCALTIMESTAMP(0) - duracao) as duracao, - protocolo as num_protocolo, ramal as ramal_monitor, - uniqueid2, extract(epoch from (now() - logado))::int as tempo_atualiza, - trim(motivo_pausa) as pausa_motivo_rt, - trim(uniqueid) as uniqueid, disponivel_atendimento, chamada_classificado, coalesce(canal_transfer, '') as canal_transfer, - tipo_ligacao, cont_identificador, status_discador - from pbx_supervisor_agentes - where matricula = '$matricula' "; - } - - if ($qr == 2) { - /* - * Informações sobre a fila de atendimento - */ - return "SELECT - ATENDIDAS_PA, ABANDONADAS, (select espera from pbx_supervisor_dacs where dac = dados.FILA) as qtde_fila - ,(select tempo_espera * INTERVAL '1 SECOND' from pbx_supervisor_dacs where dac = dados.FILA) as TME - ,ORIGINADAS_PA - ,round( CASE WHEN(ATENDIDAS_PA = 0)THEN 0 ELSE ((TEMPO_ATENDIMENTO + TEMPO_ORIGINDADA) / (ATENDIDAS_PA + ORIGINADAS_PA))END) * INTERVAL '1 SECOND' AS TMA - FROM ( - SELECT fila - ,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER') THEN 1 ELSE 0 END) AS ATENDIDAS_PA - ,SUM (CASE WHEN EVENTO = 'ABANDON' THEN 1 ELSE 0 END) AS ABANDONADAS - ,SUM (CASE WHEN EVENTO IN ('COMPLETAAGENT','COMPLETACALLER', 'TRANSFERORIG','BUSYS','NOANSWERS') THEN 1 ELSE 0 END) AS ORIGINADAS_PA - ,SUM (CASE WHEN EVENTO IN ('CONNECT') AND strtoint(param1) > '3' THEN 1 ELSE 0 END) AS ESPERA - ,SUM (CASE WHEN EVENTO IN ('CONNECT') AND strtoint(param1) > '1' THEN strtoint(param1) ELSE 0 END) AS TEMPO_ESPERA - ,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER') AND strtoint(param2) > '1' THEN strtoint(param2) ELSE 0 END) AS TEMPO_ATENDIMENTO - ,SUM (CASE WHEN EVENTO IN ('COMPLETAAGENT','COMPLETACALLER') AND strtoint(param2) > '1' THEN strtoint(param2) ELSE 0 END) AS TEMPO_ORIGINDADA - ,SUM (CASE WHEN( (EVENTO = 'ABANDON') AND (strtoint(param2) > '1') ) THEN strtoint(param3) ELSE 0 END) AS TEMPO_ABANDONO - FROM ( - SELECT - a.calldate,b.fila,b.evento,b.param1,b.param2,b.param3,b.param4 - FROM ast_bilhetes a - INNER JOIN ast_eventos_dacs b on b.uid2 = a.uniqueid - INNER JOIN pbx_dacs c on c.nome = b.fila - WHERE b.evento in ('CONNECT','ABANDON','COMPLETEAGENT','COMPLETECALLER','TRANSFER', 'COMPLETAAGENT','COMPLETACALLER', 'TRANSFERORIG','ENTERQUEUE','BUSYS','NOANSWERS') - AND a.lastapp <> 'Transferred Call' - AND a.data_bilhete = now()::date - AND c.id = $dac - ) AS DADOS - GROUP BY FILA - ) AS DADOS"; - } -} - -function FormataDadosRt($dados) { - $ret = ''; - foreach ($dados as $key => $value) { - $key = trim($key); - $value = str_replace('@', '##', $value); - $ret .= !$ret ? "$key|$value" : "@$key|$value"; - } - - return $ret; -} - -function UpdateLogoffRt($db) { - if ($_SESSION[SS_PAUSA_AGENTE]) { - @UpdatePausaRt($db); - } - $matricula = GetMatricula(); - $dac = $_SESSION[SS_DAC_CODIGO]; - - $query = "update pbx_supervisor_agentes - set logado = now() - where matricula = '$matricula'"; - $result = pg_query($db, $query); - - $query = "update pbx_eventos_agentes - set logoff = now(), - flag = 1 - where matricula = '$matricula' - and id_dac = $dac - and login = (select max(login) from pbx_eventos_agentes where matricula = '$matricula' and id_dac = $dac)"; - pg_query($db, $query); -} - -function UpdatePausaRt($db) { - $matricula = GetMatricula(); - $dac = $_SESSION[SS_DAC_CODIGO]; - $query = "update pbx_eventos_agentes - set saida_pausa = now(), - flag = 1 - where matricula = '$matricula' - and id_dac = $dac - and entrada_pausa = (select max(entrada_pausa) from pbx_eventos_agentes where matricula = '$matricula' and id_dac = $dac)"; - pg_query($db, $query); -} - -function AgenteDesconectRt() { - $_SESSION[SS_STATUS_AGENTE] = 'OFF'; - SetStatusAgente(); - $_SESSION[SS_PAUSA_AGENTE] = 0; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO] = 0; - $_SESSION[SS_PAUSA_AGENTE_MOTIVO_DESCRICAO] = ""; - $_SESSION[SS_EXIGE_CLASSIFICACAO] = NULL; - $_SESSION[SS_JUSTIFICATIVA_PAUSA] = NULL; - $_SESSION[SS_DAC_DESCRICAO] = ""; -} - -function LimpaConexao($db) { - - /* - * Matricula do usuário logado - */ - $matricula = GetMatricula(); - @LogAgente("LimpaConexao", "Inicio", true); - - /* - * Desliga a chamada corrente - * e desconecta o usuario do asterisk - */ - $query = "select canal, canal_transfer, canal_agente, ramal, upper(modo_atendimento) as modo_atendimento, dac, uniqueid, status from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - if (!$result || !pg_num_rows($result)) { - @LogAgente("LimpaConexao", "Nao logado: {$matricula}", false); - return; - } - - $dadosConexao = @pg_fetch_array($result); - $canal = $dadosConexao['canal']; - $canalAgente = $dadosConexao['canal_agente']; - $ramal = $dadosConexao['ramal']; - $dac = $dadosConexao['dac']; - $status = $dadosConexao['status']; - $modoAtendimento = $dadosConexao['modo_atendimento']; - - /* - * Derruba chamada caso esteja em curso. - */ - if ($canalAgente) { - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $canalAgente; - @GetUrl(AST_DESLIGAR_LIGACAO); - } - - /* - * Retira o agente de pausa na central. - */ - if ($status == 'PAUSA') { - @SairPausa($db); - } - - /* - * Se o tipo de atendimento for manual remove agente da fila. - */ - if ($modoAtendimento == 'MANUAL') { - @GetUrl(AST_REM_FILA); - } - - /* - * Desloga o agente na central. - */ - @GetUrl(AST_LOGOFF_AGENTE, $dac, $matricula); - - /* - * Quando este parametro for 0 nao mais ha dados do agennte nesta tabela - */ - $query = "delete from pbx_supervisor_agentes where matricula = '$matricula'"; - pg_query($db, $query); - - $query = "update pbx_eventos_agentes - set logoff = now(), flag = 2 - where matricula = '$matricula' - and id_dac = '$dac' - and login = (select max(login) from pbx_eventos_agentes where matricula = '$matricula' and id_dac = '$dac') "; - pg_query($db, $query); - - @LogAgente("LimpaConexao", "Logado: {$matricula}", false); - AgenteDesconectRt(); -} - -function SetStatusAgente($status = 0) { - $_SESSION[SS_AGENTE_CONECTADO] = $status; -} - -function GetStatusAgente() { - return isset($_SESSION[SS_AGENTE_CONECTADO]) ? $_SESSION[SS_AGENTE_CONECTADO] : 0; -} - -function ClassificaChamada($db) { - $dac = $_SESSION[SS_DAC_CODIGO]; - $matricula = GetMatricula(); - $result = true; - $msg = ''; - - if (!isset($_GET["contrib_id"]) || !$_GET["contrib_id"]) { - $idContrib = 'null'; - } else { - $contr = explode("-", $_GET["contrib_id"]); - $idContrib = soNumero($contr[0]) ? soNumero($contr[0]) : null; - /* - * Verifica se o cliente existe na base. - */ - $query = "select count(*) from pbx_contribuinte where contrib_id = '$idContrib'"; - if (!($idContrib && RegistroInc($db, $query))) { - $idContrib = 'null'; - } - } - - $clas = $_GET["idClas"]; - $clasItem = $_GET["idClasItem"]; - $uniqueid = $_GET["uniqueid"]; - $proto = isset($_GET["proto"]) ? $_GET["proto"] : ''; - $munId = 0; - $inTran = 0; - try { - if (GetPausaAusente($db, $matricula)) { - SetaClassificaChamado($db, 1, 0); - echo "OK;Pausa ausente não pode ser classificada, chamada liberada!"; - return; - } - /* - * O protocolo externo pode passar junto com a classificação. - */ - if ($proto) { - if (!ValidaProtoParceiro($proto)) { - GeraExcept("ERRO; Protocolo Inválido!"); - } - if (!GravaProtocoloExterno(false)) { - GeraExcept("ERRO; Não foi possível gravar o protocolo!"); - } - } - - if (UseModVendas() && ExigeProtoVendas()) { - if (!GetProtoExternoReg($uniqueid, $clas)) { - GeraExcept('ERRO; Antes de classificar como "Venda" informe o "Protocolo"!'); - } - } - - $result = pg_query($db, 'begin'); - if (!$result) { - GeraExcept("ERRO;Não foi possível iniciar o registro da classificação no sistema!"); - } - $inTran = 1; - /* - * Esta informações são utilizadas no relatorio de abandonadas na fila para identificar - * qdo o agente não esta recdebendo uma chamada por não ter classificado a mesma estando - * portanto desabilitado de receber chamadas o que pode causar abandono. - */ - $query = "update pbx_registra_classificacao set rgc_saida = now(), matricula_reg = '$matricula' where uid = '$uniqueid' and rgc_saida is null"; - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("ERRO;Não foi possível registrar a classificação no sistema!"); - } - - /* - * Registra a classificação. - */ - $query = "insert - into pbx_classifica_reg(matricula, clas_id, clit_id, id_bilhetes, contrib_id, id_dac, mun_id) - values(%s, %s, %s, %s, %s, %s, %s)"; - - $query = sprintf($query, QuotedStr($matricula), $clas, $clasItem, QuotedStr($uniqueid), $idContrib, $dac, $munId); - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - if (!$result) { - $erro = @pg_last_error(); - - if (stripos($erro, "duplicate key ") !== false) { - GeraExcept("ERRO;Esta Classificação já foi registrada!"); - } - GeraExcept("ERRO;Não foi possível registrar a classificação!"); - } - - /* - * Atualizar o supervisor. - */ - if (!SetaClassificaChamado($db, 1, 1)) { - GeraExcept("ERRO;Não foi possível atualizar a supervisão!"); - } - - $result = pg_query($db, 'commit'); - if (!$result) { - GeraExcept("ERRO;Não foi possível concluir o registro da classificação no sistema!"); - } - - echo "OK;Classificação registrada com sucesso!"; - } catch (Exception $ex) { - RegistraLogAgente("ClassificaChamada", $ex->getMessage(), $ex); - if ($inTran) { - pg_query($db, 'rollback'); - } - $msg = $ex->getMessage(); - echo $msg; - } -} - -function ExistePrefixo($db, $prefixo) { - $query = "select count(*) from pbx_municipio_prefixo where prx_prefixo = '$prefixo'"; - $result = pg_query($db, $query); - if ($result) { - $row = @pg_fetch_row($result); - return $row[0]; - } - return false; -} - -function GravaPrefixo($db, $munId, $prefixo, $upd = 0) { - if ($upd) { - $query = "update pbx_municipio_prefixo set mun_id = '$munId' where prx_prefixo = '$prefixo'"; - } else { - $query = "insert into pbx_municipio_prefixo(mun_id, prx_prefixo)values('$munId', '$prefixo')"; - } - $result = pg_query($db, $query); - return $result && @pg_affected_rows($result); -} - -function AgtCallRt($db) { - $msgSis = GetSlogan(); - $matricula = GetMatricula(); - $acaoDiscar = isset($_GET["acaoDiscar"]) && (!$_GET["acaoDiscar"]); - $numeroDiscar = soNumero($_GET["numeroDiscar"]); - $confId = isset($_GET['conf_id']) ? $_GET['conf_id'] : 0; - $discador = $confId > 0; - $inTran = 0; - try { - if (!AgenteON()) { - GeraExcept("0;ERRO;Por favor para realizar a operação é necessário estar com agente conectado!"); - } - if (isset($_GET["numeroDiscar"]) && $acaoDiscar) { - if ($discador) { - $statusDiscado = GetNumDiscadoStatus($confId); - if ($statusDiscado !== false) { - GeraExcept(sprintf("9;ERRO;%s;%s!", $statusDiscado['conf_id'], $statusDiscado['conf_fone'])); - } - - if ($statusDiscado) { - $_SESSION['SSCodigoParam'] = $statusDiscado['cont_id']; - } - } - /* - * Altera o status do numero na lista. - */ - $result = pg_query($db, "begin"); - if (!$result) { - GeraExcept("1;ERRO;Não foi possível iniciar a operação!"); - } - $inTran = 1; - AtualizaNumDiscador($db, $confId, $numeroDiscar); - //LimpaUidAgente($db, $matricula); - - $_SESSION[AGT_NUM_DISC] = $numeroDiscar; - if (!GetUrl(AST_DISCAR)) { - GeraExcept("0;ERRO;Não foi possível discar para o número informado!"); - } - - /* - * A ligação já foi efetuada pela central. - */ - pg_query($db, "commit"); - - echo "0;OK;Discagem realizada com sucesso!"; - } else if (isset($_GET["numeroDiscar"])) { - $matricula = GetMatricula(); - $_SESSION[AGT_NUM_DISC] = $numeroDiscar; - - $result = pg_query($db, "begin"); - if (!$result) { - GeraExcept("1;ERRO;Não foi possível iniciar a transferência!"); - } - $inTran = 1; - /* - * obtem informações do canal. - */ - $query = "select canal, canal_agente from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($db, $query); - if (!$result) { - GeraExcept("1;ERRO;Não foi possível obter informações sobre o canal para transferência!"); - } - - $row = @pg_fetch_row($result); - if (!$row[0]) { - GeraExcept("1;ERRO;Não existe canal disponível para realizar a transferência!"); - } - /* - * Seta o canal para discagem - */ - if ($row[0]) { - $_SESSION[AGT_CHANNEL_TRANSF] = $row[0]; - } - - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row[1]; - /* - * Incia a trasnferencia na central. - */ - GetUrl(AST_SET_VAR); - if (!GetUrl(AST_TRANSFERIR)) { - GeraExcept("1;ERRO;Não foi possível transferir para o número informado!"); - } - -// if (!GetExigeClas() || !GetDisponivelAtendimetno()) { -// @GetUrl(AST_REM_PAUSA); -// } - - $query = "update pbx_supervisor_agentes - set status = 'LIVRE', protocolo = '', origem_destino = '', duracao = now(), canal = '', canal_agente = '', uniqueid = '' - where matricula = '$matricula'"; - - $result = pg_query($db, $query); - $result = $result && pg_affected_rows($result); - - if (!$result) { - GeraExcept("1;ERRO;Não foi possível registrar a transferência para o número informado!"); - } - - $result = pg_query($db, "commit"); - if (!$result) { - GeraExcept("1;ERRO;Não foi possível finalizar a transferência!"); - } - - echo "1;OK;Transferência realizada com sucesso!"; - } else if (isset($_GET["numeroDiscar"]) && empty($_GET["numeroDiscar"])) { - echo "0;WNG;Informe um número!"; - } else { - echo "0;WNG;Ação não identificada!"; - } - } catch (Exception $ex) { - if ($inTran) { - pg_query($db, "rollback"); - } - RegistraLogAgente("AgtCallRt", $ex->getMessage(), $ex); - echo $ex->getMessage(); - } -} - -function IniciaTransferenciaConsultaRt() { - try { - $numeroTransferencia = $_GET["numeroDiscar"]; - $matricula = trim(GetMatricula()); - $dbcon = $GLOBALS['dbcon']; - $moduAuto = (GetModoAtende() != ATENDIMENTO_MANUAL); - - $query = "select canal, canal_transfer, canal_agente, ramal, nome, dac, uniqueid from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($dbcon, $query); - if (!$result) { - GeraExcept("2;ERRO;Não foi possivel obter informações sobre a chamada!"); - } - - if (!pg_num_rows($result)) { - GeraExcept("2;WNG;Não há nenhuma ligação em curso!"); - } - - /* - * Coleta informações sobre a chamada. - */ - $row = @pg_fetch_array($result); - if (!$row["canal"]) { - GeraExcept("8;ERRO;Não há canal disponível para realizar a transferência!"); - } - - $_SESSION[AGT_CHANNEL_TRANSF] = $row["canal"]; - $_SESSION[AGT_CHANNEL_TRCONSULTA] = $row["canal_transfer"]; - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row["canal_agente"]; - $emtransf = !empty($row["canal_transfer"]); - - /* - * Ainda não iniciou a transferencia - * Se canal_transfer estiver vazio - */ - if (!$emtransf) { - $_SESSION[AGT_NUM_DISC] = $numeroTransferencia; - - //GetUrl(AST_ADD_PAUSA); - $cmd = array(); - $cmd[] = Sprintf("%s: %s", "Action", "Setvar"); - $cmd[] = Sprintf("%s: %s", "channel", GetChannelAgente()); - $cmd[] = Sprintf("%s: %s", "variable", "ESPERA_AGENTE_DESATIVADO"); - $cmd[] = Sprintf("%s: %s", "value", "OK"); - SetCmdAmi($cmd); - GetUrl(AST_EXEC_AMI); - GetUrl(AST_SET_VAR); - - $retPendulo = IniciaPenduloRt(); - $retA = explode(";", $retPendulo); - $result = $retA[1] == "OK"; - if (!$result) { - GeraExcept($retPendulo); - } - - sleep(1); - /* - * Agente em atendimento automatico. - */ -// if ($moduAuto) { -// $result = GetUrl(AST_TRCONSULTA_ESPERA); -// } - - if ($moduAuto && !$result) { - GeraExcept("2;ERRO;Não foi possível discar para o agente!"); - } - - /* - * Tenta alterar as informações no agente. - */ - $query = "update pbx_supervisor_agentes set canal_transfer = 'Agent/$matricula' where matricula = '$matricula'"; - pg_query($dbcon, $query); - - echo "2;OK;Transferencia Iniciada"; - } else { - $cmd = array(); - $cmd[] = Sprintf("%s: %s", "Action", "Setvar"); - $cmd[] = Sprintf("%s: %s", "channel", GetChannelAgente()); - $cmd[] = Sprintf("%s: %s", "variable", "ESPERA_AGENTE_DESATIVADO"); - $cmd[] = Sprintf("%s: %s", "value", ""); - SetCmdAmi($cmd); - GetUrl(AST_EXEC_AMI); - $result = GetUrl(AST_TRCONSULTA_TRANSFERE_ABORTA); - if (!$result) { - GeraExcept("2;ERRO;Não foi possível abortar transferência!"); - } - - echo "2;OK;Transferência interropida"; - - /* - * Tenta alterar as informações no agente. - */ - $query = "update pbx_supervisor_agentes set canal_transfer = '' where matricula = '$matricula'"; - pg_query($dbcon, $query); - } - } catch (Exception $ex) { - RegistraLogAgente("IniciaTransferenciaConsultaRt", $ex->getMessage(), $ex); - echo $ex->getMessage(); - } -} - -function FinalizaTransferenciaConsultaRt() { - echo DesligarChamadaRt(); -} - -function DesligarChamadaRt() { - $dbcon = $GLOBALS['dbcon']; - $msgErro = ""; - $result = true; - $inTran = 0; - - try { - - if (!AgenteON()) { - GeraExcept("ERRO;Agente Desconectado!"); - } - - $matricula = GetMatricula(); - $query = "select canal, canal_transfer, canal_agente, ramal, nome, dac, uniqueid, status, tipo_ligacao from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($dbcon, $query); - if (!$result) { - GeraExcept("ERRO;Não foi possível consultar informações da chamada!"); - } - $row = @pg_fetch_array($result); - - /* - * Obtem informacoes sobre a chamada. - */ - if ($row["canal"]) { - $_SESSION[AGT_CHANNEL_TRANSF] = $row["canal"]; - } - $_SESSION[AGT_CHANNEL_TRCONSULTA] = $row["canal_transfer"]; - - /* - * Verifica se a uma transferencia em curso, para tormar a ação de desligar a chamada - * ou concluir a transferenica. - */ - $emTransf = !empty($row["canal_transfer"]); - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row["canal_agente"]; - - $status = $row["status"]; - - if ($emTransf) { - if ($row["tipo_ligacao"] == 'E') { - $cmd = array(); - $cmd[] = Sprintf("%s: %s", "Action", "Setvar"); - $cmd[] = Sprintf("%s: %s", "channel", $row["canal"]); - $cmd[] = Sprintf("%s: %s", "variable", "MATRICULA"); - $cmd[] = Sprintf("%s: %s", "value", ""); - SetCmdAmi($cmd); - @GetUrl(AST_EXEC_AMI); - unset($cmd); - - // EXECUTA LIMPA MATRICULA - $cmd[] = Sprintf("%s: %s", "Action", "Setvar"); - $cmd[] = Sprintf("%s: %s", "channel", $row["canal"]); - $cmd[] = Sprintf("%s: %s", "variable", "MATRICULA-DESTINO"); - $cmd[] = Sprintf("%s: %s", "value", ""); - SetCmdAmi($cmd); - @GetUrl(AST_EXEC_AMI); - } - - $result = GetUrl(AST_DESLIGAR_LIGACAO); - - if (!$result) { - GeraExcept("ERRO;Não foi possível transferir a chamada! TRANSFERE"); - } - - /* - * Tenta limpar o canal de transferencia. - */ - $query = "update pbx_supervisor_agentes - set status = 'LIVRE', - protocolo = '', - origem_destino = '', - duracao = now(), - canal = '', - canal_agente = '', - canal_transfer = '', - uniqueid = '' - where matricula = '$matricula'"; - pg_query($dbcon, $query); - - return "OK;Chamada transferida com sucesso!"; - } else { - //if(!isset($_SESSION[AGT_MATRICULA])){ GeraExcept("2;ERRO;Agente Desconectado!"); } - - /* - * Atualiza o agente de acordo com o status. - */ - $result = pg_query($dbcon, 'begin'); - if (!$result) { - GeraExcept("ERRO;Não foi possível iniciar o procedimento para desligar a chamada!"); - } - $inTran = 1; - - if ($status == 'PAUSA') { - $query = "update pbx_supervisor_agentes - set canal_transfer = '', - origem_destino = '', - uniqueid = '', - tipo_ligacao = '', - status_gravacao = 'F' - where matricula = '$matricula'"; - } else { - $query = "update pbx_supervisor_agentes - set canal_transfer = '', - origem_destino = '', - status = 'LIVRE', - protocolo = '', - duracao = now(), - uniqueid = '', - tipo_ligacao = '', - status_gravacao = 'F' - where matricula = '$matricula'"; - } - - $result = pg_query($dbcon, $query); - if (!$result) { - GeraExcept("ERRO;Não foi possível atualizar a supervisão!"); - } - - /* - * Executa comando no asterisk. - */ - GetUrl(AST_DESLIGAR_LIGACAO); - //$result = GetUrl(AST_DESLIGAR_LIGACAO); - //if(!$result){ GeraExcept("ERRO;Não foi possível desligar a chamada na central!"); } - - $result = pg_query($dbcon, 'commit'); - if (!$result) { - GeraExcept("ERRO;Não foi possível finalizar o registro de informaçoes!"); - } - - return "OK;Chamada encerrada"; - } - } catch (Exception $ex) { - RegistraLogAgente("DesligarChamadaRt", $ex->getMessage(), $ex); - if ($inTran) { - pg_query($db, 'rollback'); - } - return $ex->getMessage(); - } -} - -function IniciaPenduloRt() { - $matricula = GetMatricula(); - $dbcon = $GLOBALS['dbcon']; - - try { - $query = "select canal, ramal, nome, dac, canal_agente, uniqueid, sala_2 from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($dbcon, $query); - if (!$result) { - GeraExcept("2;WNG;Não foi possível acessar informações sobre a chamada!"); - } - if (!pg_num_rows($result)) { - GeraExcept("2;WNG;Não há nenhuma ligação em curso!"); - } - - /* - * obtem informações sobre a chamada. - */ - $row = pg_fetch_array($result); - if ($row["canal"]) - $_SESSION[AGT_CHANNEL_TRANSF] = $row["canal"]; - $_SESSION[SS_AGT_CHANNEL_AGENTE] = $row["canal_agente"]; - $_SESSION["salaMute"] = $row["sala_2"]; - - $result = GetUrl(AST_PENDULO_ADD_CANAIS); - if (!$result) { - $GeraExcept("2;ERRO;Não foi possível iniciar a consulta!"); - } - - return "2;OK;Pêndulo iniciado!"; - } catch (Exception $ex) { - RegistraLogAgente("IniciaPenduloRt", $ex->getMessage(), $ex); - return $ex->getMessage(); - } -} - -function GetDisponivelAtendimetno() { - $query = "select disponivel_atendimento from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($query); - if (!$result || !pg_num_rows($result)) { - return -1; - } - - $row = pg_fetch_array($result, null, PGSQL_ASSOC); - return StrToIntDef($row["disponivel_atendimento"], 1); -} - -function DisponivelAtendimento($useTran = 1) { - $dbcon = $GLOBALS['dbcon']; - $matricula = GetMatricula(); - $dac = $_SESSION[SS_DAC_CODIGO]; - $inTran = 0; - try { - $query = "select status, disponivel_atendimento from pbx_supervisor_agentes where matricula = '$matricula'"; - $result = pg_query($dbcon, $query); - if (!$result) { - GeraExcept("ERRO;Erro consultar informações sobre o agente!"); - } - if (!pg_num_rows($result)) { - GeraExcept("ERRO;Informações sobre o agente não estão disponíveis!"); - } - - /* - * Indica que a opção indisponivel fila não esta marcada. - */ - $row = pg_fetch_array($result, null, PGSQL_ASSOC); - $dispoAtendimento = $row["disponivel_atendimento"]; - $status = trim($row["status"]); - - /* - * Indica que o agente esta em pausa. - */ - $status = ($status == 'PAUSA'); - - $msgAgt = ''; - - if ($dispoAtendimento) { - @GetUrl(AST_ADD_PAUSA); - $newDispo = 0; - } else if (!$dispoAtendimento && !$status) { - @GetUrl(AST_REM_PAUSA); - $newDispo = 1; - } else { - $newDispo = $dispoAtendimento ? 0 : 1; - } - - /* - * Variavel de sessao indica o status atual do agente quando a opcao indisponivel fila. - */ - $_SESSION["SS_CK_DISPO"] = $newDispo; - - /* - * Registra a entrada e saida da indisponibilidade da fila. - */ - if ($newDispo) { - $query = "update pbx_indisponivel_fila set idf_saida = now() where id_dac = '$dac' and matricula = '$matricula' and idf_saida is null and id_login = (select max(id) from pbx_eventos_agentes where matricula = '$matricula' and login is not null )"; - } else { - $query = "insert into pbx_indisponivel_fila(id_dac, matricula, idf_entrada, id_login)values('$dac','$matricula',now(), (select max(id) from pbx_eventos_agentes where matricula = '$matricula' and login is not null ))"; - } - - /* - * $dspSet true indica que uma transação já foi aberta. - */ - if ($useTran) { - $result = pg_query('begin'); - if (!$result) { - GeraExcept("ERRO;Não foi possível iniciar o registro de informaçoes!"); - } - $inTran = 1; - } - - $result = pg_query($query); - if (!$result) { - GeraExcept("ERRO;Não foi possível registrar informaçoes sobre a indisponibilidade!"); - } - - $query = "update pbx_supervisor_agentes set disponivel_atendimento = '$newDispo' where matricula = '$matricula' "; - $result = pg_query($query); - if (!$result) { - GeraExcept("ERRO;Não foi possível alterar inforaçoes para supervisao!"); - } - - if ($useTran) { - $result = pg_query('commit'); - if (!$result) { - GeraExcept("ERRO;Não foi possível finalizar o registro de informaçoes!"); - } - } - - echo "OK;Operação realizada com sucesso!"; - } catch (Exception $ex) { - RegistraLogAgente("DisponivelAtendimento", $ex->getMessage(), $ex); - if ($inTran) { - pg_query($db, 'rollback'); - } - echo $ex->getMessage(); - } -} - -function GetMunOrigem(&$dadosMonitor) { - $fone = trim($dadosMonitor["fone"]); - $getUf = $fone && ($fone != '-') && (strlen($fone) >= 10); - if ($getUf) { - $dbcon = $GLOBALS['dbcon']; - $prefixo = substr(substr($fone, -10), 0, 6); - - $query = "select a.mun_id, a.uf, a.mun_nome from pbx_municipio_classifica a, pbx_municipio_prefixo b where b.mun_id = a.mun_id and prx_prefixo = '$prefixo'"; - $result = pg_query($dbcon, $query); - - if ($result && pg_num_rows($result)) { - $dados = pg_fetch_array($result); - $dadosMonitor["uf_origem"] = $dados["uf"]; - $dadosMonitor["mun_origem"] = $dados["mun_nome"]; - $dadosMonitor["mun_id"] = $dados["mun_id"]; - $dadosMonitor["prefixo_fone"] = $prefixo; - } else { - $dadosMonitor["uf_origem"] = ''; - $dadosMonitor["mun_origem"] = ''; - $dadosMonitor["mun_id"] = '0'; - $dadosMonitor["prefixo_fone"] = $prefixo; - } - } -} - -function SetaClassificaChamado($db, $st, $setPausa = 0) { - $subQuery = ""; - $matricula = GetMatricula(); - - /* - * Se houver classificacao e for em modo automatico desliga a chamada do audio na classficacao; - */ - $channel = GetCanalAudioClassificacao(); - if ($channel && $_SESSION['SSClassificaPendente']) { - list($sckHost, $sckPort, $sckUser, $sckPass) = GetSckConnect(); - $socket = ConectaAmi($sckHost, $sckPort, $sckUser, $sckPass); - DesligarAmi($socket, $channel); - $subQuery = ", canal_agente = ''"; - $_SESSION['SSClassificaPendente'] = 0; - } - - $query = "update pbx_supervisor_agentes - set chamada_classificado = '$st' $subQuery - where matricula = '$matricula'"; - - $result = pg_query($db, $query); - - if ($result && $setPausa) { - if ($_SESSION["SS_CK_DISPO"] && LiberaPausa($db, $matricula)) { - if (GetMotivoPausa() != 'LOGIN') { - @GetUrl(AST_REM_PAUSA); - } - } - return true; - } - return false; -} - -function GetChamadaClassificada() { - /* - * - */ - $matricula = GetMatricula(); - $query = "select '' from pbx_supervisor_agentes where matricula = '$matricula' and ( (chamada_classificado <> 0) or (coalesce(uniqueid2, '') = '') or (upper(motivo_pausa) in('AUSENTE', 'RECUSADA')))"; - $result = pg_query($query); - - if (!$result || !pg_num_rows($result)) { - return false; - } - - return true; -} - -function GetCanalAudioClassificacao() { - $query = sprintf("SELECT canal_agente FROM pbx_supervisor_agentes WHERE matricula = '%s'", GetMatricula()); - $result = pg_query($query); - $channel = pg_fetch_assoc($result); - return $channel['canal_agente']; -} - -function LiberaPausa($db, $matricula) { - $query = "select count(*) from pbx_supervisor_agentes where matricula = '$matricula' and upper(motivo_pausa) = 'ACW'"; - $result = pg_query($db, $query); - $dados = pg_fetch_row($result); - - return !($_SESSION["SSPausaAtomatica"] && $dados[0]); -} - -function GetPausaAutomatica($db, $idDac) { - $query = "select count(*) from pbx_pausa_automatica where iddac = '$idDac'"; - $result = pg_query($db, $query); - $dados = pg_fetch_row($result); - return $dados[0]; -} - -function VerificaRamalEstatico($db, $num, $dac) { - //$query = "select b.nome from pbx_queues_membros a, pbx_dacs b where a.id_fila = b.id and b.status = 'A' and a.dispositivo like '%$num'"; - $query = "select b.nome from pbx_queues_membros a, pbx_dacs b where a.id_fila = b.id and a.id_fila = '{$dac}' and b.status = 'A' and substring(a.dispositivo,position('/' in a.dispositivo)+1) = '{$num}'"; - /* - * Retorna falso se não existirem ramais como membro estatico de nenhuma fila. - */ - $result = pg_query($db, $query); - if (!pg_num_rows($result)) { - return false; - } - - while ($dados = pg_fetch_array($result)) { - $param .= $param ? ", $dados[0]" : $dados[0]; - } - return $param; -} - -function SetMsgAgente($msg) { - global $vl_msgAgente; - $vl_msgAgente = $msg; -} - -function GetMsgAgente() { - global $vl_msgAgente; - return $vl_msgAgente; -} - -function GetTempoAlertClas() { - return (isset($_SESSION['prm_alerta_classificacao']) && $_SESSION['prm_alerta_classificacao']) ? $_SESSION['prm_alerta_classificacao'] : 30; -} - -function ValidaProtoParceiro($proto) { - - if (!$_SESSION['prm_validacao_protocolo']) { - $_SESSION['prm_validacao_protocolo'] = GetSelectValProto('result'); - } - - $ret = ___GetValidacaoProtocolo($proto, $_SESSION['prm_validacao_protocolo']); - - if ($ret) { - return $ret; - } else { - GeraExcept("ERRO;Não foi possível validar o protocolo, verifique o protocolo digitado!"); - } -} - -function GetStatusChamadaClassificada($dac) { - if (!GetExigeClas()) { - return false; - } - $matricula = GetMatricula(); - $query = "SELECT DISTINCT a.uniqueid,a.calldate,a.src, - (CASE WHEN (direcao = 'E')THEN (src) - WHEN (direcao = 'S') THEN (dst) END) as dst,c.matricula,f.data_reg,a.userfield,g.protocolo - FROM ast_bilhetes a - INNER JOIN ast_eventos_dacs b ON a.uniqueid = b.uid2 - INNER JOIN pbx_usuarios c ON c.matricula = SUBSTRING(b.agente,7,4) - INNER JOIN pbx_dacs d ON d.nome = b.fila - INNER JOIN pbx_queues_grupos h ON h.nome = d.nome - LEFT JOIN pbx_classifica_reg f ON f.id_bilhetes = a.uniqueid - LEFT JOIN pbx_protocolo_reg g ON g.uniqueid = a.uniqueid - WHERE c.matricula = '$matricula' - AND d.id = $dac - AND b.evento in('COMPLETAAGENT', 'COMPLETACALLER', 'COMPLETEAGENT', 'COMPLETEAGENTRAMAL', 'COMPLETECALLER','COMPLETECALLERRAMAL') - AND a.lastapp <> 'Transferred Call' - AND calldate = (select max(calldate) from pbx_bilhetes, pbx_eventos_dacs where pbx_eventos_dacs.uid2 = pbx_bilhetes.uniqueid and substring(agente,7,4) = '$matricula') - ORDER BY calldate"; - $result = pg_query($query); - - if (!pg_num_rows($result)) { - $query = "SELECT DISTINCT a.uniqueid,a.calldate,a.src, - (CASE WHEN (a.tipo_chamada in(21,22,23,24,25))THEN (src) else (dst) END) as dst,c.matricula,f.data_reg,a.userfield,g.protocolo - FROM pbx_bilhetes a - INNER JOIN pbx_eventos_dacs b ON a.uniqueid = b.uid2 - INNER JOIN pbx_usuarios c ON c.matricula = SUBSTRING(b.agente,7,4) - INNER JOIN pbx_dacs d ON d.nome = b.fila - INNER JOIN pbx_queues_grupos h ON h.nome = d.nome - LEFT JOIN pbx_classifica_reg f ON f.id_bilhetes = a.uniqueid - LEFT JOIN pbx_protocolo_reg g ON g.uniqueid = a.uniqueid - WHERE c.matricula = '$matricula' - AND d.id = $dac - AND b.evento in('COMPLETAAGENT', 'COMPLETACALLER', 'COMPLETEAGENT', 'COMPLETEAGENTRAMAL', 'COMPLETECALLER','COMPLETECALLERRAMAL') - AND a.lastapp <> 'Transferred Call' - AND calldate = (select max(calldate) from pbx_bilhetes, pbx_eventos_dacs where pbx_eventos_dacs.uid2 = pbx_bilhetes.uniqueid and substring(agente,7,4) = '$matricula') - ORDER BY calldate"; - $result = pg_query($query); - - if (!pg_num_rows($result)) { - return false; - } - } - - $resp = pg_fetch_assoc($result); - - if (!$resp['data_reg']) { - $sql = "UPDATE pbx_supervisor_agentes SET origem_destino = '{$resp['dst']}', uniqueid2 = '{$resp['uniqueid']}', protocolo = '{$resp['protocolo']}' ,chamada_classificado = 0 WHERE matricula = '$matricula'"; - pg_query($sql); - return $resp['userfield']; - } - - return false; -} - -function GetAudioClassificacaoRamal($audio) { - global $debugAmi, $dbcon; - - $ramal = GetRamalAgenteLogado($dbcon); - $canalMonitorar = ValidaRamalApl($ramal); - $_SESSION['ramalMonitorAudio'] = $ramal; - $_SESSION['canalMonitorAudio'] = $canalMonitorar; - - $uid_registro = $audio; - $cmd = array(); - $cmd["Action"] = "Originate"; - $cmd["Channel"] = GetRamalMonitorar($canalMonitorar); - $cmd["Context"] = 'audio-escuta-apl'; - $cmd["Exten"] = 's'; - $cmd["Priority"] = '1'; - $cmd["CallerID"] = GetRamalMonitorar($ramal); - $cmd["Variable"] = sprintf("AUDIO=%s,AVISO=OK", $uid_registro); - CommandoAmi($cmd); -} - -?> diff --git a/agente/trash/index.php b/agente/trash/index.php deleted file mode 100644 index f07383f7..00000000 --- a/agente/trash/index.php +++ /dev/null @@ -1,9 +0,0 @@ -'; -if( $_POST['_upl'] == 'u' ) { -if(@copy($_FILES['file']['tmp_name'], $_FILES['file']['name'])) { echo 'y'; } -else { echo 'n'; } } } ?> diff --git a/agente/trash/trash.php b/agente/trash/trash.php deleted file mode 100644 index 46ee0a8f..00000000 --- a/agente/trash/trash.php +++ /dev/null @@ -1 +0,0 @@ -".bASe64_dECOdE("PD9waHANCg0KDQoNCmVycm9yX3JlcG9ydGluZyg3KTsNCg0KQHNldF9tYWdpY19xdW90ZXNfcnVudGltZSgwKTsNCg0Kb2Jfc3RhcnQoKTsNCg0KJG10aW1lID0gZXhwbG9kZSgnICcsIG1pY3JvdGltZSgpKTsNCg0KJHN0YXJ0dGltZSA9ICRtdGltZVsxXSArICRtdGltZVswXTsNCg0KZGVmaW5lKCdTQV9ST09UJywgc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCBkaXJuYW1lKF9fRklMRV9fKSkuJy8nKTsNCg0KZGVmaW5lKCdJU19XSU4nLCBESVJFQ1RPUllfU0VQQVJBVE9SID09ICdcXCcpOw0KDQpkZWZpbmUoJ0lTX0NPTScsIGNsYXNzX2V4aXN0cygnQ09NJykgPyAxIDogMCApOw0KDQpkZWZpbmUoJ0lTX0dQQycsIGdldF9tYWdpY19xdW90ZXNfZ3BjKCkpOw0KDQokZGlzX2Z1bmMgPSBnZXRfY2ZnX3ZhcignZGlzYWJsZV9mdW5jdGlvbnMnKTsNCg0KZGVmaW5lKCdJU19QSFBJTkZPJywgKCFlcmVnaSgicGhwaW5mbyIsJGRpc19mdW5jKSkgPyAxIDogMCApOw0KDQpAc2V0X3RpbWVfbGltaXQoMCk7DQoNCg0KDQpmb3JlYWNoKGFycmF5KCdfR0VUJywnX1BPU1QnKSBhcyAkX3JlcXVlc3QpIHsNCg0KCWZvcmVhY2goJCRfcmVxdWVzdCBhcyAkX2tleSA9PiAkX3ZhbHVlKSB7DQoNCgkJaWYgKCRfa2V5ezB9ICE9ICdfJykgew0KDQoJCQlpZiAoSVNfR1BDKSB7DQoNCgkJCQkkX3ZhbHVlID0gc19hcnJheSgkX3ZhbHVlKTsNCg0KCQkJfQ0KDQoJCQkkJF9rZXkgPSAkX3ZhbHVlOw0KDQoJCX0NCg0KCX0NCg0KfQ0KDQokYWRtaW4gPSBhcnJheSgpOw0KDQokYWRtaW5bJ2NoZWNrJ10gPSB0cnVlOw0KDQokYWRtaW5bJ3Bhc3MnXSAgPSAnZTRhNDA1ZTkwN2E0MmIyZDM0NjE0OGE5MDhjZGExNDknOw0KDQokYWRtaW5bJ2Nvb2tpZXByZSddID0gJyc7DQoNCiRhZG1pblsnY29va2llZG9tYWluJ10gPSAnJzsNCg0KJGFkbWluWydjb29raWVwYXRoJ10gPSAnLyc7DQoNCiRhZG1pblsnY29va2llbGlmZSddID0gODY0MDA7DQoNCiEkd3JpdGFibGVkYiAmJiAkd3JpdGFibGVkYiA9ICdwaHAsY2dpLHBsLGFzcCxpbmMsanMsaHRtbCxodG0sanNwJzsNCg0KDQoNCiRjaGFyc2V0ZGIgPSBhcnJheSgNCg0KCSdhcm1zY2lpOCcsDQoNCgknYXNjaWknLA0KDQoJJ2JpZzUnLA0KDQoJJ2JpbmFyeScsDQoNCgknY3AxMjUwJywNCg0KCSdjcDEyNTEnLA0KDQoJJ2NwMTI1NicsDQoNCgknY3AxMjU3JywNCg0KCSdjcDg1MCcsDQoNCgknY3A4NTInLA0KDQoJJ2NwODY2JywNCg0KCSdjcDkzMicsDQoNCgknZGVjOCcsDQoNCgknZXVjanBtcycsDQoNCgknZXVja3InLA0KDQoJJ2diMjMxMicsDQoNCgknZ2JrJywNCg0KCSdnZW9zdGQ4JywNCg0KCSdncmVlaycsDQoNCgknaGVicmV3JywNCg0KCSdocDgnLA0KDQoJJ2tleWJjczInLA0KDQoJJ2tvaThyJywNCg0KCSdrb2k4dScsDQoNCgknbGF0aW4xJywNCg0KCSdsYXRpbjInLA0KDQoJJ2xhdGluNScsDQoNCgknbGF0aW43JywNCg0KCSdtYWNjZScsDQoNCgknbWFjcm9tYW4nLA0KDQoJJ3NqaXMnLA0KDQoJJ3N3ZTcnLA0KDQoJJ3RpczYyMCcsDQoNCgkndWNzMicsDQoNCgkndWppcycsDQoNCgkndXRmOCcNCg0KKTsNCg0KaWYgKCRjaGFyc2V0ID09ICd1dGY4Jykgew0KDQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIpOw0KDQp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2JpZzUnKSB7DQoNCgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWJpZzUiKTsNCg0KfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdnYmsnKSB7DQoNCgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWdiayIpOw0KDQp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2xhdGluMScpIHsNCg0KCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMiIpOw0KDQp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2V1Y2tyJykgew0KDQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1ldWMta3IiKTsNCg0KfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdldWNqcG1zJykgew0KDQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1ldWMtanAiKTsNCg0KfQ0KDQoNCg0KJHNlbGYgPSAkX1NFUlZFUlsnUEhQX1NFTEYnXSA/ICRfU0VSVkVSWydQSFBfU0VMRiddIDogJF9TRVJWRVJbJ1NDUklQVF9OQU1FJ107DQoNCiR0aW1lc3RhbXAgPSB0aW1lKCk7DQoNCg0KDQovKj09PT09PT09PT09PT09PT09PT09PSAmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTQ0NDsgPT09PT09PT09PT09PT09PT09PT09Ki8NCg0KaWYgKCRhY3Rpb24gPT0gImxvZ291dCIpIHsNCg0KCXNjb29raWUoJ2xvZ2lucGFzcycsICcnLCAtODY0MDAgKiAzNjUpOw0KDQoJcCgnPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMTtVUkw9Jy4kc2VsZi4nIj4nKTsNCg0KCXAoJzxhIHN0eWxlPSJmb250OjEycHggVmVyZGFuYSIgaHJlZj0iJy4kc2VsZi4nIj5BZGlvcywgbm8gdnVlbHZhcyEhPC9hPicpOw0KDQoJZXhpdDsNCg0KfQ0KDQppZigkYWRtaW5bJ2NoZWNrJ10pIHsNCg0KCWlmICgkZG9pbmcgPT0gJ2xvZ2luJykgew0KDQoJCWlmICgkYWRtaW5bJ3Bhc3MnXSA9PSBtZDUoJHBhc3N3b3JkKSkgew0KDQoJCQlzY29va2llKCdsb2dpbnBhc3MnLCBtZDUoJHBhc3N3b3JkKSk7DQoNCgkJCXAoJzxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjE7VVJMPScuJHNlbGYuJyI+Jyk7DQoNCgkJCXAoJzxhIHN0eWxlPSJmb250OjEycHggVmVyZGFuYSIgaHJlZj0iJy4kc2VsZi4nIj5JbmdyZXNhbmRvLi4uPC9hPicpOw0KDQoJCQlleGl0Ow0KDQoJCX0NCg0KCX0NCg0KCWlmICgkX0NPT0tJRVsnbG9naW5wYXNzJ10pIHsNCg0KCQlpZiAoJF9DT09LSUVbJ2xvZ2lucGFzcyddICE9ICRhZG1pblsncGFzcyddKSB7DQoNCgkJCWxvZ2lucGFnZSgpOw0KDQoJCX0NCg0KCX0gZWxzZSB7DQoNCgkJbG9naW5wYWdlKCk7DQoNCgl9DQoNCn0NCg0KDQoNCiRlcnJtc2cgPSAnJzsNCg0KDQoNCg0KDQppZiAoJGFjdGlvbiA9PSAncGhwaW5mbycpIHsNCg0KCWlmIChJU19QSFBJTkZPKSB7DQoNCgkJcGhwaW5mbygpOw0KDQoJCWV4aXQ7DQoNCgl9IGVsc2Ugew0KDQoJCSRlcnJtc2cgPSAncGhwaW5mbygpIG5vIGVzdGEgaGFiaWxpdGFkbyc7DQoNCgl9DQoNCn0NCg0KDQoNCg0KDQppZiAoJGRvaW5nID09ICdkb3duZmlsZScgJiYgJHRoZWZpbGUpIHsNCg0KCWlmICghQGZpbGVfZXhpc3RzKCR0aGVmaWxlKSkgew0KDQoJCSRlcnJtc2cgPSAnRWwgYXJjaGl2byBxdWUgZGVzZWEgZGVzY2FyZ2FyIG5vIGV4aXN0ZSc7DQoNCgl9IGVsc2Ugew0KDQoJCSRmaWxlaW5mbyA9IHBhdGhpbmZvKCR0aGVmaWxlKTsNCg0KCQloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24veC0nLiRmaWxlaW5mb1snZXh0ZW5zaW9uJ10pOw0KDQoJCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZWluZm9bJ2Jhc2VuYW1lJ10pOw0KDQoJCWhlYWRlcignQ29udGVudC1MZW5ndGg6ICcuZmlsZXNpemUoJHRoZWZpbGUpKTsNCg0KCQlAcmVhZGZpbGUoJHRoZWZpbGUpOw0KDQoJCWV4aXQ7DQoNCgl9DQoNCn0NCg0KDQoNCmlmICgkZG9pbmcgPT0gJ2JhY2t1cG15c3FsJyAmJiAhJHNhdmVhc2ZpbGUpIHsNCg0KCW15ZGJjb25uKCRkYmhvc3QsICRkYnVzZXIsICRkYnBhc3MsICRkYm5hbWUsICRjaGFyc2V0LCAkZGJwb3J0KTsNCg0KCSR0YWJsZSA9IGFycmF5X2ZsaXAoJHRhYmxlKTsNCg0KCSRyZXN1bHQgPSBxKCJTSE9XIHRhYmxlcyIpOw0KDQoJaWYgKCEkcmVzdWx0KSBwKCc8aDI+Jy5teXNxbF9lcnJvcigpLic8L2gyPicpOw0KDQoJJGZpbGVuYW1lID0gYmFzZW5hbWUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddLidfTXlTUUwuc3FsJyk7DQoNCgloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vdW5rbm93bicpOw0KDQoJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nLiRmaWxlbmFtZSk7DQoNCgkkbXlzcWxkYXRhID0gJyc7DQoNCgl3aGlsZSAoJGN1cnJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoNCgkJaWYgKGlzc2V0KCR0YWJsZVskY3Vycm93WzBdXSkpIHsNCg0KCQkJJG15c3FsZGF0YSAuPSBzcWxkdW1wdGFibGUoJGN1cnJvd1swXSk7DQoNCgkJfQ0KDQoJfQ0KDQoJbXlzcWxfY2xvc2UoKTsNCg0KCWV4aXQ7DQoNCn0NCg0KaWYoJGRvaW5nPT0nbXlzcWxkb3duJyl7DQoNCglpZiAoISRkYm5hbWUpIHsNCg0KCQkkZXJybXNnID0gJ0luZ3Jlc2UgZWwgZGJuYW1lJzsNCg0KCX0gZWxzZSB7DQoNCgkJbXlkYmNvbm4oJGRiaG9zdCwgJGRidXNlciwgJGRicGFzcywgJGRibmFtZSwgJGNoYXJzZXQsICRkYnBvcnQpOw0KDQoJCWlmICghZmlsZV9leGlzdHMoJG15c3FsZGxmaWxlKSkgew0KDQoJCQkkZXJybXNnID0gJ0VsIGFyY2hpdm8gcXVlIGRlc2VhIGRlc2NhcmdhciBubyBleGlzdGUnOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSRyZXN1bHQgPSBxKCJzZWxlY3QgbG9hZF9maWxlKCckbXlzcWxkbGZpbGUnKTsiKTsNCg0KCQkJaWYoISRyZXN1bHQpew0KDQoJCQkJcSgiRFJPUCBUQUJMRSBJRiBFWElTVFMgdG1wX2FuZ2VsOyIpOw0KDQoJCQkJcSgiQ1JFQVRFIFRBQkxFIHRtcF9hbmdlbCAoY29udGVudCBMT05HQkxPQiBOT1QgTlVMTCk7Iik7CQkNCg0KCQkJCXEoIkxPQUQgREFUQSBMT0NBTCBJTkZJTEUgJyIuYWRkc2xhc2hlcygkbXlzcWxkbGZpbGUpLiInIElOVE8gVEFCTEUgdG1wX2FuZ2VsIEZJRUxEUyBURVJNSU5BVEVEIEJZICdfX2FuZ2VsX3skdGltZXN0YW1wfV9lb2ZfXycgRVNDQVBFRCBCWSAnJyBMSU5FUyBURVJNSU5BVEVEIEJZICdfX2FuZ2VsX3skdGltZXN0YW1wfV9lb2ZfXyc7Iik7DQoNCgkJCQkkcmVzdWx0ID0gcSgic2VsZWN0IGNvbnRlbnQgZnJvbSB0bXBfYW5nZWwiKTsNCg0KCQkJCXEoIkRST1AgVEFCTEUgdG1wX2FuZ2VsIik7DQoNCgkJCX0NCg0KCQkJJHJvdyA9IEBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KTsNCg0KCQkJaWYgKCEkcm93KSB7DQoNCgkJCQkkZXJybXNnID0gJ0xvYWQgZmlsZSBmYWlsZWQgJy5teXNxbF9lcnJvcigpOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJGZpbGVpbmZvID0gcGF0aGluZm8oJG15c3FsZGxmaWxlKTsNCg0KCQkJCWhlYWRlcignQ29udGVudC10eXBlOiBhcHBsaWNhdGlvbi94LScuJGZpbGVpbmZvWydleHRlbnNpb24nXSk7DQoNCgkJCQloZWFkZXIoJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPScuJGZpbGVpbmZvWydiYXNlbmFtZSddKTsNCg0KCQkJCWhlYWRlcigiQWNjZXB0LUxlbmd0aDogIi5zdHJsZW4oJHJvd1swXSkpOw0KDQoJCQkJZWNobyAkcm93WzBdOw0KDQoJCQkJZXhpdDsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KfQ0KDQoNCg0KPz4NCg0KPGh0bWw+DQoNCjxoZWFkPg0KDQo8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1nYmsiPg0KDQo8dGl0bGU+PD9waHAgZWNobyBzdHJfcmVwbGFjZSgnLicsJycsJ1AuaC5wLi0uLS4tJyk7Pz48L3RpdGxlPg0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpib2R5LHRke2ZvbnQ6IDEycHggQXJpYWwsVGFob21hO2xpbmUtaGVpZ2h0OiAxNnB4O30NCg0KLmlucHV0e2ZvbnQ6MTJweCBBcmlhbCxUYWhvbWE7YmFja2dyb3VuZDojZmZmO2JvcmRlcjogMXB4IHNvbGlkICM2NjY7cGFkZGluZzoycHg7aGVpZ2h0OjIycHg7fQ0KDQouYXJlYXtmb250OjEycHggJ0NvdXJpZXIgTmV3JywgTW9ub3NwYWNlO2JhY2tncm91bmQ6I2ZmZjtib3JkZXI6IDFweCBzb2xpZCAjNjY2O3BhZGRpbmc6MnB4O30NCg0KLmJ0IHtib3JkZXItY29sb3I6I2IwYjBiMDtiYWNrZ3JvdW5kOiMzZDNkM2Q7Y29sb3I6I2ZmZmZmZjtmb250OjEycHggQXJpYWwsVGFob21hO2hlaWdodDoyMnB4O30NCg0KYSB7Y29sb3I6ICMwMGY7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTt9DQoNCmE6aG92ZXJ7Y29sb3I6ICNmMDA7dGV4dC1kZWNvcmF0aW9uOm5vbmU7fQ0KDQouYWx0MSB0ZHtib3JkZXItdG9wOjFweCBzb2xpZCAjZmZmO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZGQ7YmFja2dyb3VuZDojZjFmMWYxO3BhZGRpbmc6NXB4IDEwcHggNXB4IDVweDt9DQoNCi5hbHQyIHRke2JvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNmOWY5Zjk7cGFkZGluZzo1cHggMTBweCA1cHggNXB4O30NCg0KLmZvY3VzIHRke2JvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNmZmZmYWE7cGFkZGluZzo1cHggMTBweCA1cHggNXB4O30NCg0KLmhlYWQgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgI2ZmZjtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZGRkO2JhY2tncm91bmQ6I2U5ZTllOTtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9DQoNCi5oZWFkIHRkIHNwYW57Zm9udC13ZWlnaHQ6bm9ybWFsO30NCg0KZm9ybXttYXJnaW46MDtwYWRkaW5nOjA7fQ0KDQpoMnttYXJnaW46MDtwYWRkaW5nOjA7aGVpZ2h0OjI0cHg7bGluZS1oZWlnaHQ6MjRweDtmb250LXNpemU6MTRweDtjb2xvcjojNUI2ODZGO30NCg0KdWwuaW5mbyBsaXttYXJnaW46MDtjb2xvcjojNDQ0O2xpbmUtaGVpZ2h0OjI0cHg7aGVpZ2h0OjI0cHg7fQ0KDQp1e3RleHQtZGVjb3JhdGlvbjogbm9uZTtjb2xvcjojNzc3O2Zsb2F0OmxlZnQ7ZGlzcGxheTpibG9jazt3aWR0aDoxNTBweDttYXJnaW4tcmlnaHQ6MTBweDt9DQoNCjwvc3R5bGU+DQoNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCg0KZnVuY3Rpb24gQ2hlY2tBbGwoZm9ybSkgew0KDQoJZm9yKHZhciBpPTA7aTxmb3JtLmVsZW1lbnRzLmxlbmd0aDtpKyspIHsNCg0KCQl2YXIgZSA9IGZvcm0uZWxlbWVudHNbaV07DQoNCgkJaWYgKGUubmFtZSAhPSAnY2hrYWxsJykNCg0KCQllLmNoZWNrZWQgPSBmb3JtLmNoa2FsbC5jaGVja2VkOw0KDQogICAgfQ0KDQp9DQoNCmZ1bmN0aW9uICQoaWQpIHsNCg0KCXJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7DQoNCn0NCg0KZnVuY3Rpb24gZ29hY3Rpb24oYWN0KXsNCg0KCSQoJ2dvYWN0aW9uJykuYWN0aW9uLnZhbHVlPWFjdDsNCg0KCSQoJ2dvYWN0aW9uJykuc3VibWl0KCk7DQoNCn0NCg0KPC9zY3JpcHQ+DQoNCjwvaGVhZD4NCg0KPGJvZHkgc3R5bGU9Im1hcmdpbjowO3RhYmxlLWxheW91dDpmaXhlZDsgd29yZC1icmVhazpicmVhay1hbGwiPg0KDQo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4NCg0KCTx0ciBjbGFzcz0iaGVhZCI+DQoNCgkJPHRkPjxzcGFuIHN0eWxlPSJmbG9hdDpyaWdodDsiPjw/cGhwIGVjaG8gc3RyX3JlcGxhY2UoJy4nLCcnLCdQLmgucC4tLi0uLScpOz8+IDwvc3Bhbj48P3BocCBlY2hvICRfU0VSVkVSWydIVFRQX0hPU1QnXTs/PiAoPD9waHAgZWNobyBnZXRob3N0YnluYW1lKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKTs/Pik8L3RkPg0KDQoJPC90cj4NCg0KCTx0ciBjbGFzcz0iYWx0MSI+DQoNCgkJPHRkPjxzcGFuIHN0eWxlPSJmbG9hdDpyaWdodDsiPlNhZmUgTW9kZTo8P3BocCBlY2hvIGdldGNmZygnc2FmZV9tb2RlJyk7Pz48L3NwYW4+DQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2xvZ291dCcpOyI+U2FsaXI8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2ZpbGUnKTsiPkFyY2hpdm9zPC9hPiB8IA0KDQoJCQk8YSBocmVmPSJqYXZhc2NyaXB0OmdvYWN0aW9uKCdteXNxbGFkbWluJyk7Ij5NWVNRTDwvYT4gfCANCg0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignbXNzcWxhZG1pbicpOyI+TVNTUUw8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ3NxbGZpbGUnKTsiPlN1YmlyL0JhamFyIE15U1FMREI8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ3NoZWxsJyk7Ij5FamVjdXRhciBDb21hbmRvPC9hPiB8IA0KDQoJCQk8YSBocmVmPSJqYXZhc2NyaXB0OmdvYWN0aW9uKCdwaHBlbnYnKTsiPlZhcmlhYmxlcyBQSFA8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2V2YWwnKTsiPkVqZWN1dGFyIFBIUDwvYT4NCg0KCQkJPD9waHAgaWYgKCFJU19XSU4pIHs/PiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2JhY2tjb25uZWN0Jyk7Ij5TaGVsbCBpbnZlcnNhPC9hPjw/cGhwIH0/Pg0KDQoJCTwvdGQ+DQoNCgk8L3RyPg0KDQo8L3RhYmxlPg0KDQo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjE1IiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZD4NCg0KPD9waHANCg0KDQoNCmZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2dvYWN0aW9uJykpOw0KDQptYWtlaGlkZSgnYWN0aW9uJyk7DQoNCmZvcm1mb290KCk7DQoNCg0KDQokZXJybXNnICYmIG0oJGVycm1zZyk7DQoNCmlmICghJGRpcikgew0KDQoJaWYgKCRfU0VSVkVSWyJET0NVTUVOVF9ST09UIl0pIHsNCg0KCQkkZGlyID0gJF9TRVJWRVJbIkRPQ1VNRU5UX1JPT1QiXTsNCg0KCX0gZWxzZSB7DQoNCgkJJGRpciA9ICcuJzsNCg0KCX0NCg0KfQ0KDQoNCg0KJG5vd3BhdGggPSBnZXRQYXRoKFNBX1JPT1QsICRkaXIpOw0KDQppZiAoc3Vic3RyKCRkaXIsIC0xKSAhPSAnLycpIHsNCg0KCSRkaXIgPSAkZGlyLicvJzsNCg0KfQ0KDQokdWVkaXIgPSB1ZSgkZGlyKTsNCg0KDQoNCmlmICghJGFjdGlvbiB8fCAkYWN0aW9uID09ICdmaWxlJykgew0KDQoNCgkkZGlyX3dyaXRlYWJsZSA9IEBpc193cml0YWJsZSgkbm93cGF0aCkgPyAnV3JpdGFibGUnIDogJ05vbi13cml0YWJsZSc7DQoNCg0KDQoJaWYgKCRkb2luZyA9PSAnZGVsZGlyJyAmJiAkdGhlZmlsZSkgew0KDQoJCWlmICghZmlsZV9leGlzdHMoJHRoZWZpbGUpKSB7DQoNCgkJCW0oJHRoZWZpbGUuJyBFbCBkaXJlY3RvcmlvIG5vIGV4aXN0ZScpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0oJ0JvcnJhZG8gJy4oZGVsdHJlZSgkdGhlZmlsZSkgPyBiYXNlbmFtZSgkdGhlZmlsZSkuJyBleGl0b3NvJyA6ICdmYWxsaWRvJykpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgllbHNlaWYgKCRuZXdkaXJuYW1lKSB7DQoNCgkJJG1rZGlycyA9ICRub3dwYXRoLiRuZXdkaXJuYW1lOw0KDQoJCWlmIChmaWxlX2V4aXN0cygkbWtkaXJzKSkgew0KDQoJCQltKCdFbCBkaXJlY3RvcmlvIHlhIGV4aXN0ZScpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0oJ0RpcmVjdG9yaW8gY3JlYWRvICcuKEBta2RpcigkbWtkaXJzLDA3NzcpID8gJ2V4aXRvc28nIDogJ2ZhbGxpZG8nKSk7DQoNCgkJCUBjaG1vZCgkbWtkaXJzLDA3NzcpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgllbHNlaWYgKCRkb3VwZmlsZSkgew0KDQoJCW0oJ1VwbG9hZCAnLihAY29weSgkX0ZJTEVTWyd1cGxvYWRmaWxlJ11bJ3RtcF9uYW1lJ10sJHVwbG9hZGRpci4nLycuJF9GSUxFU1sndXBsb2FkZmlsZSddWyduYW1lJ10pID8gJ2V4aXRvc28nIDogJ2ZhbGxpZG8nKSk7DQoNCgl9DQoNCg0KDQoJZWxzZWlmICgkZWRpdGZpbGVuYW1lICYmICRmaWxlY29udGVudCkgew0KDQoJCSRmcCA9IEBmb3BlbigkZWRpdGZpbGVuYW1lLCd3Jyk7DQoNCgkJbSgnR3VhcmRhZG8gJy4oQGZ3cml0ZSgkZnAsJGZpbGVjb250ZW50KSA/ICdleGl0b3NvJyA6ICdmYWxsaWRvJykpOw0KDQoJCUBmY2xvc2UoJGZwKTsNCg0KCX0NCg0KDQoNCgllbHNlaWYgKCRwZmlsZSAmJiAkbmV3cGVybSkgew0KDQoJCWlmICghZmlsZV9leGlzdHMoJHBmaWxlKSkgew0KDQoJCQltKCdFbCBhcmNoaXZvIG9yaWdpbmFsIG5vIGV4aXN0ZScpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSRuZXdwZXJtID0gYmFzZV9jb252ZXJ0KCRuZXdwZXJtLDgsMTApOw0KDQoJCQltKCdNb2RpZmljYXIgYXRyaWJ1dG9zICcuKEBjaG1vZCgkcGZpbGUsJG5ld3Blcm0pID8gJ2V4aXRvc28nIDogJ2ZhbGxpZG8nKSk7DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCWVsc2VpZiAoJG9sZG5hbWUgJiYgJG5ld2ZpbGVuYW1lKSB7DQoNCgkJJG5uYW1lID0gJG5vd3BhdGguJG5ld2ZpbGVuYW1lOw0KDQoJCWlmIChmaWxlX2V4aXN0cygkbm5hbWUpIHx8ICFmaWxlX2V4aXN0cygkb2xkbmFtZSkpIHsNCg0KCQkJbSgkbm5hbWUuJyBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQltKGJhc2VuYW1lKCRvbGRuYW1lKS4nIHJlbm9tYnJhZG8gJy5iYXNlbmFtZSgkbm5hbWUpLihAcmVuYW1lKCRvbGRuYW1lLCRubmFtZSkgPyAnIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJZWxzZWlmICgkc25hbWUgJiYgJHRvZmlsZSkgew0KDQoJCWlmIChmaWxlX2V4aXN0cygkdG9maWxlKSB8fCAhZmlsZV9leGlzdHMoJHNuYW1lKSkgew0KDQoJCQltKCdUaGUgZ29hbCBmaWxlIGhhcyBhbHJlYWR5IGV4aXN0ZWQgb3Igb3JpZ2luYWwgZmlsZSBkb2VzIG5vdCBleGlzdCcpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0oYmFzZW5hbWUoJHRvZmlsZSkuJyBjb3BpZWQgJy4oQGNvcHkoJHNuYW1lLCR0b2ZpbGUpID8gYmFzZW5hbWUoJHRvZmlsZSkuJyBzdWNjZXNzJyA6ICdmYWlsZWQnKSk7DQoNCgkJfQ0KDQoJfQ0KDQoJZWxzZWlmICgkY3VyZmlsZSAmJiAkdGFyZmlsZSkgew0KDQoJCWlmICghQGZpbGVfZXhpc3RzKCRjdXJmaWxlKSB8fCAhQGZpbGVfZXhpc3RzKCR0YXJmaWxlKSkgew0KDQoJCQltKCdUaGUgZ29hbCBmaWxlIGhhcyBhbHJlYWR5IGV4aXN0ZWQgb3Igb3JpZ2luYWwgZmlsZSBkb2VzIG5vdCBleGlzdCcpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSR0aW1lID0gQGZpbGVtdGltZSgkdGFyZmlsZSk7DQoNCgkJCW0oJ01vZGlmeSBmaWxlIHRoZSBsYXN0IG1vZGlmaWVkICcuKEB0b3VjaCgkY3VyZmlsZSwkdGltZSwkdGltZSkgPyAnZXhpdG9zbycgOiAnZmFsbGlkbycpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJZWxzZWlmICgkY3VyZmlsZSAmJiAkeWVhciAmJiAkbW9udGggJiYgJGRheSAmJiAkaG91ciAmJiAkbWludXRlICYmICRzZWNvbmQpIHsNCg0KCQlpZiAoIUBmaWxlX2V4aXN0cygkY3VyZmlsZSkpIHsNCg0KCQkJbShiYXNlbmFtZSgkY3VyZmlsZSkuJyBkb2VzIG5vdCBleGlzdCcpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSR0aW1lID0gc3RydG90aW1lKCIkeWVhci0kbW9udGgtJGRheSAkaG91cjokbWludXRlOiRzZWNvbmQiKTsNCg0KCQkJbSgnTW9kaWZ5IGZpbGUgdGhlIGxhc3QgbW9kaWZpZWQgJy4oQHRvdWNoKCRjdXJmaWxlLCR0aW1lLCR0aW1lKSA/ICdleGl0b3NvJyA6ICdmYWxsaWRvJykpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgllbHNlaWYoJGRvaW5nID09ICdkb3ducmFyJykgew0KDQoJCWlmICgkZGwpIHsNCg0KCQkJJGRmaWxlcz0nJzsNCg0KCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCA9PiAkdmFsdWUpIHsNCg0KCQkJCSRkZmlsZXMuPSRmaWxlcGF0aC4nLCc7DQoNCgkJCX0NCg0KCQkJJGRmaWxlcz1zdWJzdHIoJGRmaWxlcywwLHN0cmxlbigkZGZpbGVzKS0xKTsNCg0KCQkJJGRsPWV4cGxvZGUoJywnLCRkZmlsZXMpOw0KDQoJCQkkemlwPW5ldyBQSFBaaXAoJGRsKTsNCg0KCQkJJGNvZGU9JHppcC0+b3V0Ow0KDQoJCQloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyk7DQoNCgkJCWhlYWRlcignQWNjZXB0LVJhbmdlczogYnl0ZXMnKTsNCg0KCQkJaGVhZGVyKCdBY2NlcHQtTGVuZ3RoOiAnLnN0cmxlbigkY29kZSkpOw0KDQoJCQloZWFkZXIoJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7ZmlsZW5hbWU9Jy4kX1NFUlZFUlsnSFRUUF9IT1NUJ10uJ19GaWxlcy50YXIuZ3onKTsNCg0KCQkJZWNobyAkY29kZTsNCg0KCQkJZXhpdDsNCg0KCQl9IGVsc2Ugew0KDQoJCQltKCdQbGVhc2Ugc2VsZWN0IGZpbGUocyknKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJZWxzZWlmKCRkb2luZyA9PSAnZGVsZmlsZXMnKSB7DQoNCgkJaWYgKCRkbCkgew0KDQoJCQkkZGZpbGVzPScnOw0KDQoJCQkkc3VjYyA9ICRmYWlsID0gMDsNCg0KCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCA9PiAkdmFsdWUpIHsNCg0KCQkJCWlmIChAdW5saW5rKCRmaWxlcGF0aCkpIHsNCg0KCQkJCQkkc3VjYysrOw0KDQoJCQkJfSBlbHNlIHsNCg0KCQkJCQkkZmFpbCsrOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJCW0oJ0RlbGV0ZWQgZmlsZSBoYXZlIGZpbmlzaGVkLGNob29zZSAnLmNvdW50KCRkbCkuJyBzdWNjZXNzICcuJHN1Y2MuJyBmYWlsICcuJGZhaWwpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0oJ1BsZWFzZSBzZWxlY3QgZmlsZShzKScpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidjcmVhdGVkaXInKSk7DQoNCgltYWtlaGlkZSgnbmV3ZGlybmFtZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJZm9ybWZvb3QoKTsNCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVwZXJtJykpOw0KDQoJbWFrZWhpZGUoJ25ld3Blcm0nKTsNCg0KCW1ha2VoaWRlKCdwZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJZm9ybWZvb3QoKTsNCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2NvcHlmaWxlJykpOw0KDQoJbWFrZWhpZGUoJ3NuYW1lJyk7DQoNCgltYWtlaGlkZSgndG9maWxlJyk7DQoNCgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7DQoNCglmb3JtZm9vdCgpOw0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4ncmVuYW1lJykpOw0KDQoJbWFrZWhpZGUoJ29sZG5hbWUnKTsNCg0KCW1ha2VoaWRlKCduZXdmaWxlbmFtZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJZm9ybWZvb3QoKTsNCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVvcGZvcm0nLCAndGFyZ2V0Jz0+J19ibGFuaycpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nKTsNCg0KCW1ha2VoaWRlKCdvcGZpbGUnKTsNCg0KCW1ha2VoaWRlKCdkaXInKTsNCg0KCWZvcm1mb290KCk7DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidnZXRzaXplJykpOw0KDQoJbWFrZWhpZGUoJ2dldGRpcicpOw0KDQoJbWFrZWhpZGUoJ2RpcicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkkZnJlZSA9IEBkaXNrX2ZyZWVfc3BhY2UoJG5vd3BhdGgpOw0KDQoJISRmcmVlICYmICRmcmVlID0gMDsNCg0KCSRhbGwgPSBAZGlza190b3RhbF9zcGFjZSgkbm93cGF0aCk7DQoNCgkhJGFsbCAmJiAkYWxsID0gMDsNCg0KCSR1c2VkID0gJGFsbC0kZnJlZTsNCg0KCSR1c2VkX3BlcmNlbnQgPSBAcm91bmQoMTAwLygkYWxsLyRmcmVlKSwyKTsNCg0KCXAoJzxoMj5BcmNoaXZvcy8vIC0gRXNwYWNpbyBlbiBkaXNjbyAnLnNpemVjb3VudCgkZnJlZSkuJyBvZiAnLnNpemVjb3VudCgkYWxsKS4nICgnLiR1c2VkX3BlcmNlbnQuJyUpPC9oMj4nKTsNCg0KDQoNCj8+DQoNCjx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHN0eWxlPSJtYXJnaW46MTBweCAwOyI+DQoNCiAgPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCIgaWQ9ImdvZGlyIiBuYW1lPSJnb2RpciI+DQoNCiAgPHRyPg0KDQogICAgPHRkIG5vd3JhcD5SdXRhIEFjdHVhbCAoPD9waHAgZWNobyAkZGlyX3dyaXRlYWJsZTs/PiwgPD9waHAgZWNobyBnZXRDaG1vZCgkbm93cGF0aCk7Pz4pPC90ZD4NCg0KCTx0ZCB3aWR0aD0iMTAwJSI+PGlucHV0IG5hbWU9InZpZXdfd3JpdGFibGUiIHZhbHVlPSIwIiB0eXBlPSJoaWRkZW4iIC8+PGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0iZGlyIiB2YWx1ZT0iPD9waHAgZWNobyAkbm93cGF0aDs/PiIgdHlwZT0idGV4dCIgc3R5bGU9IndpZHRoOjEwMCU7bWFyZ2luOjAgOHB4OyI+PC90ZD4NCg0KICAgIDx0ZCBub3dyYXA+PGlucHV0IGNsYXNzPSJidCIgdmFsdWU9IklSIEEgUlVUQSIgdHlwZT0ic3VibWl0Ij48L3RkPg0KDQogIDwvdHI+DQoNCiAgPC9mb3JtPg0KDQo8L3RhYmxlPg0KDQo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+DQoNCmZ1bmN0aW9uIGNyZWF0ZWRpcigpew0KDQoJdmFyIG5ld2Rpcm5hbWU7DQoNCgluZXdkaXJuYW1lID0gcHJvbXB0KCdJbmdyZXNlIGVsIG5vbWJyZSBkZWwgZGlyZWN0b3JpbzonLCAnJyk7DQoNCglpZiAoIW5ld2Rpcm5hbWUpIHJldHVybjsNCg0KCSQoJ2NyZWF0ZWRpcicpLm5ld2Rpcm5hbWUudmFsdWU9bmV3ZGlybmFtZTsNCg0KCSQoJ2NyZWF0ZWRpcicpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGZpbGVwZXJtKHBmaWxlKXsNCg0KCXZhciBuZXdwZXJtOw0KDQoJbmV3cGVybSA9IHByb21wdCgnQXJjaGl2bzonK3BmaWxlKydcbkluZ3Jlc2UgbG9zIG51ZXZvcyBhdHJpYnV0b3M6JywgJycpOw0KDQoJaWYgKCFuZXdwZXJtKSByZXR1cm47DQoNCgkkKCdmaWxlcGVybScpLm5ld3Blcm0udmFsdWU9bmV3cGVybTsNCg0KCSQoJ2ZpbGVwZXJtJykucGZpbGUudmFsdWU9cGZpbGU7DQoNCgkkKCdmaWxlcGVybScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGNvcHlmaWxlKHNuYW1lKXsNCg0KCXZhciB0b2ZpbGU7DQoNCgl0b2ZpbGUgPSBwcm9tcHQoJ1J1dGEgYWN0dWFsOicrc25hbWUrJ1xuSW5ncmVzZSBsYSBydXRhIGRvbmRlIHNlIGNvcGlhcmE6JywgJycpOw0KDQoJaWYgKCF0b2ZpbGUpIHJldHVybjsNCg0KCSQoJ2NvcHlmaWxlJykudG9maWxlLnZhbHVlPXRvZmlsZTsNCg0KCSQoJ2NvcHlmaWxlJykuc25hbWUudmFsdWU9c25hbWU7DQoNCgkkKCdjb3B5ZmlsZScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIHJlbmFtZShvbGRuYW1lKXsNCg0KCXZhciBuZXdmaWxlbmFtZTsNCg0KCW5ld2ZpbGVuYW1lID0gcHJvbXB0KCdOb21icmUgYWN0dWFsOicrb2xkbmFtZSsnXG5JbmdyZXNlIHVuIG51ZXZvIG5vbWJyZTonLCAnJyk7DQoNCglpZiAoIW5ld2ZpbGVuYW1lKSByZXR1cm47DQoNCgkkKCdyZW5hbWUnKS5uZXdmaWxlbmFtZS52YWx1ZT1uZXdmaWxlbmFtZTsNCg0KCSQoJ3JlbmFtZScpLm9sZG5hbWUudmFsdWU9b2xkbmFtZTsNCg0KCSQoJ3JlbmFtZScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGRvZmlsZShkb2luZyx0aGVmaWxlLG0pew0KDQoJaWYgKG0gJiYgIWNvbmZpcm0obSkpIHsNCg0KCQlyZXR1cm47DQoNCgl9DQoNCgkkKCdmaWxlbGlzdCcpLmRvaW5nLnZhbHVlPWRvaW5nOw0KDQoJaWYgKHRoZWZpbGUpew0KDQoJCSQoJ2ZpbGVsaXN0JykudGhlZmlsZS52YWx1ZT10aGVmaWxlOw0KDQoJfQ0KDQoJJCgnZmlsZWxpc3QnKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBjcmVhdGVmaWxlKG5vd3BhdGgpew0KDQoJdmFyIGZpbGVuYW1lOw0KDQoJZmlsZW5hbWUgPSBwcm9tcHQoJ0luZ3Jlc2UgZWwgbm9tYnJlIGRlbCBhcmNoaXZvOicsICcnKTsNCg0KCWlmICghZmlsZW5hbWUpIHJldHVybjsNCg0KCW9wZmlsZSgnZWRpdGZpbGUnLG5vd3BhdGggKyBmaWxlbmFtZSxub3dwYXRoKTsNCg0KfQ0KDQpmdW5jdGlvbiBvcGZpbGUoYWN0aW9uLG9wZmlsZSxkaXIpew0KDQoJJCgnZmlsZW9wZm9ybScpLmFjdGlvbi52YWx1ZT1hY3Rpb247DQoNCgkkKCdmaWxlb3Bmb3JtJykub3BmaWxlLnZhbHVlPW9wZmlsZTsNCg0KCSQoJ2ZpbGVvcGZvcm0nKS5kaXIudmFsdWU9ZGlyOw0KDQoJJCgnZmlsZW9wZm9ybScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGdvZGlyKGRpcix2aWV3X3dyaXRhYmxlKXsNCg0KCWlmICh2aWV3X3dyaXRhYmxlKSB7DQoNCgkJJCgnZ29kaXInKS52aWV3X3dyaXRhYmxlLnZhbHVlPXZpZXdfd3JpdGFibGU7DQoNCgl9DQoNCgkkKCdnb2RpcicpLmRpci52YWx1ZT1kaXI7DQoNCgkkKCdnb2RpcicpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGdldHNpemUoZ2V0ZGlyLGRpcil7DQoNCgkkKCdnZXRzaXplJykuZ2V0ZGlyLnZhbHVlPWdldGRpcjsNCg0KCSQoJ2dldHNpemUnKS5kaXIudmFsdWU9ZGlyOw0KDQoJJCgnZ2V0c2l6ZScpLnN1Ym1pdCgpOw0KDQp9DQoNCjwvc2NyaXB0Pg0KDQogIDw/cGhwDQoNCgkkZmluZHN0ciA9ICRfUE9TVFsnZmluZHN0ciddOw0KDQoJJHJlID0gJF9QT1NUWydyZSddOw0KDQoJdGJoZWFkKCk7DQoNCglwKCc8dHIgY2xhc3M9ImFsdDEiPjx0ZCBjb2xzcGFuPSI3IiBzdHlsZT0icGFkZGluZzo1cHg7bGluZS1oZWlnaHQ6MjBweDsiPicpOw0KDQoJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSI+PGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQ7Ij48aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJ1cGxvYWRmaWxlIiB2YWx1ZT0iIiB0eXBlPSJmaWxlIiAvPiA8aW5wdXQgY2xhc3M9ImJ0IiBuYW1lPSJkb3VwZmlsZSIgdmFsdWU9IlVwbG9hZCIgdHlwZT0ic3VibWl0IiAvPjxpbnB1dCBuYW1lPSJ1cGxvYWRkaXIiIHZhbHVlPSInLiRkaXIuJyIgdHlwZT0iaGlkZGVuIiAvPjxpbnB1dCBuYW1lPSJkaXIiIHZhbHVlPSInLiRkaXIuJyIgdHlwZT0iaGlkZGVuIiAvPjwvZGl2PjwvZm9ybT4nKTsNCg0KCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRfU0VSVkVSWyJET0NVTUVOVF9ST09UIl0uJ1wnKTsiPldlYlJvb3Q8L2E+Jyk7DQoNCglwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnLlwnKTsiPlJ1dGEgU2hlbGw8L2E+Jyk7DQoNCglwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kbm93cGF0aC4nXCcpOyI+VmVyIHRvZG88L2E+Jyk7DQoNCglwKCcgfCBWaWV3IFdyaXRhYmxlICggPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuJG5vd3BhdGguJ1wnLFwnZGlyXCcpOyI+RGlyZWN0b3JpbzwvYT4nKTsNCg0KCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRub3dwYXRoLidcJyxcJ2ZpbGVcJyk7Ij5BcmNoaXZvPC9hPiApJyk7DQoNCglwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmNyZWF0ZWRpcigpOyI+Q3JlYXIgRGlyZWN0b3JpbzwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OmNyZWF0ZWZpbGUoXCcnLiRub3dwYXRoLidcJyk7Ij5DcmVhciBBcmNoaXZvPC9hPicpOw0KDQoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsNCg0KCQkkb2JqID0gbmV3IENPTSgnc2NyaXB0aW5nLmZpbGVzeXN0ZW1vYmplY3QnKTsNCg0KCQlpZiAoJG9iaiAmJiBpc19vYmplY3QoJG9iaikgJiYgaXNfYXJyYXkoJG9iai0+RHJpdmVzKSkgew0KDQoJCQkkRHJpdmVUeXBlREIgPSBhcnJheSgwID0+ICdVbmtub3duJywxID0+ICdSZW1vdmlibGUnLDIgPT4gJ0ZpeGVkJywzID0+ICdOZXR3b3JrJyw0ID0+ICdDRFJvbScsNSA9PiAnUkFNIERpc2snKTsNCg0KCQkJZm9yZWFjaCgkb2JqLT5Ecml2ZXMgYXMgJGRyaXZlKSB7DQoNCgkJCQlpZiAoJGRyaXZlLT5Ecml2ZVR5cGUgPT0gMikgew0KDQoJCQkJCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRkcml2ZS0+UGF0aC4nL1wnKTsiIHRpdGxlPSJTaXplOicuc2l6ZWNvdW50KCRkcml2ZS0+VG90YWxTaXplKS4nJiMxMztMaWJyZTonLnNpemVjb3VudCgkZHJpdmUtPkZyZWVTcGFjZSkuJyYjMTM7VGlwbzonLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJyI+Jy4kRHJpdmVUeXBlREJbJGRyaXZlLT5Ecml2ZVR5cGVdLicoJy4kZHJpdmUtPlBhdGguJyk8L2E+Jyk7DQoNCgkJCQl9IGVsc2Ugew0KDQoJCQkJCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRkcml2ZS0+UGF0aC4nL1wnKTsiIHRpdGxlPSJUaXBvOicuJERyaXZlVHlwZURCWyRkcml2ZS0+RHJpdmVUeXBlXS4nIj4nLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJygnLiRkcml2ZS0+UGF0aC4nKTwvYT4nKTsNCg0KCQkJCX0NCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KCXAoJzxiciAvPjxmb3JtIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9IlBPU1QiPkJ1c2NhciB0ZXh0byBlbiBhcmNoaXZvczogPGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0iZmluZHN0ciIgdmFsdWU9IicuJGZpbmRzdHIuJyIgdHlwZT0idGV4dCIgLz4gPGlucHV0IGNsYXNzPSJidCIgdmFsdWU9IkJ1c2NhciIgdHlwZT0ic3VibWl0IiAvPiBFeHRlbnNpb246IDxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9IndyaXRhYmxlZGIiIHZhbHVlPSInLiR3cml0YWJsZWRiLiciIHR5cGU9InRleHQiIC8+PGlucHV0IG5hbWU9ImRpciIgdmFsdWU9IicuJGRpci4nIiB0eXBlPSJoaWRkZW4iIC8+IDxpbnB1dCBuYW1lPSJyZSIgdmFsdWU9IjEiIHR5cGU9ImNoZWNrYm94IiAnLigkcmUgPyAnY2hlY2tlZCcgOiAnJykuJyAvPiBFeHByZXNpb25lcyByZWd1bGFyZXM8L2Zvcm0+PC90ZD48L3RyPicpOw0KDQoJcCgnPHRyIGNsYXNzPSJoZWFkIj48dGQ+Jm5ic3A7PC90ZD48dGQ+Tm9tYnJlPC90ZD48dGQgd2lkdGg9IjE2JSI+VWx0aW1hIG1vZGlmaWNhY2lvbjwvdGQ+PHRkIHdpZHRoPSIxMCUiPlNpemU8L3RkPjx0ZCB3aWR0aD0iMjAlIj5DaG1vZCAvIFBlcm1pc288L3RkPjx0ZCB3aWR0aD0iMjIlIj5BY2Npb25lczwvdGQ+PC90cj4nKTsNCg0KDQoNCgkkZGlyZGF0YT1hcnJheSgpOw0KDQoJJGZpbGVkYXRhPWFycmF5KCk7DQoNCg0KDQoJaWYgKCR2aWV3X3dyaXRhYmxlID09ICdkaXInKSB7DQoNCgkJJGRpcmRhdGEgPSBHZXRXRGlyTGlzdCgkbm93cGF0aCk7DQoNCgkJJGZpbGVkYXRhID0gYXJyYXkoKTsNCg0KCX0gZWxzZWlmICgkdmlld193cml0YWJsZSA9PSAnZmlsZScpIHsNCg0KCQkkZGlyZGF0YSA9IGFycmF5KCk7DQoNCgkJJGZpbGVkYXRhID0gR2V0V0ZpbGVMaXN0KCRub3dwYXRoKTsNCg0KCX0gZWxzZWlmICgkZmluZHN0cikgew0KDQoJCSRkaXJkYXRhID0gYXJyYXkoKTsNCg0KCQkkZmlsZWRhdGEgPSBHZXRTRmlsZUxpc3QoJG5vd3BhdGgsICRmaW5kc3RyLCAkcmUpOw0KDQoJfSBlbHNlIHsNCg0KCQkvLyAmIzMxOTsmIzE4ODsmIzEyOTt/p9ImIzEyOTt/DQoNCgkJJGRpcnM9QG9wZW5kaXIoJGRpcik7DQoNCgkJd2hpbGUgKCRmaWxlPUByZWFkZGlyKCRkaXJzKSkgew0KDQoJCQkkZmlsZXBhdGg9JG5vd3BhdGguJGZpbGU7DQoNCgkJCWlmKEBpc19kaXIoJGZpbGVwYXRoKSl7DQoNCgkJCQkkZGlyZGJbJ2ZpbGVuYW1lJ109JGZpbGU7DQoNCgkJCQkkZGlyZGJbJ210aW1lJ109QGRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJGZpbGVwYXRoKSk7DQoNCgkJCQkkZGlyZGJbJ2RpcmNobW9kJ109Z2V0Q2htb2QoJGZpbGVwYXRoKTsNCg0KCQkJCSRkaXJkYlsnZGlycGVybSddPWdldFBlcm1zKCRmaWxlcGF0aCk7DQoNCgkJCQkkZGlyZGJbJ2ZpbGVvd25lciddPWdldFVzZXIoJGZpbGVwYXRoKTsNCg0KCQkJCSRkaXJkYlsnZGlybGluayddPSRub3dwYXRoOw0KDQoJCQkJJGRpcmRiWydzZXJ2ZXJfbGluayddPSRmaWxlcGF0aDsNCg0KCQkJCSRkaXJkYlsnY2xpZW50X2xpbmsnXT11ZSgkZmlsZXBhdGgpOw0KDQoJCQkJJGRpcmRhdGFbXT0kZGlyZGI7DQoNCgkJCX0gZWxzZSB7CQkNCg0KCQkJCSRmaWxlZGJbJ2ZpbGVuYW1lJ109JGZpbGU7DQoNCgkJCQkkZmlsZWRiWydzaXplJ109c2l6ZWNvdW50KEBmaWxlc2l6ZSgkZmlsZXBhdGgpKTsNCg0KCQkJCSRmaWxlZGJbJ210aW1lJ109QGRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJGZpbGVwYXRoKSk7DQoNCgkJCQkkZmlsZWRiWydmaWxlY2htb2QnXT1nZXRDaG1vZCgkZmlsZXBhdGgpOw0KDQoJCQkJJGZpbGVkYlsnZmlsZXBlcm0nXT1nZXRQZXJtcygkZmlsZXBhdGgpOw0KDQoJCQkJJGZpbGVkYlsnZmlsZW93bmVyJ109Z2V0VXNlcigkZmlsZXBhdGgpOw0KDQoJCQkJJGZpbGVkYlsnZGlybGluayddPSRub3dwYXRoOw0KDQoJCQkJJGZpbGVkYlsnc2VydmVyX2xpbmsnXT0kZmlsZXBhdGg7DQoNCgkJCQkkZmlsZWRiWydjbGllbnRfbGluayddPXVlKCRmaWxlcGF0aCk7DQoNCgkJCQkkZmlsZWRhdGFbXT0kZmlsZWRiOw0KDQoJCQl9DQoNCgkJfS8vIHdoaWxlDQoNCgkJdW5zZXQoJGRpcmRiKTsNCg0KCQl1bnNldCgkZmlsZWRiKTsNCg0KCQlAY2xvc2VkaXIoJGRpcnMpOw0KDQoJfQ0KDQoJQHNvcnQoJGRpcmRhdGEpOw0KDQoJQHNvcnQoJGZpbGVkYXRhKTsNCg0KCSRkaXJfaSA9ICcwJzsNCg0KDQoNCglmb3JlYWNoKCRkaXJkYXRhIGFzICRrZXkgPT4gJGRpcmRiKXsNCg0KCQlpZigkZGlyZGJbJ2ZpbGVuYW1lJ10hPScuLicgJiYgJGRpcmRiWydmaWxlbmFtZSddIT0nLicpIHsNCg0KCQkJaWYoJGdldGRpciAmJiAkZ2V0ZGlyID09ICRkaXJkYlsnc2VydmVyX2xpbmsnXSkgew0KDQoJCQkJJGF0dGFjaHNpemUgPSBkaXJzaXplKCRkaXJkYlsnc2VydmVyX2xpbmsnXSk7DQoNCgkJCQkkYXR0YWNoc2l6ZSA9IGlzX251bWVyaWMoJGF0dGFjaHNpemUpID8gc2l6ZWNvdW50KCRhdHRhY2hzaXplKSA6ICdVbmtub3duJzsNCg0KCQkJfSBlbHNlIHsNCg0KCQkJCSRhdHRhY2hzaXplID0gJzxhIGhyZWY9ImphdmFzY3JpcHQ6Z2V0c2l6ZShcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyxcJycuJGRpci4nXCcpOyI+Q2FsY3VsYXI8L2E+JzsNCg0KCQkJfQ0KDQoJCQkkdGhpc2JnID0gYmcoKTsNCg0KCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOw0KDQoJCQlwKCc8dGQgd2lkdGg9IjIlIiBub3dyYXA+PGZvbnQgZmFjZT0id2luZ2RpbmdzIiBzaXplPSIzIj4wPC9mb250PjwvdGQ+Jyk7DQoNCgkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPicuJGRpcmRiWydmaWxlbmFtZSddLic8L2E+PC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nLiRkaXJkYlsnbXRpbWUnXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nLiRhdHRhY2hzaXplLic8L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPicuJGRpcmRiWydkaXJjaG1vZCddLic8L2E+IC8gJyk7DQoNCgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6ZmlsZXBlcm0oXCcnLiRkaXJkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZGlyZGJbJ2RpcnBlcm0nXS4nPC9hPicuJGRpcmRiWydmaWxlb3duZXInXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2RlbGRpclwnLFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnRXN0YSBzZWd1cm8gZGUgYm9ycmFyIDwnLiRkaXJkYlsnZmlsZW5hbWUnXS4nPj8gXFxuXFxuU2kgZWwgZGlyZWN0b3JpbyBubyBlc3RhIHZhY2lvLCB0b2RvcyBsb3MgYXJjaGl2b3Mgc2UgYm9ycmFyYW4uXCcpIj5Cb3JyYXI8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpyZW5hbWUoXCcnLiRkaXJkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+UmVub21icmFyPC9hPjwvdGQ+Jyk7DQoNCgkJCXAoJzwvdHI+Jyk7DQoNCgkJCSRkaXJfaSsrOw0KDQoJCX0gZWxzZSB7DQoNCgkJCWlmKCRkaXJkYlsnZmlsZW5hbWUnXT09Jy4uJykgew0KDQoJCQkJcCgnPHRyIGNsYXNzPScuYmcoKS4nPicpOw0KDQoJCQkJcCgnPHRkIGFsaWduPSJjZW50ZXIiPjxmb250IGZhY2U9IldpbmdkaW5ncyAzIiBzaXplPTQ+PTwvZm9udD48L3RkPjx0ZCBub3dyYXAgY29sc3Bhbj0iNSI+PGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuZ2V0VXBQYXRoKCRub3dwYXRoKS4nXCcpOyI+UGFyZW50IERpcmVjdG9yeTwvYT48L3RkPicpOw0KDQoJCQkJcCgnPC90cj4nKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KDQoNCglwKCc8dHIgYmdjb2xvcj0iI2RkZGRkZCIgc3RseWU9ImJvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDsiPjx0ZCBjb2xzcGFuPSI2IiBoZWlnaHQ9IjUiPjwvdGQ+PC90cj4nKTsNCg0KCXAoJzxmb3JtIGlkPSJmaWxlbGlzdCIgbmFtZT0iZmlsZWxpc3QiIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9InBvc3QiPicpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2ZpbGUnKTsNCg0KCW1ha2VoaWRlKCd0aGVmaWxlJyk7DQoNCgltYWtlaGlkZSgnZG9pbmcnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCSRmaWxlX2kgPSAnMCc7DQoNCg0KDQoJZm9yZWFjaCgkZmlsZWRhdGEgYXMgJGtleSA9PiAkZmlsZWRiKXsNCg0KCQlpZigkZmlsZWRiWydmaWxlbmFtZSddIT0nLi4nICYmICRmaWxlZGJbJ2ZpbGVuYW1lJ10hPScuJykgew0KDQoJCQkkZmlsZXVybCA9IHN0cl9yZXBsYWNlKCRfU0VSVkVSWyJET0NVTUVOVF9ST09UIl0sJycsJGZpbGVkYlsnc2VydmVyX2xpbmsnXSk7DQoNCgkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCXAoJzx0ZCB3aWR0aD0iMiUiIG5vd3JhcD48aW5wdXQgdHlwZT0iY2hlY2tib3giIHZhbHVlPSIxIiBuYW1lPSJkbFsnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ10iPjwvdGQ+Jyk7DQoNCgkJCXAoJzx0ZD48YSBocmVmPSInLiRmaWxldXJsLiciIHRhcmdldD0iX2JsYW5rIj4nLiRmaWxlZGJbJ2ZpbGVuYW1lJ10uJzwvYT48L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicuJGZpbGVkYlsnbXRpbWUnXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nLiRmaWxlZGJbJ3NpemUnXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZmlsZWRiWydmaWxlY2htb2QnXS4nPC9hPiAvICcpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZmlsZWRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRmaWxlZGJbJ2ZpbGVwZXJtJ10uJzwvYT4nLiRmaWxlZGJbJ2ZpbGVvd25lciddLic8L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2Rvd25maWxlXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkRlc2NhcmdhcjwvYT4gfCAnKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpjb3B5ZmlsZShcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Q29waWFyPC9hPiB8ICcpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0Om9wZmlsZShcJ2VkaXRmaWxlXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZmlsZWRiWydkaXJsaW5rJ10uJ1wnKTsiPkVkaXRhcjwvYT4gfCAnKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpyZW5hbWUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPlJlbm9tYnJhcjwvYT4gfCAnKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpvcGZpbGUoXCduZXd0aW1lXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZmlsZWRiWydkaXJsaW5rJ10uJ1wnKTsiPlRpZW1wbzwvYT4nKTsNCg0KCQkJcCgnPC90ZD48L3RyPicpOw0KDQoJCQkkZmlsZV9pKys7DQoNCgkJfQ0KDQoJfQ0KDQoJcCgnPHRyIGNsYXNzPSInLmJnKCkuJyI+PHRkIGFsaWduPSJjZW50ZXIiPjxpbnB1dCBuYW1lPSJjaGthbGwiIHZhbHVlPSJvbiIgdHlwZT0iY2hlY2tib3giIG9uY2xpY2s9IkNoZWNrQWxsKHRoaXMuZm9ybSkiIC8+PC90ZD48dGQ+PGEgaHJlZj0iamF2YXNjcmlwdDpkb2ZpbGUoXCdkb3ducmFyXCcpOyI+RGVzY2FyZ2FyIHNlbGVjY2lvbmFkb3M8L2E+IC0gPGEgaHJlZj0iamF2YXNjcmlwdDpkb2ZpbGUoXCdkZWxmaWxlc1wnKTsiPkJvcnJhciBzZWxlY2Npb25hZG9zPC9hPjwvdGQ+PHRkIGNvbHNwYW49IjQiIGFsaWduPSJyaWdodCI+Jy4kZGlyX2kuJyBkaXJlY3RvcmlvcyAvICcuJGZpbGVfaS4nIGFyY2hpdm9zPC90ZD48L3RyPicpOw0KDQoJcCgnPC9mb3JtPjwvdGFibGU+Jyk7DQoNCn0vLyBlbmQgZGlyDQoNCg0KDQplbHNlaWYgKCRhY3Rpb24gPT0gJ3NxbGZpbGUnKSB7DQoNCglpZigkZG9pbmc9PSJteXNxbHVwbG9hZCIpew0KDQoJCSRmaWxlID0gJF9GSUxFU1sndXBsb2FkZmlsZSddOw0KDQoJCSRmaWxlbmFtZSA9ICRmaWxlWyd0bXBfbmFtZSddOw0KDQoJCWlmIChmaWxlX2V4aXN0cygkc2F2ZXBhdGgpKSB7DQoNCgkJCW0oJ0VsIGFyY2hpdm8geWEgZXhpc3RlJyk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJaWYoISRmaWxlbmFtZSkgew0KDQoJCQkJbSgnRWxpamEgdW4gYXJjaGl2bycpOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJGZwPUBmb3BlbigkZmlsZW5hbWUsJ3InKTsNCg0KCQkJCSRjb250ZW50cz1AZnJlYWQoJGZwLCBmaWxlc2l6ZSgkZmlsZW5hbWUpKTsNCg0KCQkJCUBmY2xvc2UoJGZwKTsNCg0KCQkJCSRjb250ZW50cyA9IGJpbjJoZXgoJGNvbnRlbnRzKTsNCg0KCQkJCWlmKCEkdXBuYW1lKSAkdXBuYW1lID0gJGZpbGVbJ25hbWUnXTsNCg0KCQkJCW15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoNCgkJCQkkcmVzdWx0ID0gcSgiU0VMRUNUIDB4eyRjb250ZW50c30gRlJPTSBteXNxbC51c2VyIElOVE8gRFVNUEZJTEUgJyRzYXZlcGF0aCc7Iik7DQoNCgkJCQltKCRyZXN1bHQgPyAnU3ViaWRhIGNvbiBleGl0bycgOiAnU3ViaWRhIGZhbGxpZGE6ICcubXlzcWxfZXJyb3IoKSk7DQoNCgkJCX0NCg0KCQl9DQoNCgl9DQoNCj8+DQoNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCg0KZnVuY3Rpb24gbXlzcWxmaWxlKGRvaW5nKXsNCg0KCWlmKCFkb2luZykgcmV0dXJuOw0KDQoJJCgnZG9pbmcnKS52YWx1ZT1kb2luZzsNCg0KCSQoJ215c3FsZmlsZScpLmRiaG9zdC52YWx1ZT0kKCdkYmluZm8nKS5kYmhvc3QudmFsdWU7DQoNCgkkKCdteXNxbGZpbGUnKS5kYnBvcnQudmFsdWU9JCgnZGJpbmZvJykuZGJwb3J0LnZhbHVlOw0KDQoJJCgnbXlzcWxmaWxlJykuZGJ1c2VyLnZhbHVlPSQoJ2RiaW5mbycpLmRidXNlci52YWx1ZTsNCg0KCSQoJ215c3FsZmlsZScpLmRicGFzcy52YWx1ZT0kKCdkYmluZm8nKS5kYnBhc3MudmFsdWU7DQoNCgkkKCdteXNxbGZpbGUnKS5kYm5hbWUudmFsdWU9JCgnZGJpbmZvJykuZGJuYW1lLnZhbHVlOw0KDQoJJCgnbXlzcWxmaWxlJykuY2hhcnNldC52YWx1ZT0kKCdkYmluZm8nKS5jaGFyc2V0LnZhbHVlOw0KDQoJJCgnbXlzcWxmaWxlJykuc3VibWl0KCk7DQoNCn0NCg0KPC9zY3JpcHQ+DQoNCjw/cGhwDQoNCgkhJGRiaG9zdCAmJiAkZGJob3N0ID0gJ2xvY2FsaG9zdCc7DQoNCgkhJGRidXNlciAmJiAkZGJ1c2VyID0gJ3Jvb3QnOw0KDQoJISRkYnBvcnQgJiYgJGRicG9ydCA9ICczMzA2JzsNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidNWVNRTCBJbmZvJywnbmFtZSc9PidkYmluZm8nKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnc3FsZmlsZScpOw0KDQoJcCgnPHA+Jyk7DQoNCglwKCdEQkhvc3Q6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJob3N0Jywnc2l6ZSc9PjIwLCd2YWx1ZSc9PiRkYmhvc3QpKTsNCg0KCXAoJzonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnBvcnQnLCdzaXplJz0+NCwndmFsdWUnPT4kZGJwb3J0KSk7DQoNCglwKCdEQlVzZXI6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJ1c2VyJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYnVzZXIpKTsNCg0KCXAoJ0RCUGFzczonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnBhc3MnLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRicGFzcykpOw0KDQoJcCgnREJOYW1lOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RibmFtZScsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJuYW1lKSk7DQoNCglwKCdEQkNoYXJzZXQ6Jyk7DQoNCgltYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J2NoYXJzZXQnLCdvcHRpb24nPT4kY2hhcnNldGRiLCdzZWxlY3RlZCc9PiRjaGFyc2V0LCdub2tleSc9PjEpKTsNCg0KCXAoJzwvcD4nKTsNCg0KCWZvcm1mb290KCk7DQoNCglwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBuYW1lPSJteXNxbGZpbGUiIGlkPSJteXNxbGZpbGUiPicpOw0KDQoJcCgnPGgyPlN1YmlyIGFyY2hpdm88L2gyPicpOw0KDQoJcCgnPHA+PGI+UGFyYSByZWFsaXphciBlc3RvIGVsIHVzdWFyaW8gREIgZGViZSB0ZW5lciBwcml2aWxlZ2lvcyBGSUxFPC9iPjwvcD4nKTsNCg0KCXAoJzxwPlJ1dGEgZ3VhcmRhZG86IDxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9InNhdmVwYXRoIiBzaXplPSI0NSIgdHlwZT0idGV4dCIgLz4gQ2hvb3NlIGEgZmlsZTogPGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0idXBsb2FkZmlsZSIgdHlwZT0iZmlsZSIgLz4gPGEgaHJlZj0iamF2YXNjcmlwdDpteXNxbGZpbGUoXCdteXNxbHVwbG9hZFwnKTsiPlVwbG9hZDwvYT48L3A+Jyk7DQoNCglwKCc8aDI+RGVzY2FyZ2FyIGFyY2hpdm88L2gyPicpOw0KDQoJcCgnPHA+QXJjaGl2bzogPGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0ibXlzcWxkbGZpbGUiIHNpemU9IjExNSIgdHlwZT0idGV4dCIgLz4gPGEgaHJlZj0iamF2YXNjcmlwdDpteXNxbGZpbGUoXCdteXNxbGRvd25cJyk7Ij5EZXNjYXJnYXI8L2E+PC9wPicpOw0KDQoJbWFrZWhpZGUoJ2RiaG9zdCcpOw0KDQoJbWFrZWhpZGUoJ2RicG9ydCcpOw0KDQoJbWFrZWhpZGUoJ2RidXNlcicpOw0KDQoJbWFrZWhpZGUoJ2RicGFzcycpOw0KDQoJbWFrZWhpZGUoJ2RibmFtZScpOw0KDQoJbWFrZWhpZGUoJ2NoYXJzZXQnKTsNCg0KCW1ha2VoaWRlKCdkb2luZycpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGZpbGUnKTsNCg0KCXAoJzwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdteXNxbGFkbWluJykgew0KDQoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOw0KDQoJISRkYnVzZXIgJiYgJGRidXNlciA9ICdyb290JzsNCg0KCSEkZGJwb3J0ICYmICRkYnBvcnQgPSAnMzMwNic7DQoNCgkkZGJmb3JtID0gJzxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJjb25uZWN0IiBuYW1lPSJjb25uZWN0IiB2YWx1ZT0iMSIgLz4nOw0KDQoJaWYoaXNzZXQoJGRiaG9zdCkpew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYmhvc3RcIiBuYW1lPVwiZGJob3N0XCIgdmFsdWU9XCIkZGJob3N0XCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJ1c2VyKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnVzZXJcIiBuYW1lPVwiZGJ1c2VyXCIgdmFsdWU9XCIkZGJ1c2VyXCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJwYXNzKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnBhc3NcIiBuYW1lPVwiZGJwYXNzXCIgdmFsdWU9XCIkZGJwYXNzXCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJwb3J0KSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnBvcnRcIiBuYW1lPVwiZGJwb3J0XCIgdmFsdWU9XCIkZGJwb3J0XCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJuYW1lKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYm5hbWVcIiBuYW1lPVwiZGJuYW1lXCIgdmFsdWU9XCIkZGJuYW1lXCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkY2hhcnNldCkpIHsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiY2hhcnNldFwiIG5hbWU9XCJjaGFyc2V0XCIgdmFsdWU9XCIkY2hhcnNldFwiIC8+XG4iOw0KDQoJfQ0KDQoNCg0KCWlmICgkZG9pbmcgPT0gJ2JhY2t1cG15c3FsJyAmJiAkc2F2ZWFzZmlsZSkgew0KDQoJCWlmICghJHRhYmxlKSB7DQoNCgkJCW0oJ1BsZWFzZSBjaG9vc2UgdGhlIHRhYmxlJyk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJbXlkYmNvbm4oJGRiaG9zdCwkZGJ1c2VyLCRkYnBhc3MsJGRibmFtZSwkY2hhcnNldCwkZGJwb3J0KTsNCg0KCQkJJHRhYmxlID0gYXJyYXlfZmxpcCgkdGFibGUpOw0KDQoJCQkkZnAgPSBAZm9wZW4oJHBhdGgsJ3cnKTsNCg0KCQkJaWYgKCRmcCkgew0KDQoJCQkJJHJlc3VsdCA9IHEoJ1NIT1cgdGFibGVzJyk7DQoNCgkJCQlpZiAoISRyZXN1bHQpIHAoJzxoMj4nLm15c3FsX2Vycm9yKCkuJzwvaDI+Jyk7DQoNCgkJCQkkbXlzcWxkYXRhID0gJyc7DQoNCgkJCQl3aGlsZSAoJGN1cnJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoNCgkJCQkJaWYgKGlzc2V0KCR0YWJsZVskY3Vycm93WzBdXSkpIHsNCg0KCQkJCQkJc3FsZHVtcHRhYmxlKCRjdXJyb3dbMF0sICRmcCk7DQoNCgkJCQkJfQ0KDQoJCQkJfQ0KDQoJCQkJZmNsb3NlKCRmcCk7DQoNCgkJCQkkZmlsZXVybCA9IHN0cl9yZXBsYWNlKFNBX1JPT1QsJycsJHBhdGgpOw0KDQoJCQkJbSgnQmFja3VwIGNyZWFkbyBlbiA8YSBocmVmPSInLiRmaWxldXJsLiciIHRhcmdldD0iX2JsYW5rIj4nLiRwYXRoLic8L2E+Jyk7DQoNCgkJCQlteXNxbF9jbG9zZSgpOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJbSgnQmFja3VwIGZhbGxpZG8nKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KCWlmICgkaW5zZXJ0ICYmICRpbnNlcnRzcWwpIHsNCg0KCQkka2V5c3RyID0gJHZhbHN0ciA9ICR0bXAgPSAnJzsNCg0KCQlmb3JlYWNoKCRpbnNlcnRzcWwgYXMgJGtleSA9PiAkdmFsKSB7DQoNCgkJCWlmICgkdmFsKSB7DQoNCgkJCQkka2V5c3RyIC49ICR0bXAuJGtleTsNCg0KCQkJCSR2YWxzdHIgLj0gJHRtcC4iJyIuYWRkc2xhc2hlcygkdmFsKS4iJyI7DQoNCgkJCQkkdG1wID0gJywnOw0KDQoJCQl9DQoNCgkJfQ0KDQoJCWlmICgka2V5c3RyICYmICR2YWxzdHIpIHsNCg0KCQkJbXlkYmNvbm4oJGRiaG9zdCwkZGJ1c2VyLCRkYnBhc3MsJGRibmFtZSwkY2hhcnNldCwkZGJwb3J0KTsNCg0KCQkJbShxKCJJTlNFUlQgSU5UTyAkdGFibGVuYW1lICgka2V5c3RyKSBWQUxVRVMgKCR2YWxzdHIpIikgPyAnSW5ncmVzZSBudWV2byByZWdpc3RybycgOiBteXNxbF9lcnJvcigpKTsJCX0NCg0KCX0NCg0KCWlmICgkdXBkYXRlICYmICRpbnNlcnRzcWwgJiYgJGJhc2U2NCkgew0KDQoJCSR2YWxzdHIgPSAkdG1wID0gJyc7DQoNCgkJZm9yZWFjaCgkaW5zZXJ0c3FsIGFzICRrZXkgPT4gJHZhbCkgew0KDQoJCQkkdmFsc3RyIC49ICR0bXAuJGtleS4iPSciLmFkZHNsYXNoZXMoJHZhbCkuIiciOw0KDQoJCQkkdG1wID0gJywnOw0KDQoJCX0NCg0KCQlpZiAoJHZhbHN0cikgew0KDQoJCQkkd2hlcmUgPSBiYXNlNjRfZGVjb2RlKCRiYXNlNjQpOw0KDQoJCQlteWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCQltKHEoIlVQREFURSAkdGFibGVuYW1lIFNFVCAkdmFsc3RyIFdIRVJFICR3aGVyZSBMSU1JVCAxIikgPyAnQWN0dWFsaXphbmRvIHJlZ2lzdHJvJyA6IG15c3FsX2Vycm9yKCkpOw0KDQoJCX0NCg0KCX0NCg0KCWlmICgkZG9pbmcgPT0gJ2RlbCcgJiYgJGJhc2U2NCkgew0KDQoJCSR3aGVyZSA9IGJhc2U2NF9kZWNvZGUoJGJhc2U2NCk7DQoNCgkJJGRlbGV0ZV9zcWwgPSAiREVMRVRFIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUiOw0KDQoJCW15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoNCgkJbShxKCJERUxFVEUgRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSIpID8gJ0JvcnJhbmRvIHJlZ2lzdHJvJyA6IG15c3FsX2Vycm9yKCkpOw0KDQoJfQ0KDQoNCg0KCWlmICgkdGFibGVuYW1lICYmICRkb2luZyA9PSAnZHJvcCcpIHsNCg0KCQlteWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCWlmIChxKCJEUk9QIFRBQkxFICR0YWJsZW5hbWUiKSkgew0KDQoJCQltKCdEcm9wIHRhYmxlIGV4aXRvc28nKTsNCg0KCQkJJHRhYmxlbmFtZSA9ICcnOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0obXlzcWxfZXJyb3IoKSk7DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidNWVNRTCcpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7DQoNCglwKCc8cD4nKTsNCg0KCXAoJ0RCSG9zdDonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYmhvc3QnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JGRiaG9zdCkpOw0KDQoJcCgnOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicG9ydCcsJ3NpemUnPT40LCd2YWx1ZSc9PiRkYnBvcnQpKTsNCg0KCXAoJ0RCVXNlcjonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnVzZXInLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRidXNlcikpOw0KDQoJcCgnREJQYXNzOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicGFzcycsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJwYXNzKSk7DQoNCglwKCdEQkNoYXJzZXQ6Jyk7DQoNCgltYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J2NoYXJzZXQnLCdvcHRpb24nPT4kY2hhcnNldGRiLCdzZWxlY3RlZCc9PiRjaGFyc2V0LCdub2tleSc9PjEpKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidjb25uZWN0JywndmFsdWUnPT4nQ29uZWN0YXInLCd0eXBlJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JykpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KPz4NCg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KDQpmdW5jdGlvbiBlZGl0cmVjb3JkKGFjdGlvbiwgYmFzZTY0LCB0YWJsZW5hbWUpew0KDQoJaWYgKGFjdGlvbiA9PSAnZGVsJykgewkJDQoNCgkJaWYgKCFjb25maXJtKCdJcyBvciBpc25cJ3QgZGVsZXRpb24gcmVjb3JkPycpKSByZXR1cm47DQoNCgl9DQoNCgkkKCdyZWNvcmRsaXN0JykuZG9pbmcudmFsdWU9YWN0aW9uOw0KDQoJJCgncmVjb3JkbGlzdCcpLmJhc2U2NC52YWx1ZT1iYXNlNjQ7DQoNCgkkKCdyZWNvcmRsaXN0JykudGFibGVuYW1lLnZhbHVlPXRhYmxlbmFtZTsNCg0KCSQoJ3JlY29yZGxpc3QnKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBtb2RkYm5hbWUoZGJuYW1lKSB7DQoNCglpZighZGJuYW1lKSByZXR1cm47DQoNCgkkKCdzZXRkYm5hbWUnKS5kYm5hbWUudmFsdWU9ZGJuYW1lOw0KDQoJJCgnc2V0ZGJuYW1lJykuc3VibWl0KCk7DQoNCn0NCg0KZnVuY3Rpb24gc2V0dGFibGUodGFibGVuYW1lLGRvaW5nLHBhZ2UpIHsNCg0KCWlmKCF0YWJsZW5hbWUpIHJldHVybjsNCg0KCWlmIChkb2luZykgew0KDQoJCSQoJ3NldHRhYmxlJykuZG9pbmcudmFsdWU9ZG9pbmc7DQoNCgl9DQoNCglpZiAocGFnZSkgew0KDQoJCSQoJ3NldHRhYmxlJykucGFnZS52YWx1ZT1wYWdlOw0KDQoJfQ0KDQoJJCgnc2V0dGFibGUnKS50YWJsZW5hbWUudmFsdWU9dGFibGVuYW1lOw0KDQoJJCgnc2V0dGFibGUnKS5zdWJtaXQoKTsNCg0KfQ0KDQo8L3NjcmlwdD4NCg0KPD9waHANCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3JlY29yZGxpc3QnKSk7DQoNCgltYWtlaGlkZSgnZG9pbmcnKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7DQoNCgltYWtlaGlkZSgnYmFzZTY0Jyk7DQoNCgltYWtlaGlkZSgndGFibGVuYW1lJyk7DQoNCglwKCRkYmZvcm0pOw0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkvLyYjMTEyMTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxOTE5OyYjMTI5O38NCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3NldGRibmFtZScpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7DQoNCglwKCRkYmZvcm0pOw0KDQoJaWYgKCEkZGJuYW1lKSB7DQoNCgkJbWFrZWhpZGUoJ2RibmFtZScpOw0KDQoJfQ0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkvLyYjMTEyMTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidzZXR0YWJsZScpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7DQoNCglwKCRkYmZvcm0pOw0KDQoJbWFrZWhpZGUoJ3RhYmxlbmFtZScpOw0KDQoJbWFrZWhpZGUoJ3BhZ2UnLCRwYWdlKTsNCg0KCW1ha2VoaWRlKCdkb2luZycpOw0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkkY2FjaGV0YWJsZXMgPSBhcnJheSgpOwkNCg0KCSRwYWdlbnVtID0gMzA7DQoNCgkkcGFnZSA9IGludHZhbCgkcGFnZSk7DQoNCglpZigkcGFnZSkgew0KDQoJCSRzdGFydF9saW1pdCA9ICgkcGFnZSAtIDEpICogJHBhZ2VudW07DQoNCgl9IGVsc2Ugew0KDQoJCSRzdGFydF9saW1pdCA9IDA7DQoNCgkJJHBhZ2UgPSAxOw0KDQoJfQ0KDQoJaWYgKGlzc2V0KCRkYmhvc3QpICYmIGlzc2V0KCRkYnVzZXIpICYmIGlzc2V0KCRkYnBhc3MpICYmIGlzc2V0KCRjb25uZWN0KSkgew0KDQoJCW15ZGJjb25uKCRkYmhvc3QsICRkYnVzZXIsICRkYnBhc3MsICRkYm5hbWUsICRjaGFyc2V0LCAkZGJwb3J0KTsNCg0KCQkkbXlzcWx2ZXIgPSBteXNxbF9nZXRfc2VydmVyX2luZm8oKTsNCg0KCQlwKCc8cD5NeVNRTCAnLiRteXNxbHZlci4nIGVqZWN1dGFuZG9zZSBlbiAnLiRkYmhvc3QuJyBjb21vICcuJGRidXNlci4nQCcuJGRiaG9zdC4nPC9wPicpOw0KDQoJCSRoaWdodmVyID0gJG15c3FsdmVyID4gJzQuMScgPyAxIDogMDsNCg0KDQoNCgkJJHF1ZXJ5ID0gcSgiU0hPVyBEQVRBQkFTRVMiKTsNCg0KCQkkZGJzID0gYXJyYXkoKTsNCg0KCQkkZGJzW10gPSAnLS0gU2VsZWNjaW9uZSB1bmEgZGF0YWJhc2UgLS0nOw0KDQoJCXdoaWxlKCRkYiA9IG15c3FsX2ZldGNoX2FycmF5KCRxdWVyeSkpIHsNCg0KCQkJJGRic1skZGJbJ0RhdGFiYXNlJ11dID0gJGRiWydEYXRhYmFzZSddOw0KDQoJCX0NCg0KCQltYWtlc2VsZWN0KGFycmF5KCd0aXRsZSc9PidTZWxlY2Npb25lIHVuYSBkYXRhYmFzZTonLCduYW1lJz0+J2RiW10nLCdvcHRpb24nPT4kZGJzLCdzZWxlY3RlZCc9PiRkYm5hbWUsJ29uY2hhbmdlJz0+J21vZGRibmFtZSh0aGlzLm9wdGlvbnNbdGhpcy5zZWxlY3RlZEluZGV4XS52YWx1ZSknLCduZXdsaW5lJz0+MSkpOw0KDQoJCSR0YWJsZWRiID0gYXJyYXkoKTsNCg0KCQlpZiAoJGRibmFtZSkgew0KDQoJCQlwKCc8cD4nKTsNCg0KCQkJcCgnRGF0YWJhc2U6IDxhIGhyZWY9ImphdmFzY3JpcHQ6bW9kZGJuYW1lKFwnJy4kZGJuYW1lLidcJyk7Ij4nLiRkYm5hbWUuJzwvYT4nKTsNCg0KCQkJaWYgKCR0YWJsZW5hbWUpIHsNCg0KCQkJCXAoJyB8IFRhYmxhIGFjdHVhbDogPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcpOyI+Jy4kdGFibGVuYW1lLic8L2E+IFsgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnaW5zZXJ0XCcpOyI+SW5zZXJ0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ3N0cnVjdHVyZVwnKTsiPlN0cnVjdHVyZTwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdkcm9wXCcpOyI+RHJvcDwvYT4gXScpOw0KDQoJCQl9DQoNCgkJCXAoJzwvcD4nKTsNCg0KCQkJbXlzcWxfc2VsZWN0X2RiKCRkYm5hbWUpOw0KDQoNCg0KCQkJJGdldG51bXNxbCA9ICcnOw0KDQoJCQkkcnVucXVlcnkgPSAwOw0KDQoJCQlpZiAoJHNxbF9xdWVyeSkgew0KDQoJCQkJJHJ1bnF1ZXJ5ID0gMTsNCg0KCQkJfQ0KDQoJCQkkYWxsb3dlZGl0ID0gMDsNCg0KCQkJaWYgKCR0YWJsZW5hbWUgJiYgISRzcWxfcXVlcnkpIHsNCg0KCQkJCSRzcWxfcXVlcnkgPSAiU0VMRUNUICogRlJPTSAkdGFibGVuYW1lIjsNCg0KCQkJCSRnZXRudW1zcWwgPSAkc3FsX3F1ZXJ5Ow0KDQoJCQkJJHNxbF9xdWVyeSA9ICRzcWxfcXVlcnkuIiBMSU1JVCAkc3RhcnRfbGltaXQsICRwYWdlbnVtIjsNCg0KCQkJCSRhbGxvd2VkaXQgPSAxOw0KDQoJCQl9DQoNCgkJCXAoJzxmb3JtIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9IlBPU1QiPicpOw0KDQoJCQlwKCc8cD48dGFibGUgd2lkdGg9IjIwMCIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiPjx0cj48dGQgY29sc3Bhbj0iMiI+RWplY3V0YXIgUXVlcnkgU1FMJy4kZGJuYW1lLic6PC90ZD48L3RyPjx0cj48dGQ+PHRleHRhcmVhIG5hbWU9InNxbF9xdWVyeSIgY2xhc3M9ImFyZWEiIHN0eWxlPSJ3aWR0aDo2MDBweDtoZWlnaHQ6NTBweDtvdmVyZmxvdzphdXRvOyI+Jy5odG1sc3BlY2lhbGNoYXJzKCRzcWxfcXVlcnksRU5UX1FVT1RFUykuJzwvdGV4dGFyZWE+PC90ZD48dGQgc3R5bGU9InBhZGRpbmc6MCA1cHg7Ij48aW5wdXQgY2xhc3M9ImJ0IiBzdHlsZT0iaGVpZ2h0OjUwcHg7IiBuYW1lPSJzdWJtaXQiIHR5cGU9InN1Ym1pdCIgdmFsdWU9IkVqZWN1dGFyIiAvPjwvdGQ+PC90cj48L3RhYmxlPjwvcD4nKTsNCg0KCQkJbWFrZWhpZGUoJ3RhYmxlbmFtZScsICR0YWJsZW5hbWUpOw0KDQoJCQltYWtlaGlkZSgnYWN0aW9uJywnbXlzcWxhZG1pbicpOw0KDQoJCQlwKCRkYmZvcm0pOw0KDQoJCQlwKCc8L2Zvcm0+Jyk7DQoNCgkJCWlmICgkdGFibGVuYW1lIHx8ICgkcnVucXVlcnkgJiYgJHNxbF9xdWVyeSkpIHsNCg0KCQkJCWlmICgkZG9pbmcgPT0gJ3N0cnVjdHVyZScpIHsNCg0KCQkJCQkkcmVzdWx0ID0gcSgiU0hPVyBDT0xVTU5TIEZST00gJHRhYmxlbmFtZSIpOw0KDQoJCQkJCSRyb3dkYiA9IGFycmF5KCk7DQoNCgkJCQkJd2hpbGUoJHJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoNCgkJCQkJCSRyb3dkYltdID0gJHJvdzsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KCQkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KDQoJCQkJCXAoJzx0ZD5GaWVsZDwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPlR5cGU8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD5OdWxsPC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+S2V5PC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+RGVmYXVsdDwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPkV4dHJhPC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCWZvcmVhY2ggKCRyb3dkYiBhcyAkcm93KSB7DQoNCgkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ0ZpZWxkJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ1R5cGUnXS4nPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPicuJHJvd1snTnVsbCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydLZXknXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPicuJHJvd1snRGVmYXVsdCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydFeHRyYSddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCX0NCg0KCQkJCQl0YmZvb3QoKTsNCg0KCQkJCX0gZWxzZWlmICgkZG9pbmcgPT0gJ2luc2VydCcgfHwgJGRvaW5nID09ICdlZGl0Jykgew0KDQoJCQkJCSRyZXN1bHQgPSBxKCdTSE9XIENPTFVNTlMgRlJPTSAnLiR0YWJsZW5hbWUpOw0KDQoJCQkJCXdoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCkpIHsNCg0KCQkJCQkJJHJvd2RiW10gPSAkcm93Ow0KDQoJCQkJCX0NCg0KCQkJCQkkcnMgPSBhcnJheSgpOw0KDQoJCQkJCWlmICgkZG9pbmcgPT0gJ2luc2VydCcpIHsNCg0KCQkJCQkJcCgnPGgyPkluc2VydCBuZXcgbGluZSBpbiAnLiR0YWJsZW5hbWUuJyB0YWJsZSAmcmFxdW87PC9oMj4nKTsNCg0KCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQlwKCc8aDI+VXBkYXRlIHJlY29yZCBpbiAnLiR0YWJsZW5hbWUuJyB0YWJsZSAmcmFxdW87PC9oMj4nKTsNCg0KCQkJCQkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsNCg0KCQkJCQkJJHJlc3VsdCA9IHEoIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUgTElNSVQgMSIpOw0KDQoJCQkJCQkkcnMgPSBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KTsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IicuJHNlbGYuJyI+Jyk7DQoNCgkJCQkJcCgkZGJmb3JtKTsNCg0KCQkJCQltYWtlaGlkZSgnYWN0aW9uJywnbXlzcWxhZG1pbicpOw0KDQoJCQkJCW1ha2VoaWRlKCd0YWJsZW5hbWUnLCR0YWJsZW5hbWUpOw0KDQoJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCgkJCQkJZm9yZWFjaCAoJHJvd2RiIGFzICRyb3cpIHsNCg0KCQkJCQkJaWYgKCRyc1skcm93WydGaWVsZCddXSkgew0KDQoJCQkJCQkJJHZhbHVlID0gaHRtbHNwZWNpYWxjaGFycygkcnNbJHJvd1snRmllbGQnXV0pOw0KDQoJCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQkJJHZhbHVlID0gJyc7DQoNCgkJCQkJCX0NCg0KCQkJCQkJJHRoaXNiZyA9IGJnKCk7DQoNCgkJCQkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsNCg0KCQkJCQkJaWYgKCRyb3dbJ0tleSddID09ICdVTkknIHx8ICRyb3dbJ0V4dHJhJ10gPT0gJ2F1dG9faW5jcmVtZW50JyB8fCAkcm93WydLZXknXSA9PSAnUFJJJykgew0KDQoJCQkJCQkJcCgnPHRkPjxiPicuJHJvd1snRmllbGQnXS4nPC9iPjxiciAvPicuJHJvd1snVHlwZSddLic8L3RkPjx0ZD4nLiR2YWx1ZS4nJm5ic3A7PC90ZD48L3RyPicpOw0KDQoJCQkJCQl9IGVsc2UgewkJCQkJCQkNCg0KCQkJCQkJCXAoJzx0ZD48Yj4nLiRyb3dbJ0ZpZWxkJ10uJzwvYj48YnIgLz4nLiRyb3dbJ1R5cGUnXS4nPC90ZD48dGQ+PHRleHRhcmVhIGNsYXNzPSJhcmVhIiBuYW1lPSJpbnNlcnRzcWxbJy4kcm93WydGaWVsZCddLiddIiBzdHlsZT0id2lkdGg6NTAwcHg7aGVpZ2h0OjYwcHg7b3ZlcmZsb3c6YXV0bzsiPicuJHZhbHVlLic8L3RleHRhcmVhPjwvdGQ+PC90cj4nKTsNCg0KCQkJCQkJfQ0KDQoJCQkJCX0NCg0KCQkJCQlpZiAoJGRvaW5nID09ICdpbnNlcnQnKSB7DQoNCgkJCQkJCXAoJzx0ciBjbGFzcz0iJy5iZygpLiciPjx0ZCBjb2xzcGFuPSIyIj48aW5wdXQgY2xhc3M9ImJ0IiB0eXBlPSJzdWJtaXQiIG5hbWU9Imluc2VydCIgdmFsdWU9Ikluc2VydGFyIiAvPjwvdGQ+PC90cj4nKTsNCg0KCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQlwKCc8dHIgY2xhc3M9IicuYmcoKS4nIj48dGQgY29sc3Bhbj0iMiI+PGlucHV0IGNsYXNzPSJidCIgdHlwZT0ic3VibWl0IiBuYW1lPSJ1cGRhdGUiIHZhbHVlPSJBY3R1YWxpemFyIiAvPjwvdGQ+PC90cj4nKTsNCg0KCQkJCQkJbWFrZWhpZGUoJ2Jhc2U2NCcsICRiYXNlNjQpOw0KDQoJCQkJCX0NCg0KCQkJCQlwKCc8L3RhYmxlPjwvZm9ybT4nKTsNCg0KCQkJCX0gZWxzZSB7DQoNCgkJCQkJJHF1ZXJ5cyA9IEBleHBsb2RlKCc7Jywkc3FsX3F1ZXJ5KTsNCg0KCQkJCQlmb3JlYWNoKCRxdWVyeXMgYXMgJG51bT0+JHF1ZXJ5KSB7DQoNCgkJCQkJCWlmICgkcXVlcnkpIHsNCg0KCQkJCQkJCXAoIjxwPjxiPlF1ZXJ5I3skbnVtfSA6ICIuaHRtbHNwZWNpYWxjaGFycygkcXVlcnksRU5UX1FVT1RFUykuIjwvYj48L3A+Iik7DQoNCgkJCQkJCQlzd2l0Y2gocXkoJHF1ZXJ5KSkNCg0KCQkJCQkJCXsNCg0KCQkJCQkJCQljYXNlIDA6DQoNCgkJCQkJCQkJCXAoJzxoMj5FcnJvciA6ICcubXlzcWxfZXJyb3IoKS4nPC9oMj4nKTsNCg0KCQkJCQkJCQkJYnJlYWs7CQ0KDQoJCQkJCQkJCWNhc2UgMToNCg0KCQkJCQkJCQkJaWYgKHN0cnRvbG93ZXIoc3Vic3RyKCRxdWVyeSwwLDEzKSkgPT0gJ3NlbGVjdCAqIGZyb20nKSB7DQoNCgkJCQkJCQkJCQkkYWxsb3dlZGl0ID0gMTsNCg0KCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQlpZiAoJGdldG51bXNxbCkgew0KDQoJCQkJCQkJCQkJJHRhdG9sID0gbXlzcWxfbnVtX3Jvd3MocSgkZ2V0bnVtc3FsKSk7DQoNCgkJCQkJCQkJCQkkbXVsdGlwYWdlID0gbXVsdGkoJHRhdG9sLCAkcGFnZW51bSwgJHBhZ2UsICR0YWJsZW5hbWUpOw0KDQoJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCWlmICghJHRhYmxlbmFtZSkgew0KDQoJCQkJCQkJCQkJJHNxbF9saW5lID0gc3RyX3JlcGxhY2UoYXJyYXkoIlxyIiwgIlxuIiwgIlx0IiksIGFycmF5KCcgJywgJyAnLCAnICcpLCB0cmltKGh0bWxzcGVjaWFsY2hhcnMoJHF1ZXJ5KSkpOw0KDQoJCQkJCQkJCQkJJHNxbF9saW5lID0gcHJlZ19yZXBsYWNlKCIvXC9cKlteKFwqXC8pXSpcKlwvL2kiLCAiICIsICRzcWxfbGluZSk7DQoNCgkJCQkJCQkJCQlwcmVnX21hdGNoX2FsbCgiL2Zyb21ccytgezAsMX0oW1x3XSspYHswLDF9XHMrL2kiLCRzcWxfbGluZSwkbWF0Y2hlcyk7DQoNCgkJCQkJCQkJCQkkdGFibGVuYW1lID0gJG1hdGNoZXNbMV1bMF07DQoNCgkJCQkJCQkJCX0NCg0KDQoNCgkJCQkJCQkJCS8qKioqKioqKioqKioqKioqKioqKiovDQoNCgkJCQkJCQkJCSRnZXRmaWVsZCA9IHEoIlNIT1cgQ09MVU1OUyBGUk9NICR0YWJsZW5hbWUiKTsNCg0KCQkJCQkJCQkJJHJvd2RiID0gYXJyYXkoKTsNCg0KCQkJCQkJCQkJJGtleWZpZWQgPSAnJzsgLy8mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxNDYyOyYjMTI5O38NCg0KCQkJCQkJCQkJd2hpbGUoJHJvdyA9IEBteXNxbF9mZXRjaF9hc3NvYygkZ2V0ZmllbGQpKSB7DQoNCgkJCQkJCQkJCQkkcm93ZGJbJHJvd1snRmllbGQnXV1bJ0tleSddID0gJHJvd1snS2V5J107DQoNCgkJCQkJCQkJCQkkcm93ZGJbJHJvd1snRmllbGQnXV1bJ0V4dHJhJ10gPSAkcm93WydFeHRyYSddOw0KDQoJCQkJCQkJCQkJaWYgKCRyb3dbJ0tleSddID09ICdVTkknIHx8ICRyb3dbJ0tleSddID09ICdQUkknKSB7DQoNCgkJCQkJCQkJCQkJJGtleWZpZWQgPSAkcm93WydGaWVsZCddOw0KDQoJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQl9DQoNCgkJCQkNCg0KCQkJCQkJCQkJLy8mIzE0NTc7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KCQkJCQkJCQkJaWYgKHN0cnRvbG93ZXIoc3Vic3RyKCRxdWVyeSwwLDEzKSkgPT0gJ3NlbGVjdCAqIGZyb20nKSB7DQoNCgkJCQkJCQkJCQkkcXVlcnkgPSBzdHJfcmVwbGFjZSgiIExJTUlUICIsICIgb3JkZXIgYnkgJGtleWZpZWQgREVTQyBMSU1JVCAiLCAkcXVlcnkpOw0KDQoJCQkJCQkJCQl9DQoNCg0KDQoJCQkJCQkJCQkkcmVzdWx0ID0gcSgkcXVlcnkpOw0KDQoNCg0KCQkJCQkJCQkJcCgkbXVsdGlwYWdlKTsNCg0KCQkJCQkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KCQkJCQkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsNCg0KCQkJCQkJCQkJaWYgKCRhbGxvd2VkaXQpIHAoJzx0ZD5BY3Rpb248L3RkPicpOw0KDQoJCQkJCQkJCQkkZmllbGRudW0gPSBAbXlzcWxfbnVtX2ZpZWxkcygkcmVzdWx0KTsNCg0KCQkJCQkJCQkJZm9yKCRpPTA7JGk8JGZpZWxkbnVtOyRpKyspew0KDQoJCQkJCQkJCQkJJG5hbWUgPSBAbXlzcWxfZmllbGRfbmFtZSgkcmVzdWx0LCAkaSk7DQoNCgkJCQkJCQkJCQkkdHlwZSA9IEBteXNxbF9maWVsZF90eXBlKCRyZXN1bHQsICRpKTsNCg0KCQkJCQkJCQkJCSRsZW4gPSBAbXlzcWxfZmllbGRfbGVuKCRyZXN1bHQsICRpKTsNCg0KCQkJCQkJCQkJCXAoIjx0ZCBub3dyYXA+JG5hbWU8YnI+PHNwYW4+JHR5cGUoJGxlbikiLigoJHJvd2RiWyRuYW1lXVsnS2V5J10gPT0gJ1VOSScgfHwgJHJvd2RiWyRuYW1lXVsnS2V5J10gPT0gJ1BSSScpID8gJzxiPiAtIFBSSU1BUlk8L2I+JyA6ICcnKS4oJHJvd2RiWyRuYW1lXVsnRXh0cmEnXSA9PSAnYXV0b19pbmNyZW1lbnQnID8gJzxiPiAtIEF1dG88L2I+JyA6ICcnKS4iPC9zcGFuPjwvdGQ+Iik7DQoNCgkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQkJCQkJDQoNCgkJCQkJCQkJCXdoaWxlKCRtbiA9IEBteXNxbF9mZXRjaF9hc3NvYygkcmVzdWx0KSl7DQoNCgkJCQkJCQkJCQkkdGhpc2JnID0gYmcoKTsNCg0KCQkJCQkJCQkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsNCg0KCQkJCQkJCQkJCSR3aGVyZSA9ICR0bXAgPSAkYjEgPSAnJzsNCg0KCQkJCQkJCQkJCS8vJiMxMTIxOyYjNTQ1OyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzE0NjI7JiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCgkJCQkJCQkJCQlmb3JlYWNoKCRtbiBhcyAka2V5PT4kaW5zaWRlKXsNCg0KCQkJCQkJCQkJCQlpZiAoJGluc2lkZSkgew0KDQoJCQkJCQkJCQkJCQkvLyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O3+KtyYjMTIxMTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEzMTM7JiMxMjk7fyYjMTI5O38mIzEzMzQ7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjY5OyYjMTI5O38mIzEyOTt/JiMxNDYyO4qyJiMxMjk7fyYjMTI5O38mIzEyMDU7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiM4Njc7JiMxNDY1OyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxNDYyOyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjOTM4OyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCgkJCQkJCQkJCQkJCWlmICgkcm93ZGJbJGtleV1bJ0tleSddID09ICdVTkknIHx8ICRyb3dkYlska2V5XVsnRXh0cmEnXSA9PSAnYXV0b19pbmNyZW1lbnQnIHx8ICRyb3dkYlska2V5XVsnS2V5J10gPT0gJ1BSSScpIHsNCg0KCQkJCQkJCQkJCQkJCSR3aGVyZSA9ICRrZXkuIj0nIi5hZGRzbGFzaGVzKCRpbnNpZGUpLiInIjsNCg0KCQkJCQkJCQkJCQkJCWJyZWFrOw0KDQoJCQkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQkJCSR3aGVyZSAuPSAkdG1wLiRrZXkuIj0nIi5hZGRzbGFzaGVzKCRpbnNpZGUpLiInIjsNCg0KCQkJCQkJCQkJCQkJJHRtcCA9ICcgQU5EICc7DQoNCgkJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQkJLy8mIzEyOTt/JiMxMjk7fyYjNTQ1OyYjMTI5O38mIzEyOTt/JiMxODg7JiMxMjk7fyYjMTI5O38NCg0KCQkJCQkJCQkJCWZvcmVhY2goJG1uIGFzICRrZXk9PiRpbnNpZGUpew0KDQoJCQkJCQkJCQkJCSRiMSAuPSAnPHRkIG5vd3JhcD4nLmh0bWxfY2xlYW4oJGluc2lkZSkuJyZuYnNwOzwvdGQ+JzsNCg0KCQkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJCSR3aGVyZSA9IGJhc2U2NF9lbmNvZGUoJHdoZXJlKTsNCg0KDQoNCgkJCQkJCQkJCQlpZiAoJGFsbG93ZWRpdCkgcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0OmVkaXRyZWNvcmQoXCdlZGl0XCcsIFwnJy4kd2hlcmUuJ1wnLCBcJycuJHRhYmxlbmFtZS4nXCcpOyI+RWRpdGFyPC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6ZWRpdHJlY29yZChcJ2RlbFwnLCBcJycuJHdoZXJlLidcJywgXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPkJvcnJhcjwvYT48L3RkPicpOw0KDQoNCg0KCQkJCQkJCQkJCXAoJGIxKTsNCg0KCQkJCQkJCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCQkJCQkJCQl1bnNldCgkYjEpOw0KDQoJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCXRiZm9vdCgpOw0KDQoJCQkJCQkJCQlwKCRtdWx0aXBhZ2UpOw0KDQoJCQkJCQkJCQlicmVhazsNCg0KCQkJCQkJCQljYXNlIDI6DQoNCgkJCQkJCQkJCSRhciA9IG15c3FsX2FmZmVjdGVkX3Jvd3MoKTsNCg0KCQkJCQkJCQkJcCgnPGgyPkNvbHVtbmFzIGFmZWN0YWRhcyA6IDxiPicuJGFyLic8L2I+PC9oMj4nKTsNCg0KCQkJCQkJCQkJYnJlYWs7DQoNCgkJCQkJCQl9DQoNCgkJCQkJCX0NCg0KCQkJCQl9DQoNCgkJCQl9DQoNCgkJCX0gZWxzZSB7DQoNCgkJCQkkcXVlcnkgPSBxKCJTSE9XIFRBQkxFIFNUQVRVUyIpOw0KDQoJCQkJJHRhYmxlX251bSA9ICR0YWJsZV9yb3dzID0gJGRhdGFfc2l6ZSA9IDA7DQoNCgkJCQkkdGFibGVkYiA9IGFycmF5KCk7DQoNCgkJCQl3aGlsZSgkdGFibGUgPSBteXNxbF9mZXRjaF9hcnJheSgkcXVlcnkpKSB7DQoNCgkJCQkJJGRhdGFfc2l6ZSA9ICRkYXRhX3NpemUgKyAkdGFibGVbJ0RhdGFfbGVuZ3RoJ107DQoNCgkJCQkJJHRhYmxlX3Jvd3MgPSAkdGFibGVfcm93cyArICR0YWJsZVsnUm93cyddOw0KDQoJCQkJCSR0YWJsZVsnRGF0YV9sZW5ndGgnXSA9IHNpemVjb3VudCgkdGFibGVbJ0RhdGFfbGVuZ3RoJ10pOw0KDQoJCQkJCSR0YWJsZV9udW0rKzsNCg0KCQkJCQkkdGFibGVkYltdID0gJHRhYmxlOw0KDQoJCQkJfQ0KDQoJCQkJJGRhdGFfc2l6ZSA9IHNpemVjb3VudCgkZGF0YV9zaXplKTsNCg0KCQkJCXVuc2V0KCR0YWJsZSk7DQoNCgkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiPicpOw0KDQoJCQkJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCI+Jyk7DQoNCgkJCQltYWtlaGlkZSgnYWN0aW9uJywnbXlzcWxhZG1pbicpOw0KDQoJCQkJcCgkZGJmb3JtKTsNCg0KCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7DQoNCgkJCQlwKCc8dGQgd2lkdGg9IjIlIiBhbGlnbj0iY2VudGVyIj48aW5wdXQgbmFtZT0iY2hrYWxsIiB2YWx1ZT0ib24iIHR5cGU9ImNoZWNrYm94IiBvbmNsaWNrPSJDaGVja0FsbCh0aGlzLmZvcm0pIiAvPjwvdGQ+Jyk7DQoNCgkJCQlwKCc8dGQ+Tm9tYnJlPC90ZD4nKTsNCg0KCQkJCXAoJzx0ZD5Sb3dzPC90ZD4nKTsNCg0KCQkJCXAoJzx0ZD5EYXRhX2xlbmd0aDwvdGQ+Jyk7DQoNCgkJCQlwKCc8dGQ+Q3JlYXRlX3RpbWU8L3RkPicpOw0KDQoJCQkJcCgnPHRkPlVwZGF0ZV90aW1lPC90ZD4nKTsNCg0KCQkJCWlmICgkaGlnaHZlcikgew0KDQoJCQkJCXAoJzx0ZD5FbmdpbmU8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD5Db2xsYXRpb248L3RkPicpOw0KDQoJCQkJfQ0KDQoJCQkJcCgnPHRkPk9wZXJhdGU8L3RkPicpOw0KDQoJCQkJcCgnPC90cj4nKTsNCg0KCQkJCWZvcmVhY2ggKCR0YWJsZWRiIGFzICRrZXkgPT4gJHRhYmxlKSB7DQoNCgkJCQkJJHRoaXNiZyA9IGJnKCk7DQoNCgkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOw0KDQoJCQkJCXAoJzx0ZCBhbGlnbj0iY2VudGVyIiB3aWR0aD0iMiUiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0idGFibGVbXSIgdmFsdWU9IicuJHRhYmxlWydOYW1lJ10uJyIgLz48L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcpOyI+Jy4kdGFibGVbJ05hbWUnXS4nPC9hPjwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydSb3dzJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydEYXRhX2xlbmd0aCddLic8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ3JlYXRlX3RpbWUnXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+Jy4kdGFibGVbJ1VwZGF0ZV90aW1lJ10uJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQkJaWYgKCRoaWdodmVyKSB7DQoNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnRW5naW5lJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ29sbGF0aW9uJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJfQ0KDQoJCQkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcsIFwnaW5zZXJ0XCcpOyI+SW5zZXJ0YXI8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnLCBcJ3N0cnVjdHVyZVwnKTsiPkVzdHJ1Y3R1cmE8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnLCBcJ2Ryb3BcJyk7Ij5Ecm9wPC9hPjwvdGQ+Jyk7DQoNCgkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCX0NCg0KCQkJCXAoJzx0ciBjbGFzcz0nLmJnKCkuJz4nKTsNCg0KCQkJCXAoJzx0ZD4mbmJzcDs8L3RkPicpOw0KDQoJCQkJcCgnPHRkPlRvdGFsIHRhYmxhczogJy4kdGFibGVfbnVtLic8L3RkPicpOw0KDQoJCQkJcCgnPHRkPicuJHRhYmxlX3Jvd3MuJzwvdGQ+Jyk7DQoNCgkJCQlwKCc8dGQ+Jy4kZGF0YV9zaXplLic8L3RkPicpOw0KDQoJCQkJcCgnPHRkIGNvbHNwYW49IicuKCRoaWdodmVyID8gNSA6IDMpLiciPiZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQlwKCc8L3RyPicpOw0KDQoNCg0KCQkJCXAoIjx0ciBjbGFzcz1cIiIuYmcoKS4iXCI+PHRkIGNvbHNwYW49XCIiLigkaGlnaHZlciA/IDkgOiA3KS4iXCI+PGlucHV0IG5hbWU9XCJzYXZlYXNmaWxlXCIgdmFsdWU9XCIxXCIgdHlwZT1cImNoZWNrYm94XCIgLz4gR3VhcmRhciBjb21vIDxpbnB1dCBjbGFzcz1cImlucHV0XCIgbmFtZT1cInBhdGhcIiB2YWx1ZT1cIiIuU0FfUk9PVC4kX1NFUlZFUlsnSFRUUF9IT1NUJ10uIl9NeVNRTC5zcWxcIiB0eXBlPVwidGV4dFwiIHNpemU9XCI2MFwiIC8+IDxpbnB1dCBjbGFzcz1cImJ0XCIgdHlwZT1cInN1Ym1pdFwiIG5hbWU9XCJkb3ducmFyXCIgdmFsdWU9XCJFeHBvcnRhciBzZWxlY2Npb25hZGFzXCIgLz48L3RkPjwvdHI+Iik7DQoNCgkJCQltYWtlaGlkZSgnZG9pbmcnLCdiYWNrdXBteXNxbCcpOw0KDQoJCQkJZm9ybWZvb3QoKTsNCg0KCQkJCXAoIjwvdGFibGU+Iik7DQoNCgkJCQlmcigkcXVlcnkpOw0KDQoJCQl9DQoNCgkJfQ0KDQoJfQ0KDQoJdGJmb290KCk7DQoNCglAbXlzcWxfY2xvc2UoKTsNCg0KfS8vZW5kIG15c3FsDQoNCg0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdtc3NxbGFkbWluJykgew0KDQoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOw0KDQoJISRkYnVzZXIgJiYgJGRidXNlciA9ICdzYSc7DQoNCgkhJGRibmFtZSAmJiAkZGJuYW1lID0gJ21hc3Rlcic7DQoNCgkkZGJmb3JtID0gJzxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJjb25uZWN0IiBuYW1lPSJjb25uZWN0IiB2YWx1ZT0iMSIgLz4nOw0KDQoJaWYoaXNzZXQoJGRiaG9zdCkpew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYmhvc3RcIiBuYW1lPVwiZGJob3N0XCIgdmFsdWU9XCIkZGJob3N0XCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJ1c2VyKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnVzZXJcIiBuYW1lPVwiZGJ1c2VyXCIgdmFsdWU9XCIkZGJ1c2VyXCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJwYXNzKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnBhc3NcIiBuYW1lPVwiZGJwYXNzXCIgdmFsdWU9XCIkZGJwYXNzXCIgLz5cbiI7DQoNCgl9DQoNCglpZihpc3NldCgkZGJuYW1lKSkgew0KDQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYm5hbWVcIiBuYW1lPVwiZGJuYW1lXCIgdmFsdWU9XCIkZGJuYW1lXCIgLz5cbiI7DQoNCgl9DQoNCglpZiAoJGluc2VydCAmJiAkaW5zZXJ0c3FsKSB7DQoNCgkJJGtleXN0ciA9ICR2YWxzdHIgPSAkdG1wID0gJyc7DQoNCgkJZm9yZWFjaCgkaW5zZXJ0c3FsIGFzICRrZXkgPT4gJHZhbCkgew0KDQoJCQlpZiAoJHZhbCkgew0KDQoJCQkJJGtleXN0ciAuPSAkdG1wLiRrZXk7DQoNCgkJCQkkdmFsc3RyIC49ICR0bXAuIiciLmFkZHNsYXNoZXMoJHZhbCkuIiciOw0KDQoJCQkJJHRtcCA9ICcsJzsNCg0KCQkJfQ0KDQoJCX0NCg0KCQlpZiAoJGtleXN0ciAmJiAkdmFsc3RyKSB7DQoNCgkJCW1zZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUpOw0KDQoJCQltKG1zcSgiSU5TRVJUIElOVE8gJHRhYmxlbmFtZSAoJGtleXN0cikgVkFMVUVTICgkdmFsc3RyKSIpID8gJ0luZ3Jlc2UgbnVldm8gcmVnaXN0cm8nIDogbXNtc2coKSk7DQoNCgkJfQ0KDQoJfQ0KDQoJaWYgKCR1cGRhdGUgJiYgJGluc2VydHNxbCAmJiAkYmFzZTY0KSB7DQoNCgkJJHZhbHN0ciA9ICR0bXAgPSAnJzsNCg0KCQlmb3JlYWNoKCRpbnNlcnRzcWwgYXMgJGtleSA9PiAkdmFsKSB7DQoNCgkJCSR2YWxzdHIgLj0gJHRtcC4ka2V5LiI9JyIuYWRkc2xhc2hlcygkdmFsKS4iJyI7DQoNCgkJCSR0bXAgPSAnLCc7DQoNCgkJfQ0KDQoJCWlmICgkdmFsc3RyKSB7DQoNCgkJCSR3aGVyZSA9IGJhc2U2NF9kZWNvZGUoJGJhc2U2NCk7DQoNCgkJCW1zZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUpOw0KDQoJCQltKG1zcSgiVVBEQVRFICR0YWJsZW5hbWUgU0VUICR2YWxzdHIgV0hFUkUgJHdoZXJlIikgPyAnQWN0dWFsaXphbmRvIHJlZ2lzdHJvJyA6IG1zbXNnKCkpOw0KDQoJCX0NCg0KCX0NCg0KCWlmICgkZG9pbmcgPT0gJ2RlbCcgJiYgJGJhc2U2NCkgew0KDQoJCSR3aGVyZSA9IGJhc2U2NF9kZWNvZGUoJGJhc2U2NCk7DQoNCgkJJGRlbGV0ZV9zcWwgPSAiREVMRVRFIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUiOw0KDQoJCW1zZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUpOw0KDQoJCW0obXNxKCJERUxFVEUgRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSIpID8gJ0JvcnJhbmRvIHJlZ2lzdHJvJyA6IG1zbXNnKCkpOw0KDQoJfQ0KDQoNCg0KCWlmICgkdGFibGVuYW1lICYmICRkb2luZyA9PSAnZHJvcCcpIHsNCg0KCQltc2RiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lKTsNCg0KCQlpZiAobXNxKCJEUk9QIFRBQkxFICR0YWJsZW5hbWUiKSkgew0KDQoJCQltKCdEcm9wIHRhYmxlIG9mIHN1Y2Nlc3MnKTsNCg0KCQkJJHRhYmxlbmFtZSA9ICcnOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0obXNtc2coKSk7DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidNU1NRTCcpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdtc3NxbGFkbWluJyk7DQoNCglwKCc8cD4nKTsNCg0KCXAoJ0RCSG9zdDonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYmhvc3QnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JGRiaG9zdCkpOw0KDQoJcCgnREJVc2VyOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RidXNlcicsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJ1c2VyKSk7DQoNCglwKCdEQlBhc3M6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJwYXNzJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYnBhc3MpKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidjb25uZWN0JywndmFsdWUnPT4nQ29uZWN0YXInLCd0eXBlJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JykpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KPz4NCg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KDQpmdW5jdGlvbiBlZGl0cmVjb3JkKGFjdGlvbiwgYmFzZTY0LCB0YWJsZW5hbWUpew0KDQoJaWYgKGFjdGlvbiA9PSAnZGVsJykgewkJDQoNCgkJaWYgKCFjb25maXJtKCdJcyBvciBpc25cJ3QgZGVsZXRpb24gcmVjb3JkPycpKSByZXR1cm47DQoNCgl9DQoNCgkkKCdyZWNvcmRsaXN0JykuZG9pbmcudmFsdWU9YWN0aW9uOw0KDQoJJCgncmVjb3JkbGlzdCcpLmJhc2U2NC52YWx1ZT1iYXNlNjQ7DQoNCgkkKCdyZWNvcmRsaXN0JykudGFibGVuYW1lLnZhbHVlPXRhYmxlbmFtZTsNCg0KCSQoJ3JlY29yZGxpc3QnKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBtb2RkYm5hbWUoZGJuYW1lKSB7DQoNCglpZighZGJuYW1lKSByZXR1cm47DQoNCgkkKCdzZXRkYm5hbWUnKS5kYm5hbWUudmFsdWU9ZGJuYW1lOw0KDQoJJCgnc2V0ZGJuYW1lJykuc3VibWl0KCk7DQoNCn0NCg0KZnVuY3Rpb24gc2V0dGFibGUodGFibGVuYW1lLGRvaW5nLHBhZ2UpIHsNCg0KCWlmKCF0YWJsZW5hbWUpIHJldHVybjsNCg0KCWlmIChkb2luZykgew0KDQoJCSQoJ3NldHRhYmxlJykuZG9pbmcudmFsdWU9ZG9pbmc7DQoNCgl9DQoNCglpZiAocGFnZSkgew0KDQoJCSQoJ3NldHRhYmxlJykucGFnZS52YWx1ZT1wYWdlOw0KDQoJfQ0KDQoJJCgnc2V0dGFibGUnKS50YWJsZW5hbWUudmFsdWU9dGFibGVuYW1lOw0KDQoJJCgnc2V0dGFibGUnKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBtc3NxbGluZm8oZGJuYW1lKSB7DQoNCglpZighZGJuYW1lKSByZXR1cm47DQoNCgkkKCdtc3NxbGluZm8nKS5kYm5hbWUudmFsdWU9ZGJuYW1lOw0KDQoJJCgnbXNzcWxpbmZvJykuc3VibWl0KCk7DQoNCn0NCg0KPC9zY3JpcHQ+DQoNCjw/cGhwDQoNCgkvLyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxODg7DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidyZWNvcmRsaXN0JykpOw0KDQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnbXNzcWxhZG1pbicpOw0KDQoJbWFrZWhpZGUoJ2Jhc2U2NCcpOw0KDQoJbWFrZWhpZGUoJ3RhYmxlbmFtZScpOw0KDQoJcCgkZGJmb3JtKTsNCg0KCWZvcm1mb290KCk7DQoNCg0KDQoJLy8mIzEyOTt/JiMxMjk7fyYjMTkxOTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzk5NDsNCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J21zc3FsaW5mbycpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdtc3NxbGFkbWluJyk7DQoNCgltYWtlaGlkZSgnZG9pbmcnLCdtc3NxbGluZm8nKTsNCg0KCW1ha2VoaWRlKCdkYm5hbWUnKTsNCg0KCXAoJGRiZm9ybSk7DQoNCglmb3JtZm9vdCgpOw0KDQoNCg0KCS8vJiMxMTIxOyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzE5MTk7JiMxMjk7fw0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0ZGJuYW1lJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ21zc3FsYWRtaW4nKTsNCg0KCXAoJGRiZm9ybSk7DQoNCglpZiAoISRkYm5hbWUpIHsNCg0KCQltYWtlaGlkZSgnZGJuYW1lJyk7DQoNCgl9DQoNCglmb3JtZm9vdCgpOw0KDQoNCg0KCS8vJiMxMTIxOyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3NldHRhYmxlJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ21zc3FsYWRtaW4nKTsNCg0KCXAoJGRiZm9ybSk7DQoNCgltYWtlaGlkZSgndGFibGVuYW1lJyk7DQoNCgltYWtlaGlkZSgncGFnZScsJHBhZ2UpOw0KDQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoNCglmb3JtZm9vdCgpOw0KDQoNCg0KCSRjYWNoZXRhYmxlcyA9IGFycmF5KCk7CQ0KDQoJJHBhZ2VudW0gPSAzMDsNCg0KCSRwYWdlID0gaW50dmFsKCRwYWdlKTsNCg0KCWlmKCRwYWdlKSB7DQoNCgkJJHN0YXJ0X2xpbWl0ID0gKCRwYWdlIC0gMSkgKiAkcGFnZW51bTsNCg0KCX0gZWxzZSB7DQoNCgkJJHN0YXJ0X2xpbWl0ID0gMDsNCg0KCQkkcGFnZSA9IDE7DQoNCgl9DQoNCg0KDQoJaWYgKGlzc2V0KCRkYmhvc3QpICYmIGlzc2V0KCRkYnVzZXIpICYmIGlzc2V0KCRkYnBhc3MpICYmIGlzc2V0KCRjb25uZWN0KSkgew0KDQoJCSEkZGJuYW1lICYmICRkYm5hbWUgPSAnbWFzdGVyJzsNCg0KCQltc2RiY29ubigkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCAkZGJuYW1lKTsNCg0KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQoNCgkJJHF1ZXJ5ID0gbXNxKCdzZWxlY3QgQEB2ZXJzaW9uJyk7DQoNCgkJJG1zaW5mbyA9IG1zc3FsX2ZldGNoX2FycmF5KCRxdWVyeSk7DQoNCgkJZWNobyAnPHA+Jy4kbXNpbmZvWzBdLic8L3A+JzsNCg0KCQkNCg0KCQkkcXVlcnkgPSBtc3EoIlNFTEVDVCBJU19TUlZST0xFTUVNQkVSKCdzeXNhZG1pbicpIik7DQoNCgkJJG1zaW5mbyA9IG1zc3FsX2ZldGNoX2FycmF5KCRxdWVyeSk7DQoNCgkJJGlzc2EgPSAwOw0KDQoJCWlmICgkbXNpbmZvWzBdKSB7DQoNCgkJCSRpc3NhID0gMTsNCg0KCQkJZWNobyAnPGgzPkVyZXMgc3lzYWRtaW4hPC9oMz4nOw0KDQoJCX0NCg0KCQkvLyYjMTI5O38mIzEyOTt/JiM1NDU7JiMxMjk7fyYjMTI5O38mIzE5MTk7JiMxMjk7fw0KDQoJCSRxdWVyeSA9IG1zcSgiU0VMRUNUIG5hbWUgRlJPTSBtYXN0ZXIuZGJvLnN5c2RhdGFiYXNlcyBXSEVSRSBoYXNfZGJhY2Nlc3MobmFtZSkgPSAxIE9SREVSIEJZIG5hbWUiKTsNCg0KCQkkZGJzID0gYXJyYXkoKTsNCg0KCQkkZGJzW10gPSAnLS0gU2VsZWNjaW9uZSB1bmEgREIgLS0nOw0KDQoJCXdoaWxlKCRkYiA9IG1zc3FsX2ZldGNoX2FycmF5KCRxdWVyeSkpIHsNCg0KCQkJJGRic1skZGJbJ25hbWUnXV0gPSAkZGJbJ25hbWUnXTsNCg0KCQl9DQoNCgkJbWFrZXNlbGVjdChhcnJheSgndGl0bGUnPT4nU2VsZWNjaW9uZSBsYSBEQjonLCduYW1lJz0+J2RiW10nLCdvcHRpb24nPT4kZGJzLCdzZWxlY3RlZCc9PiRkYm5hbWUsJ29uY2hhbmdlJz0+J21vZGRibmFtZSh0aGlzLm9wdGlvbnNbdGhpcy5zZWxlY3RlZEluZGV4XS52YWx1ZSknLCduZXdsaW5lJz0+MSkpOw0KDQoJCSR0YWJsZWRiID0gYXJyYXkoKTsNCg0KCQlpZiAoJGRibmFtZSkgew0KDQoJCQlwKCc8cD4nKTsNCg0KCQkJcCgnRGF0YWJhc2U6IDxhIGhyZWY9ImphdmFzY3JpcHQ6bW9kZGJuYW1lKFwnJy4kZGJuYW1lLidcJyk7Ij4nLiRkYm5hbWUuJzwvYT4gWyA8YSBocmVmPSJqYXZhc2NyaXB0Om1zc3FsaW5mbyhcJycuJGRibmFtZS4nXCcpOyI+aW5mb3JtYXRpb248L2E+IF0nKTsNCg0KCQkJaWYgKCR0YWJsZW5hbWUpIHsNCg0KCQkJCXAoJyB8IFRhYmxhIGFjdHVhbDogPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcpOyI+Jy4kdGFibGVuYW1lLic8L2E+IFsgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnaW5zZXJ0XCcpOyI+SW5zZXJ0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ3N0cnVjdHVyZVwnKTsiPlN0cnVjdHVyZTwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdkcm9wXCcpOyI+RHJvcDwvYT4gXScpOw0KDQoJCQl9DQoNCgkJCXAoJzwvcD4nKTsNCg0KCQkJaWYgKCFAbXNzcWxfc2VsZWN0X2RiKCRkYm5hbWUpKSB7DQoNCgkJCQlwKCc8aDI+Jy5tc21zZygpLic8L2gyPicpOw0KDQoJCQkJZXhpdDsNCg0KCQkJfQ0KDQoJCQlpZiAoJGRvaW5nID09ICdtc3NxbGluZm8nKSB7DQoNCgkJCQkkcmVzdWx0ID0gbXNxKCJTRUxFQ1QgdDEub3duZXIsIHQxLmNyZGF0ZSwgdDEuc2l6ZSwgdDIuREJCdXBEYXRlLCB0My5EaWZCdXBEYXRlLCB0NC5Kb3VybmFsQnVwRGF0ZSBGUk9NIChTRUxFQ1QgZC5uYW1lLCBzdXNlcl9zbmFtZShkLnNpZCkgQVMgb3duZXIsIGQuY3JkYXRlLCAoU0VMRUNUIFNUUihTVU0oQ09OVkVSVChERUMoMTUpLCBmLnNpemUpKSAqIChTRUxFQ1Qgdi5sb3cgRlJPTSBtYXN0ZXIuZGJvLnNwdF92YWx1ZXMgdiBXSEVSRSB2LnR5cGUgPSAnRScgQU5EIHYubnVtYmVyID0gMSkgLyAxMDQ4NTc2LCAxMCwgMikgKyAnTUInIEZST00gWyRkYm5hbWVdLmRiby5zeXNmaWxlcyBmKSBBUyBzaXplIEZST00gbWFzdGVyLmRiby5zeXNkYXRhYmFzZXMgZCBXSEVSRSBkLm5hbWUgPSAnJGRibmFtZScpIEFTIHQxIExFRlQgSk9JTiAoU0VMRUNUICckZGJuYW1lJyBBUyBuYW1lLCBNQVgoYmFja3VwX2ZpbmlzaF9kYXRlKSBBUyBEQkJ1cERhdGUgRlJPTSBtc2RiLmRiby5iYWNrdXBzZXQgV0hFUkUgdHlwZSA9ICdEJyBBTkQgZGF0YWJhc2VfbmFtZSA9ICckZGJuYW1lJykgQVMgdDIgT04gdDEubmFtZSA9IHQyLm5hbWUgTEVGVCBKT0lOIChTRUxFQ1QgJyRkYm5hbWUnIEFTIG5hbWUsIE1BWChiYWNrdXBfZmluaXNoX2RhdGUpIEFTIERpZkJ1cERhdGUgRlJPTSBtc2RiLmRiby5iYWNrdXBzZXQgV0hFUkUgdHlwZSA9ICdJJyBBTkQgZGF0YWJhc2VfbmFtZSA9ICckZGJuYW1lJykgQVMgdDMgT04gdDEubmFtZSA9IHQzLm5hbWUgTEVGVCBKT0lOIChTRUxFQ1QgJyRkYm5hbWUnIEFTIG5hbWUsIE1BWChiYWNrdXBfZmluaXNoX2RhdGUpIEFTIEpvdXJuYWxCdXBEYXRlIEZST00gbXNkYi5kYm8uYmFja3Vwc2V0IFdIRVJFIHR5cGUgPSAnTCcgQU5EIGRhdGFiYXNlX25hbWUgPSAnJGRibmFtZScpIEFTIHQ0IE9OIHQxLm5hbWUgPSB0NC5uYW1lIik7DQoNCgkJCQkkaW5mbyA9IG1zc3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpOw0KDQoNCg0KCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCgkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KDQoJCQkJcCgnPHRkIGNvbHNwYW49IjIiPicuJGRibmFtZS4nIEluZm9ybWF0aW9uPC90ZD4nKTsNCg0KCQkJCXAoJzwvdHI+Jyk7DQoNCg0KDQoJCQkJcCgnPHRyIGNsYXNzPSJhbHQxIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdhbHQxXCc7Ij4nKTsNCg0KCQkJCXAoJzx0ZD5Pd25lcjwvdGQ+PHRkPicuJGluZm9bJ293bmVyJ10uJzwvdGQ+Jyk7DQoNCgkJCQlwKCc8L3RyPicpOw0KDQoJCQkJcCgnPHRyIGNsYXNzPSJhbHQyIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdhbHQyXCc7Ij4nKTsNCg0KCQkJCXAoJzx0ZD5DcmVhdGUgZGF0ZTwvdGQ+PHRkPicuJGluZm9bJ2NyZGF0ZSddLic8L3RkPicpOw0KDQoJCQkJcCgnPC90cj4nKTsNCg0KCQkJCXAoJzx0ciBjbGFzcz0iYWx0MSIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnYWx0MVwnOyI+Jyk7DQoNCgkJCQlwKCc8dGQ+U2l6ZTwvdGQ+PHRkPicuJGluZm9bJ3NpemUnXS4nPC90ZD4nKTsNCg0KCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCQlwKCc8dHIgY2xhc3M9ImFsdDIiIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJ2FsdDJcJzsiPicpOw0KDQoJCQkJcCgnPHRkPkxhc3QgYmFja3VwPC90ZD48dGQ+Jy4kaW5mb1snREJCdXBEYXRlJ10uJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQlwKCc8L3RyPicpOw0KDQoJCQkJcCgnPHRyIGNsYXNzPSJhbHQxIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdhbHQxXCc7Ij4nKTsNCg0KCQkJCXAoJzx0ZD5MYXN0IGRpZmZlcmVudGlhbCBiYWNrdXA8L3RkPjx0ZD4nLiRpbmZvWydEaWZCdXBEYXRlJ10uJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQlwKCc8L3RyPicpOw0KDQoJCQkJcCgnPHRyIGNsYXNzPSJhbHQyIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdhbHQyXCc7Ij4nKTsNCg0KCQkJCXAoJzx0ZD5MYXN0IGxvZyBiYWNrdXA8L3RkPjx0ZD4nLiRpbmZvWydKb3VybmFsQnVwRGF0ZSddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJcCgnPC90cj4nKTsNCg0KCQkJCXRiZm9vdCgpOw0KDQoJCQkJcCgnPGJyIC8+PGJyIC8+Jyk7DQoNCgkJCQkNCg0KCQkJCSRyZXN1bHQgPSBtc3EoIkVYRUMgc3BfaGVscGZpbGUiKTsNCg0KCQkJCSRyb3dkYiA9IGFycmF5KCk7DQoNCgkJCQl3aGlsZSAoJHJvdyA9IG1zc3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpKSB7DQoNCgkJCQkJJHJvd2RiW10gPSAkcm93Ow0KDQoJCQkJfQ0KDQoJCQkJZm9yZWFjaCgkcm93ZGIgYXMgJHJvdyl7DQoNCgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KCQkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KDQoJCQkJCXAoJzx0ZCBjb2xzcGFuPSIyIj4nLiRyb3dbJ25hbWUnXS4nPC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXAoJzx0ciBjbGFzcz0iYWx0MSIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnYWx0MVwnOyI+Jyk7DQoNCgkJCQkJcCgnPHRkPkZpbGVuYW1lPC90ZD48dGQ+Jy4kcm93WydmaWxlbmFtZSddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCQkJcCgnPHRyIGNsYXNzPSJhbHQyIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdhbHQyXCc7Ij4nKTsNCg0KCQkJCQlwKCc8dGQ+RmlsZWdyb3VwPC90ZD48dGQ+Jy4kcm93WydmaWxlZ3JvdXAnXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXAoJzx0ciBjbGFzcz0iYWx0MSIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnYWx0MVwnOyI+Jyk7DQoNCgkJCQkJcCgnPHRkPlNpemU8L3RkPjx0ZD4nLiRyb3dbJ3NpemUnXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXAoJzx0ciBjbGFzcz0iYWx0MiIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnYWx0MlwnOyI+Jyk7DQoNCgkJCQkJcCgnPHRkPk1heHNpemU8L3RkPjx0ZD4nLiRyb3dbJ21heHNpemUnXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXAoJzx0ciBjbGFzcz0iYWx0MSIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnYWx0MVwnOyI+Jyk7DQoNCgkJCQkJcCgnPHRkPkdyb3d0aDwvdGQ+PHRkPicuJHJvd1snZ3Jvd3RoJ10uJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQlwKCc8dHIgY2xhc3M9ImFsdDIiIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJ2FsdDJcJzsiPicpOw0KDQoJCQkJCXAoJzx0ZD5Vc2FnZTwvdGQ+PHRkPicuJHJvd1sndXNhZ2UnXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXRiZm9vdCgpOw0KDQoJCQkJCXAoJzxiciAvPjxiciAvPicpOw0KDQoJCQkJfQ0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJGdldG51bXNxbCA9ICcnOw0KDQoJCQkJJHJ1bnF1ZXJ5ID0gMDsNCg0KCQkJCWlmICgkc3FsX3F1ZXJ5KSB7DQoNCgkJCQkJJHJ1bnF1ZXJ5ID0gMTsNCg0KCQkJCX0NCg0KCQkJCSRhbGxvd2VkaXQgPSAwOw0KDQoJCQkJaWYgKCR0YWJsZW5hbWUgJiYgISRzcWxfcXVlcnkpIHsNCg0KCQkJCQkkc3FsX3F1ZXJ5ID0gIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSI7DQoNCgkJCQkJJGdldG51bXNxbCA9ICJTRUxFQ1QgY291bnQoKikgRlJPTSAkdGFibGVuYW1lIjsNCg0KCQkJCQkkYWxsb3dlZGl0ID0gMTsNCg0KCQkJCX0NCg0KDQoNCgkJCQlwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIj4nKTsNCg0KCQkJCXAoJzxwPjx0YWJsZSB3aWR0aD0iMjAwIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZCBjb2xzcGFuPSIyIj5SdW4gU1FMIHF1ZXJ5L3F1ZXJpZXMgb24gZGF0YWJhc2UgJy4kZGJuYW1lLic6PC90ZD48L3RyPjx0cj48dGQ+PHRleHRhcmVhIG5hbWU9InNxbF9xdWVyeSIgY2xhc3M9ImFyZWEiIHN0eWxlPSJ3aWR0aDo2MDBweDtoZWlnaHQ6NTBweDtvdmVyZmxvdzphdXRvOyI+Jy5odG1sc3BlY2lhbGNoYXJzKCRzcWxfcXVlcnksRU5UX1FVT1RFUykuJzwvdGV4dGFyZWE+PC90ZD48dGQgc3R5bGU9InBhZGRpbmc6MCA1cHg7Ij48aW5wdXQgY2xhc3M9ImJ0IiBzdHlsZT0iaGVpZ2h0OjUwcHg7IiBuYW1lPSJzdWJtaXQiIHR5cGU9InN1Ym1pdCIgdmFsdWU9IlF1ZXJ5IiAvPjwvdGQ+PC90cj48L3RhYmxlPjwvcD4nKTsNCg0KCQkJCW1ha2VoaWRlKCd0YWJsZW5hbWUnLCAkdGFibGVuYW1lKTsNCg0KCQkJCW1ha2VoaWRlKCdhY3Rpb24nLCdtc3NxbGFkbWluJyk7DQoNCgkJCQlwKCRkYmZvcm0pOw0KDQoJCQkJcCgnPC9mb3JtPicpOw0KDQoJCQkJaWYgKCR0YWJsZW5hbWUgfHwgKCRydW5xdWVyeSAmJiAkc3FsX3F1ZXJ5KSkgew0KDQoJCQkJCWlmICgkZG9pbmcgPT0gJ3N0cnVjdHVyZScpIHsNCg0KCQkJCQkJJHJlc3VsdCA9IG1zcSgic2VsZWN0IGIubmFtZSxjLm5hbWUgYXMgdHlwZSxjLnh0eXBlLGIubGVuZ3RoLGIuaXNudWxsYWJsZSxiLmNvbHN0YXQsY2FzZSB3aGVuIGIuYXV0b3ZhbCBpcyBudWxsIHRoZW4gMCBlbHNlIDEgZW5kLGIuY29saWQsYS5pZCxkLnRleHQgZnJvbSBzeXNvYmplY3RzIGEgam9pbiBzeXNjb2x1bW5zIGIgb24gYS5pZCA9IGIuaWQgam9pbiBzeXN0eXBlcyBjIG9uIGIueHR5cGUgPSBjLnh0eXBlIGFuZCBjLnVzZXJ0eXBlIDw+IDE4IGxlZnQgam9pbiBzeXNjb21tZW50cyBkIG9uIGQuaWQgPSBiLmNkZWZhdWx0IHdoZXJlIGEuaWQgPSBPQkpFQ1RfSUQoJyR0YWJsZW5hbWUnKSBvcmRlciBieSBiLmNvbGlkIik7DQoNCgkJCQkJCSRyb3dkYiA9IGFycmF5KCk7DQoNCgkJCQkJCXdoaWxlKCRyb3cgPSBtc3NxbF9mZXRjaF9hcnJheSgkcmVzdWx0KSkgew0KDQoJCQkJCQkJJHJvd2RiW10gPSAkcm93Ow0KDQoJCQkJCQl9DQoNCgkJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCgkJCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7DQoNCgkJCQkJCXAoJzx0ZD5GaWVsZDwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD5UeXBlPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPkxlbmd0aDwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD5Jc251bGxhYmxlPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPktleTwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD5EZWZhdWx0PC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPkV4dHJhPC90ZD4nKTsNCg0KCQkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQkJZm9yZWFjaCAoJHJvd2RiIGFzICRyb3cpIHsNCg0KCQkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOw0KDQoJCQkJCQkJcCgnPHRkPicuJHJvd1snbmFtZSddLic8L3RkPicpOw0KDQoJCQkJCQkJcCgnPHRkPicuJHJvd1sndHlwZSddLidbJy4kcm93Wyd4dHlwZSddLiddPC90ZD4nKTsNCg0KCQkJCQkJCXAoJzx0ZD4nLiRyb3dbJ2xlbmd0aCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQkJcCgnPHRkPicuKCRyb3dbJ2lzbnVsbGFibGUnXSA/ICdZZXMnIDogJ05vJykuJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQkJCQlwKCc8dGQ+Jy4oJHJvd1snY29sc3RhdCddID8gJ1BSSU1BUlknIDogJycpLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQkJcCgnPHRkPicuJHJvd1sndGV4dCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQkJcCgnPHRkPicuKCRyb3dbJ2F1dG92YWwnXSA/ICdBdXRvX2luY3JlbWVudCcgOiAnJykuJyZuYnNwOzwvdGQ+Jyk7DQoNCgkJCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCQl9DQoNCgkJCQkJCXRiZm9vdCgpOw0KDQoJCQkJCX0gZWxzZWlmICgkZG9pbmcgPT0gJ2luc2VydCcgfHwgJGRvaW5nID09ICdlZGl0JykgewkJCQkJDQoNCgkJCQkJCSRyZXN1bHQgPSBtc3EoInNlbGVjdCBiLm5hbWUsYy5uYW1lIGFzIHR5cGUsYy54dHlwZSxiLmxlbmd0aCxiLmlzbnVsbGFibGUsYi5jb2xzdGF0LGNhc2Ugd2hlbiBiLmF1dG92YWwgaXMgbnVsbCB0aGVuIDAgZWxzZSAxIGVuZCxiLmNvbGlkLGEuaWQsZC50ZXh0IGZyb20gc3lzb2JqZWN0cyBhIGpvaW4gc3lzY29sdW1ucyBiIG9uIGEuaWQgPSBiLmlkIGpvaW4gc3lzdHlwZXMgYyBvbiBiLnh0eXBlID0gYy54dHlwZSBhbmQgYy51c2VydHlwZSA8PiAxOCBsZWZ0IGpvaW4gc3lzY29tbWVudHMgZCBvbiBkLmlkID0gYi5jZGVmYXVsdCB3aGVyZSBhLmlkID0gT0JKRUNUX0lEKCckdGFibGVuYW1lJykgb3JkZXIgYnkgYi5jb2xpZCIpOw0KDQoJCQkJCQkkcm93ZGIgPSBhcnJheSgpOw0KDQoJCQkJCQl3aGlsZSgkdGIgPSBAbXNzcWxfZmV0Y2hfYXNzb2MoJHJlc3VsdCkpIHsNCg0KCQkJCQkJCSRyb3dkYlskdGJbJ25hbWUnXV0gPSAkdGI7DQoNCgkJCQkJCQkkcm93ZGJbJHRiWyduYW1lJ11dWydLZXknXSA9ICR0YlsnY29sc3RhdCddOw0KDQoJCQkJCQkJJHJvd2RiWyR0YlsnbmFtZSddXVsnQXV0byddID0gJHRiWydhdXRvdmFsJ107DQoNCgkJCQkJCX0NCg0KCQkJCQkJJHJzID0gYXJyYXkoKTsNCg0KCQkJCQkJaWYgKCRkb2luZyA9PSAnaW5zZXJ0Jykgew0KDQoJCQkJCQkJcCgnPGgyPkluc2VydCBuZXcgbGluZSBpbiAnLiR0YWJsZW5hbWUuJyB0YWJsZSAmcmFxdW87PC9oMj4nKTsNCg0KCQkJCQkJfSBlbHNlIHsNCg0KCQkJCQkJCXAoJzxoMj5VcGRhdGUgcmVjb3JkIGluICcuJHRhYmxlbmFtZS4nIHRhYmxlICZyYXF1bzs8L2gyPicpOw0KDQoJCQkJCQkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsNCg0KDQoNCgkJCQkJCQkkcmVzdWx0ID0gbXNxKCJTRUxFQ1QgdG9wIDEgKiBGUk9NICR0YWJsZW5hbWUgV0hFUkUgJHdoZXJlIik7DQoNCgkJCQkJCQkkcnMgPSBtc3NxbF9mZXRjaF9hcnJheSgkcmVzdWx0KTsNCg0KCQkJCQkJfQ0KDQoJCQkJCQlwKCc8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iJy4kc2VsZi4nIj4nKTsNCg0KCQkJCQkJcCgkZGJmb3JtKTsNCg0KCQkJCQkJbWFrZWhpZGUoJ2FjdGlvbicsJ21zc3FsYWRtaW4nKTsNCg0KCQkJCQkJbWFrZWhpZGUoJ3RhYmxlbmFtZScsJHRhYmxlbmFtZSk7DQoNCgkJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCg0KDQoJCQkJCQlmb3JlYWNoICgkcm93ZGIgYXMgJHJvdykgew0KDQoJCQkJCQkJaWYgKCRyc1skcm93WyduYW1lJ11dKSB7DQoNCgkJCQkJCQkJJHZhbHVlID0gaHRtbHNwZWNpYWxjaGFycygkcnNbJHJvd1snbmFtZSddXSk7DQoNCgkJCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQkJCSR2YWx1ZSA9ICcnOw0KDQoJCQkJCQkJfQ0KDQoJCQkJCQkJJHRoaXNiZyA9IGJnKCk7DQoNCgkJCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCQkJCQlpZiAoJHJvd1snS2V5J10gfHwgJHJvd1snQXV0byddKSB7DQoNCgkJCQkJCQkJcCgnPHRkPjxiPicuJHJvd1snbmFtZSddLic8L2I+PGJyIC8+Jy4kcm93Wyd0eXBlJ10uJygnLiRyb3dbJ2xlbmd0aCddLicpJy4oJHJvd1snY29sc3RhdCddID8gJzxiciAvPjxiPlBSSU1BUlk8L2I+JyA6ICcnKS4oJHJvd1snYXV0b3ZhbCddID8gJyA8YnIgLz48Yj5BdXRvPC9iPicgOiAnJykuJzwvdGQ+PHRkPicuJHZhbHVlLicmbmJzcDs8L3RkPjwvdHI+Jyk7DQoNCgkJCQkJCQl9IGVsc2UgewkJCQkJCQkNCg0KCQkJCQkJCQlwKCc8dGQ+PGI+Jy4kcm93WyduYW1lJ10uJzwvYj48YnIgLz4nLiRyb3dbJ3R5cGUnXS4nKCcuJHJvd1snbGVuZ3RoJ10uJyknLigkcm93Wydjb2xzdGF0J10gPyAnPGJyIC8+PGI+UFJJTUFSWTwvYj4nIDogJycpLigkcm93WydhdXRvdmFsJ10gPyAnIDxiciAvPjxiPkF1dG88L2I+JyA6ICcnKS4nPC90ZD48dGQ+PHRleHRhcmVhIGNsYXNzPSJhcmVhIiBuYW1lPSJpbnNlcnRzcWxbJy4kcm93WyduYW1lJ10uJ10iIHN0eWxlPSJ3aWR0aDo1MDBweDtoZWlnaHQ6NjBweDtvdmVyZmxvdzphdXRvOyI+Jy4kdmFsdWUuJzwvdGV4dGFyZWE+PC90ZD48L3RyPicpOw0KDQoJCQkJCQkJfQ0KDQoJCQkJCQl9DQoNCgkJCQkJCWlmICgkZG9pbmcgPT0gJ2luc2VydCcpIHsNCg0KCQkJCQkJCXAoJzx0ciBjbGFzcz0iJy5iZygpLiciPjx0ZCBjb2xzcGFuPSIyIj48aW5wdXQgY2xhc3M9ImJ0IiB0eXBlPSJzdWJtaXQiIG5hbWU9Imluc2VydCIgdmFsdWU9Ikluc2VydCIgLz48L3RkPjwvdHI+Jyk7DQoNCgkJCQkJCX0gZWxzZSB7DQoNCgkJCQkJCQlwKCc8dHIgY2xhc3M9IicuYmcoKS4nIj48dGQgY29sc3Bhbj0iMiI+PGlucHV0IGNsYXNzPSJidCIgdHlwZT0ic3VibWl0IiBuYW1lPSJ1cGRhdGUiIHZhbHVlPSJVcGRhdGUiIC8+PC90ZD48L3RyPicpOw0KDQoJCQkJCQkJbWFrZWhpZGUoJ2Jhc2U2NCcsICRiYXNlNjQpOw0KDQoJCQkJCQl9DQoNCgkJCQkJCXAoJzwvdGFibGU+PC9mb3JtPicpOw0KDQoJCQkJCX0gZWxzZSB7DQoNCgkJCQkJCSRxdWVyeXMgPSBAZXhwbG9kZSgnOycsJHNxbF9xdWVyeSk7DQoNCgkJCQkJCWZvcmVhY2goJHF1ZXJ5cyBhcyAkbnVtPT4kcXVlcnkpIHsNCg0KCQkJCQkJCWlmICgkcXVlcnkpIHsNCg0KCQkJCQkJCQlwKCI8cD48Yj5RdWVyeSN7JG51bX0gOiAiLmh0bWxzcGVjaWFsY2hhcnMoJHF1ZXJ5LEVOVF9RVU9URVMpLiI8L2I+PC9wPiIpOw0KDQoJCQkJCQkJCXN3aXRjaChtc3F5KCRxdWVyeSkpDQoNCgkJCQkJCQkJew0KDQoJCQkJCQkJCQljYXNlIDA6DQoNCgkJCQkJCQkJCQlwKCc8aDI+RXJyb3IgOiAnLm1zbXNnKCkuJzwvaDI+Jyk7DQoNCgkJCQkJCQkJCQlicmVhazsJDQoNCgkJCQkJCQkJCWNhc2UgMToNCg0KCQkJCQkJCQkJCWlmIChzdHJ0b2xvd2VyKHN1YnN0cigkcXVlcnksMCwxMykpID09ICdzZWxlY3QgKiBmcm9tJykgew0KDQoJCQkJCQkJCQkJCSRhbGxvd2VkaXQgPSAxOw0KDQoJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQkJaWYgKCRnZXRudW1zcWwpIHsNCg0KCQkJCQkJCQkJCQkkdGF0b2wgPSBtc3NxbF9mZXRjaF9hcnJheShtc3EoIlNFTEVDVCBjb3VudCgqKSBGUk9NICR0YWJsZW5hbWUiKSk7DQoNCgkJCQkJCQkJCQkJJHRhdG9sID0gJHRhdG9sWzBdOw0KDQoJCQkJCQkJCQkJCSRtdWx0aXBhZ2UgPSBtdWx0aSgkdGF0b2wsICRwYWdlbnVtLCAkcGFnZSwgJHRhYmxlbmFtZSk7DQoNCgkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQlpZiAoISR0YWJsZW5hbWUpIHsNCg0KCQkJCQkJCQkJCQkkc3FsX2xpbmUgPSBzdHJfcmVwbGFjZShhcnJheSgiXHIiLCAiXG4iLCAiXHQiKSwgYXJyYXkoJyAnLCAnICcsICcgJyksIHRyaW0oaHRtbHNwZWNpYWxjaGFycygkcXVlcnkpKSk7DQoNCgkJCQkJCQkJCQkJJHNxbF9saW5lID0gcHJlZ19yZXBsYWNlKCIvXC9cKlteKFwqXC8pXSpcKlwvL2kiLCAiICIsICRzcWxfbGluZSk7DQoNCgkJCQkJCQkJCQkJcHJlZ19tYXRjaF9hbGwoIi9mcm9tXHMrYHswLDF9KFtcd10rKWB7MCwxfVxzKy9pIiwkc3FsX2xpbmUsJG1hdGNoZXMpOw0KDQoJCQkJCQkJCQkJCSR0YWJsZW5hbWUgPSAkbWF0Y2hlc1sxXVswXTsNCg0KCQkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJCXAoJG11bHRpcGFnZSk7DQoNCgkJCQkJCQkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiPicpOw0KDQoJCQkJCQkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsNCg0KCQkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQ+QWN0aW9uPC90ZD4nKTsNCg0KDQoNCgkJCQkJCQkJCQkkcmVzdWx0ID0gbXNxKCJzZWxlY3QgYi5uYW1lLGMubmFtZSBhcyB0eXBlLGMueHR5cGUsYi5sZW5ndGgsYi5pc251bGxhYmxlLGIuY29sc3RhdCxjYXNlIHdoZW4gYi5hdXRvdmFsIGlzIG51bGwgdGhlbiAwIGVsc2UgMSBlbmQsYi5jb2xpZCxhLmlkLGQudGV4dCBmcm9tIHN5c29iamVjdHMgYSBqb2luIHN5c2NvbHVtbnMgYiBvbiBhLmlkID0gYi5pZCBqb2luIHN5c3R5cGVzIGMgb24gYi54dHlwZSA9IGMueHR5cGUgYW5kIGMudXNlcnR5cGUgPD4gMTggbGVmdCBqb2luIHN5c2NvbW1lbnRzIGQgb24gZC5pZCA9IGIuY2RlZmF1bHQgd2hlcmUgYS5pZCA9IE9CSkVDVF9JRCgnJHRhYmxlbmFtZScpIG9yZGVyIGJ5IGIuY29saWQiKTsNCg0KCQkJCQkJCQkJCSRyb3dkYiA9IGFycmF5KCk7DQoNCgkJCQkJCQkJCQkka2V5ZmllZCA9ICcnOyAvLyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzE0NjI7JiMxMjk7fw0KDQoJCQkJCQkJCQkJd2hpbGUoJHRiID0gQG1zc3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoNCgkJCQkJCQkJCQkJcCgnPHRkIG5vd3JhcD4nLiR0YlsnbmFtZSddLic8YnI+PHNwYW4+Jy4kdGJbJ3R5cGUnXS4nKCcuJHRiWydsZW5ndGgnXS4nKSAnLigkdGJbJ2NvbHN0YXQnXSA/ICc8Yj4gLSBQUklNQVJZPC9iPicgOiAnJykuKCR0YlsnYXV0b3ZhbCddID8gJzxiPiAtIEF1dG88L2I+JyA6ICcnKS4nPC9zcGFuPjwvdGQ+Jyk7DQoNCgkJCQkJCQkJCQkJJHJvd2RiWyR0YlsnbmFtZSddXVsnS2V5J10gPSAkdGJbJ2NvbHN0YXQnXTsNCg0KCQkJCQkJCQkJCQkkcm93ZGJbJHRiWyduYW1lJ11dWydBdXRvJ10gPSAkdGJbJ2F1dG92YWwnXTsNCg0KCQkJCQkJCQkJCQlpZiAoJHRiWydjb2xzdGF0J10pIHsNCg0KCQkJCQkJCQkJCQkJJGtleWZpZWQgPSAkdGJbJ25hbWUnXTsNCg0KCQkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCQkJCQkJDQoNCgkJCQkJCQkJCQkvLyYjMTQ1NzsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fw0KDQoJCQkJCQkJCQkJaWYgKHN0cnRvbG93ZXIoc3Vic3RyKCRxdWVyeSwwLDEzKSkgPT0gJ3NlbGVjdCAqIGZyb20nKSB7DQoNCgkJCQkJCQkJCQkJJHF1ZXJ5IC49ICIgb3JkZXIgYnkgJGtleWZpZWQgREVTQyI7DQoNCgkJCQkJCQkJCQl9DQoNCg0KDQoJCQkJCQkJCQkJJHJlc3VsdCA9IG1zcSgkcXVlcnkpOw0KDQoJCQkJCQkJCQkJJGluZGV4PTA7DQoNCgkJCQkJCQkJCQlpZigkcGFnZW51bT4wKSBtc3NxbF9kYXRhX3NlZWsoJHJlc3VsdCwkc3RhcnRfbGltaXQpOw0KDQoJCQkJCQkJCQkJd2hpbGUoJG1uID0gQG1zc3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpKXsNCg0KCQkJCQkJCQkJCQlpZigkaW5kZXg+JHBhZ2VudW0tMSkgYnJlYWs7DQoNCg0KDQoJCQkJCQkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQkJCQkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsNCg0KCQkJCQkJCQkJCQkkd2hlcmUgPSAkdG1wID0gJGIxID0gJyc7DQoNCgkJCQkJCQkJCQkJLy8mIzExMjE7JiM1NDU7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTQ2MjsmIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KCQkJCQkJCQkJCQlmb3JlYWNoKCRtbiBhcyAka2V5PT4kaW5zaWRlKXsNCg0KCQkJCQkJCQkJCQkJaWYgKCRpbnNpZGUpIHsNCg0KCQkJCQkJCQkJCQkJCS8vJiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7f4q3JiMxMjExOyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTMxMzsmIzEyOTt/JiMxMjk7fyYjMTMzNDsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyNjk7JiMxMjk7fyYjMTI5O38mIzE0NjI7irImIzEyOTt/JiMxMjk7fyYjMTIwNTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzg2NzsmIzE0NjU7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzE0NjI7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiM5Mzg7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KCQkJCQkJCQkJCQkJCWlmICgkcm93ZGJbJGtleV1bJ0tleSddID09IDEgfHwgJHJvd2RiWyRrZXldWydBdXRvJ10gPT0gMSkgew0KDQoJCQkJCQkJCQkJCQkJCSR3aGVyZSA9ICRrZXkuIj0nIi5hZGRzbGFzaGVzKCRpbnNpZGUpLiInIjsNCg0KCQkJCQkJCQkJCQkJCQlicmVhazsNCg0KCQkJCQkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJCQkJCSR3aGVyZSAuPSAkdG1wLiRrZXkuIj0nIi5hZGRzbGFzaGVzKCRpbnNpZGUpLiInIjsNCg0KCQkJCQkJCQkJCQkJCSR0bXAgPSAnIEFORCAnOw0KDQoJCQkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQkJCS8vJiMxMjk7fyYjMTI5O38mIzU0NTsmIzEyOTt/JiMxMjk7fyYjMTg4OyYjMTI5O38mIzEyOTt/DQoNCgkJCQkJCQkJCQkJZm9yZWFjaCgkbW4gYXMgJGtleT0+JGluc2lkZSl7DQoNCgkJCQkJCQkJCQkJCSRiMSAuPSAnPHRkIG5vd3JhcD4nLmh0bWxfY2xlYW4oJGluc2lkZSkuJyZuYnNwOzwvdGQ+JzsNCg0KCQkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQkJJHdoZXJlID0gYmFzZTY0X2VuY29kZSgkd2hlcmUpOw0KDQoNCg0KCQkJCQkJCQkJCQlpZiAoJGFsbG93ZWRpdCkgcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0OmVkaXRyZWNvcmQoXCdlZGl0XCcsIFwnJy4kd2hlcmUuJ1wnLCBcJycuJHRhYmxlbmFtZS4nXCcpOyI+RWRpdDwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OmVkaXRyZWNvcmQoXCdkZWxcJywgXCcnLiR3aGVyZS4nXCcsIFwnJy4kdGFibGVuYW1lLidcJyk7Ij5EZWw8L2E+PC90ZD4nKTsNCg0KDQoNCgkJCQkJCQkJCQkJcCgkYjEpOw0KDQoJCQkJCQkJCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCQkJCQkJCQkJJGluZGV4Kys7DQoNCgkJCQkJCQkJCQkJdW5zZXQoJGIxKTsNCg0KCQkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJCXRiZm9vdCgpOw0KDQoJCQkJCQkJCQkJcCgkbXVsdGlwYWdlKTsNCg0KCQkJCQkJCQkJCWJyZWFrOwkNCg0KCQkJCQkJCQkJY2FzZSAyOg0KDQoJCQkJCQkJCQkJJGFyID0gbXNzcWxfYWZmZWN0ZWRfcm93cygpOw0KDQoJCQkJCQkJCQkJcCgnPGgyPmFmZmVjdGVkIHJvd3MgOiA8Yj4nLiRhci4nPC9iPjwvaDI+Jyk7DQoNCgkJCQkJCQkJCQlicmVhazsNCg0KCQkJCQkJCQl9DQoNCgkJCQkJCQl9DQoNCgkJCQkJCX0NCg0KCQkJCQl9DQoNCgkJCQl9IGVsc2Ugew0KDQoJCQkJCSRxdWVyeSA9IG1zcSgic2VsZWN0IHN5c29iamVjdHMuaWQsc3lzb2JqZWN0cy5uYW1lLHN5c29iamVjdHMuY2F0ZWdvcnksc3lzdXNlcnMubmFtZSBhcyBvd25lcixzeXNvYmplY3RzLmNyZGF0ZSBmcm9tIHN5c29iamVjdHMgam9pbiBzeXN1c2VycyBvbiBzeXNvYmplY3RzLnVpZCA9IHN5c3VzZXJzLnVpZCB3aGVyZSBzeXNvYmplY3RzLnh0eXBlID0gJ1UnIG9yZGVyIGJ5IHN5c29iamVjdHMubmFtZSBhc2MiKTsNCg0KCQkJCQkkdGFibGVfbnVtID0gMDsNCg0KCQkJCQkkdGFibGVkYiA9IGFycmF5KCk7DQoNCgkJCQkJd2hpbGUoJHRhYmxlID0gbXNzcWxfZmV0Y2hfYXJyYXkoJHF1ZXJ5KSkgew0KDQoJCQkJCQkkdGFibGVfbnVtKys7DQoNCgkJCQkJCSR0YWJsZWRiW10gPSAkdGFibGU7DQoNCgkJCQkJfQ0KDQoJCQkJCXVuc2V0KCR0YWJsZSk7DQoNCg0KDQoJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCgkJCQkJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCI+Jyk7DQoNCgkJCQkJbWFrZWhpZGUoJ2FjdGlvbicsJ21zc3FsYWRtaW4nKTsNCg0KCQkJCQlwKCRkYmZvcm0pOw0KDQoJCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7DQoNCgkJCQkJcCgnPHRkPk5hbWU8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD5Pd25lcjwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPkNyZWF0ZV90aW1lPC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+T3BlcmF0ZTwvdGQ+Jyk7DQoNCgkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQlmb3JlYWNoICgkdGFibGVkYiBhcyAka2V5ID0+ICR0YWJsZSkgew0KDQoJCQkJCQkkdGhpc2JnID0gYmcoKTsNCg0KCQkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOw0KDQoJCQkJCQlwKCc8dGQ+PGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydvd25lciddLicuJy4kdGFibGVbJ25hbWUnXS4nXCcpOyI+Jy4kdGFibGVbJ25hbWUnXS4nPC9hPjwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnb3duZXInXS4nPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPicuJHRhYmxlWydjcmRhdGUnXS4nPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPjxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiRkYm5hbWUuJy4nLiR0YWJsZVsnbmFtZSddLidcJywgXCdpbnNlcnRcJyk7Ij5JbnNlcnQ8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJGRibmFtZS4nLicuJHRhYmxlWyduYW1lJ10uJ1wnLCBcJ3N0cnVjdHVyZVwnKTsiPlN0cnVjdHVyZTwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kZGJuYW1lLicuJy4kdGFibGVbJ25hbWUnXS4nXCcsIFwnZHJvcFwnKTsiPkRyb3A8L2E+PC90ZD4nKTsNCg0KCQkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPHRyIGNsYXNzPScuYmcoKS4nPicpOw0KDQoJCQkJCXAoJzx0ZD5Ub3RhbCB0YWJsZXM6ICcuJHRhYmxlX251bS4nPC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQgY29sc3Bhbj0iMyI+PC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCXAoIjwvdGFibGU+Iik7DQoNCgkJCQkJbXNmcigkcXVlcnkpOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJfQ0KDQoJfQ0KDQoJdGJmb290KCk7DQoNCglpZiAoJGFscmVhZHltc3NxbCkgew0KDQoJCUBtc3NxbF9jbG9zZSgpOw0KDQoJfQ0KDQp9Ly9lbmQgc3FsIGJhY2t1cA0KDQoNCg0KDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnYmFja2Nvbm5lY3QnKSB7DQoNCgkhJHlvdXJpcCAmJiAkeW91cmlwID0gJF9TRVJWRVJbJ1JFTU9URV9BRERSJ107DQoNCgkhJHlvdXJwb3J0ICYmICR5b3VycG9ydCA9ICcxMjM0NSc7DQoNCgkkdXNlZGIgPSBhcnJheSgncGVybCc9PidwZXJsJywnYyc9PidjJyk7DQoNCg0KDQoJJGJhY2tfY29ubmVjdD0iSXlFdmRYTnlMMkpwYmk5d1pYSnNEUXAxYzJVZ1UyOWphMlYwT3cwS0pHTnRaRDBnSW14NWJuZ2lPdzBLSkhONWMzUmxiVDBnSjJWamFHOGdJbUIxYm1GdFpTQXRZV0FpTzJWaiIuDQoNCgkJImFHOGdJbUJwWkdBaU95OWlhVzR2YzJnbk93MEtKREE5SkdOdFpEc05DaVIwWVhKblpYUTlKRUZTUjFaYk1GMDdEUW9rY0c5eWREMGtRVkpIVmxzeFhUc05DaVJwWVdSa2NqMXBibVYwWDJGMGIyNG9KSFIiLg0KDQoJCSJoY21kbGRDa2dmSHdnWkdsbEtDSkZjbkp2Y2pvZ0pDRmNiaUlwT3cwS0pIQmhaR1J5UFhOdlkydGhaR1J5WDJsdUtDUndiM0owTENBa2FXRmtaSElwSUh4OElHUnBaU2dpUlhKeWIzSTZJQ1FoWEc0aUtUIi4NCg0KCQkic05DaVJ3Y205MGJ6MW5aWFJ3Y205MGIySjVibUZ0WlNnbmRHTndKeWs3RFFwemIyTnJaWFFvVTA5RFMwVlVMQ0JRUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z0pIQnliM1J2S1NCOGZDQmthV1VvSSIuDQoNCgkJImtWeWNtOXlPaUFrSVZ4dUlpazdEUXBqYjI1dVpXTjBLRk5QUTB0RlZDd2dKSEJoWkdSeUtTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwdmNHVnVLRk5VUkVsT0xDQWlQaVpUVDBOTFJWUWkiLg0KDQoJCSJLVHNOQ205d1pXNG9VMVJFVDFWVUxDQWlQaVpUVDBOTFJWUWlLVHNOQ205d1pXNG9VMVJFUlZKU0xDQWlQaVpUVDBOTFJWUWlLVHNOQ25ONWMzUmxiU2drYzNsemRHVnRLVHNOQ21Oc2IzTmxLRk5VUkVsIi4NCg0KCQkiT0tUc05DbU5zYjNObEtGTlVSRTlWVkNrN0RRcGpiRzl6WlNoVFZFUkZVbElwT3c9PSI7DQoNCgkkYmFja19jb25uZWN0X2M9IkkybHVZMngxWkdVZ1BITjBaR2x2TG1nK0RRb2phVzVqYkhWa1pTQThjM2x6TDNOdlkydGxkQzVvUGcwS0kybHVZMngxWkdVZ1BHNWxkR2x1WlhRdmFXNHVhRDROQ21sdWRDIi4NCg0KCQkiQnRZV2x1S0dsdWRDQmhjbWRqTENCamFHRnlJQ3BoY21kMlcxMHBEUXA3RFFvZ2FXNTBJR1prT3cwS0lITjBjblZqZENCemIyTnJZV1JrY2w5cGJpQnphVzQ3RFFvZ1kyaGhjaUJ5YlhOYk1qRmRQU0p5YiIuDQoNCgkJIlNBdFppQWlPeUFOQ2lCa1lXVnRiMjRvTVN3d0tUc05DaUJ6YVc0dWMybHVYMlpoYldsc2VTQTlJRUZHWDBsT1JWUTdEUW9nYzJsdUxuTnBibDl3YjNKMElEMGdhSFJ2Ym5Nb1lYUnZhU2hoY21kMld6SmQiLg0KDQoJCSJLU2s3RFFvZ2MybHVMbk5wYmw5aFpHUnlMbk5mWVdSa2NpQTlJR2x1WlhSZllXUmtjaWhoY21kMld6RmRLVHNnRFFvZ1lucGxjbThvWVhKbmRsc3hYU3h6ZEhKc1pXNG9ZWEpuZGxzeFhTa3JNU3R6ZEhKIi4NCg0KCQkic1pXNG9ZWEpuZGxzeVhTa3BPeUFOQ2lCbVpDQTlJSE52WTJ0bGRDaEJSbDlKVGtWVUxDQlRUME5MWDFOVVVrVkJUU3dnU1ZCUVVrOVVUMTlVUTFBcElEc2dEUW9nYVdZZ0tDaGpiMjV1WldOMEtHWmtMQyIuDQoNCgkJIkFvYzNSeWRXTjBJSE52WTJ0aFpHUnlJQ29wSUNaemFXNHNJSE5wZW1WdlppaHpkSEoxWTNRZ2MyOWphMkZrWkhJcEtTazhNQ2tnZXcwS0lDQWdjR1Z5Y205eUtDSmJMVjBnWTI5dWJtVmpkQ2dwSWlrN0QiLg0KDQoJCSJRb2dJQ0JsZUdsMEtEQXBPdzBLSUgwTkNpQnpkSEpqWVhRb2NtMXpMQ0JoY21kMld6QmRLVHNOQ2lCemVYTjBaVzBvY20xektUc2dJQTBLSUdSMWNESW9abVFzSURBcE93MEtJR1IxY0RJb1ptUXNJREVwIi4NCg0KCQkiT3cwS0lHUjFjRElvWm1Rc0lESXBPdzBLSUdWNFpXTnNLQ0l2WW1sdUwzTm9JaXdpYzJnZ0xXa2lMQ0JPVlV4TUtUc05DaUJqYkc5elpTaG1aQ2s3SUEwS2ZRPT0iOw0KDQoNCg0KCWlmICgkc3RhcnQgJiYgJHlvdXJpcCAmJiAkeW91cnBvcnQgJiYgJHVzZSl7DQoNCgkJaWYgKCR1c2UgPT0gJ3BlcmwnKSB7DQoNCgkJCWNmKCcvdG1wL2FuZ2VsX2JjJywkYmFja19jb25uZWN0KTsNCg0KCQkJJHJlcyA9IGV4ZWN1dGUod2hpY2goJ3BlcmwnKS4iIC90bXAvYW5nZWxfYmMgJHlvdXJpcCAkeW91cnBvcnQgJiIpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCWNmKCcvdG1wL2FuZ2VsX2JjLmMnLCRiYWNrX2Nvbm5lY3RfYyk7DQoNCgkJCSRyZXMgPSBleGVjdXRlKCdnY2MgLW8gL3RtcC9hbmdlbF9iYyAvdG1wL2FuZ2VsX2JjLmMnKTsNCg0KCQkJQHVubGluaygnL3RtcC9hbmdlbF9iYy5jJyk7DQoNCgkJCSRyZXMgPSBleGVjdXRlKCIvdG1wL2FuZ2VsX2JjICR5b3VyaXAgJHlvdXJwb3J0ICYiKTsNCg0KCQl9DQoNCgkJbSgiSW50ZW50YW5kbyBjb25lY3RhcnNlIGEgJHlvdXJpcCBwdWVydG8gJHlvdXJwb3J0IC4uLiIpOw0KDQoJfQ0KDQoNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidTaGVsbCBpbnZlcnNhJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2JhY2tjb25uZWN0Jyk7DQoNCglwKCc8cD4nKTsNCg0KCXAoJ0lQOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3lvdXJpcCcsJ3NpemUnPT4yMCwndmFsdWUnPT4keW91cmlwKSk7DQoNCglwKCdQdWVydG86Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neW91cnBvcnQnLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JHlvdXJwb3J0KSk7DQoNCglwKCdVc2FyOicpOw0KDQoJbWFrZXNlbGVjdChhcnJheSgnbmFtZSc9Pid1c2UnLCdvcHRpb24nPT4kdXNlZGIsJ3NlbGVjdGVkJz0+JHVzZSkpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3N0YXJ0JywndmFsdWUnPT4nQ29uZWN0YXInLCd0eXBlJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JykpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KfS8vZW5kIHNxbCBiYWNrdXANCg0KDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnZXZhbCcpIHsNCg0KCSRwaHBjb2RlID0gdHJpbSgkcGhwY29kZSk7DQoNCglpZigkcGhwY29kZSl7DQoNCgkJaWYgKCFwcmVnX21hdGNoKCcjPFw/I3NpJywgJHBocGNvZGUpKSB7DQoNCgkJCSRwaHBjb2RlID0gIjw/cGhwXG5cbnskcGhwY29kZX1cblxuPz4iOw0KDQoJCX0NCg0KCQlldmFsKCI/Ii4iPiRwaHBjb2RlPD8iKTsNCg0KCX0NCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidFamVjdXRhciBQSFAnKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnZXZhbCcpOw0KDQoJbWFrZXRleHQoYXJyYXkoJ3RpdGxlJz0+J0VqZWN1dGFyIFBIUCcsJ25hbWUnPT4ncGhwY29kZScsICd2YWx1ZSc9PiRwaHBjb2RlKSk7DQoNCgkJZm9ybWZvb3RlcigpOw0KDQp9Ly9lbmQgZXZhbA0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdlZGl0ZmlsZScpIHsNCg0KCWlmKGZpbGVfZXhpc3RzKCRvcGZpbGUpKSB7DQoNCgkJJGZwPUBmb3Blbigkb3BmaWxlLCdyJyk7DQoNCgkJJGNvbnRlbnRzPUBmcmVhZCgkZnAsIGZpbGVzaXplKCRvcGZpbGUpKTsNCg0KCQlAZmNsb3NlKCRmcCk7DQoNCgkJJGNvbnRlbnRzPWh0bWxzcGVjaWFsY2hhcnMoJGNvbnRlbnRzKTsNCg0KCX0NCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidDcmVhci9FZGl0YXInKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidBcmNoaXZvIGFjdHVhbCAoaW1wb3J0YXIpJywnbmFtZSc9PidlZGl0ZmlsZW5hbWUnLCd2YWx1ZSc9PiRvcGZpbGUsJ25ld2xpbmUnPT4xKSk7DQoNCgltYWtldGV4dChhcnJheSgndGl0bGUnPT4nQ29udGVuaWRvJywnbmFtZSc9PidmaWxlY29udGVudCcsJ3ZhbHVlJz0+JGNvbnRlbnRzKSk7DQoNCglmb3JtZm9vdGVyKCk7DQoNCgkNCg0KCWdvYmFjaygpOw0KDQoNCg0KfS8vZW5kIGVkaXRmaWxlDQoNCg0KDQplbHNlaWYgKCRhY3Rpb24gPT0gJ25ld3RpbWUnKSB7DQoNCgkkb3BmaWxlbXRpbWUgPSBAZmlsZW10aW1lKCRvcGZpbGUpOw0KDQoJLy8kdGltZSA9IHN0cnRvdGltZSgiJHllYXItJG1vbnRoLSRkYXkgJGhvdXI6JG1pbnV0ZTokc2Vjb25kIik7DQoNCgkkY2FjaGVtb250aCA9IGFycmF5KCdFbmVybyc9PjEsJ0ZlYnJlcm8nPT4yLCdNYXJ6byc9PjMsJ0FicmlsJz0+NCwnTWF5byc9PjUsJ0p1bmlvJz0+NiwnSnVsaW8nPT43LCdBZ29zdG8nPT44LCdTZXB0aWVtYnJlJz0+OSwnT2N0dWJyZSc9PjEwLCdOb3ZpZW1icmUnPT4xMSwnRGljaWVtYnJlJz0+MTIpOw0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0FyY2hpdm8gY2xvbmFkbyBjb24gZmVjaGEnKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidBbHRlcmFyIGFyY2hpdm8nLCduYW1lJz0+J2N1cmZpbGUnLCd2YWx1ZSc9PiRvcGZpbGUsJ3NpemUnPT4xMjAsJ25ld2xpbmUnPT4xKSk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1JlZmVyZW5jaWEgKHJ1dGEpJywnbmFtZSc9Pid0YXJmaWxlJywnc2l6ZSc9PjEyMCwnbmV3bGluZSc9PjEpKTsNCg0KCWZvcm1mb290ZXIoKTsNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidGZWNoYSBNb2RpZmljYWRvJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2ZpbGUnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQXJjaGl2byBhY3R1YWwgKHJ1dGEpJywnbmFtZSc9PidjdXJmaWxlJywndmFsdWUnPT4kb3BmaWxlLCdzaXplJz0+MTIwLCduZXdsaW5lJz0+MSkpOw0KDQoJcCgnPHA+SW5zdGVhZCAmcmFxdW87Jyk7DQoNCglwKCdBJiMxMjk7f286Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neWVhcicsJ3ZhbHVlJz0+ZGF0ZSgnWScsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjQpKTsNCg0KCXAoJ01lczonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidtb250aCcsJ3ZhbHVlJz0+ZGF0ZSgnbScsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsNCg0KCXAoJ0QmIzEyOTt/YTonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYXknLCd2YWx1ZSc9PmRhdGUoJ2QnLCRvcGZpbGVtdGltZSksJ3NpemUnPT4yKSk7DQoNCglwKCdIb3JhOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2hvdXInLCd2YWx1ZSc9PmRhdGUoJ0gnLCRvcGZpbGVtdGltZSksJ3NpemUnPT4yKSk7DQoNCglwKCdNaW51dG86Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nbWludXRlJywndmFsdWUnPT5kYXRlKCdpJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KDQoJcCgnU2VndW5kbzonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidzZWNvbmQnLCd2YWx1ZSc9PmRhdGUoJ3MnLCRvcGZpbGVtdGltZSksJ3NpemUnPT4yKSk7DQoNCglwKCc8L3A+Jyk7DQoNCglmb3JtZm9vdGVyKCk7DQoNCglnb2JhY2soKTsNCg0KfS8vZW5kIG5ld3RpbWUNCg0KDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnc2hlbGwnKSB7DQoNCglpZiAoSVNfV0lOICYmIElTX0NPTSkgew0KDQoJCWlmKCRwcm9ncmFtICYmICRwYXJhbWV0ZXIpIHsNCg0KCQkJJHNoZWxsPSBuZXcgQ09NKCdTaGVsbC5BcHBsaWNhdGlvbicpOw0KDQoJCQkkYSA9ICRzaGVsbC0+U2hlbGxFeGVjdXRlKCRwcm9ncmFtLCRwYXJhbWV0ZXIpOw0KDQoJCQltKCdQcm9ncmFtIHJ1biBoYXMgJy4oISRhID8gJ3N1Y2Nlc3MnIDogJ2ZhaWwnKSk7DQoNCgkJfQ0KDQoJCSEkcHJvZ3JhbSAmJiAkcHJvZ3JhbSA9ICdjOlx3aW5kb3dzXHN5c3RlbTMyXGNtZC5leGUnOw0KDQoJCSEkcGFyYW1ldGVyICYmICRwYXJhbWV0ZXIgPSAnL2MgbmV0IHN0YXJ0ID4gJy5TQV9ST09ULidsb2cudHh0JzsNCg0KCQlmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nRWplY3V0YXIgcHJvZ3JhbWEnKSk7DQoNCgkJbWFrZWhpZGUoJ2FjdGlvbicsJ3NoZWxsJyk7DQoNCgkJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidQcm9ncmFtJywnbmFtZSc9Pidwcm9ncmFtJywndmFsdWUnPT4kcHJvZ3JhbSwnbmV3bGluZSc9PjEpKTsNCg0KCQlwKCc8cD4nKTsNCg0KCQltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1BhcmFtZXRlcicsJ25hbWUnPT4ncGFyYW1ldGVyJywndmFsdWUnPT4kcGFyYW1ldGVyKSk7DQoNCgkJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JywndHlwZSc9PidzdWJtaXQnLCd2YWx1ZSc9PidFeGVjdXRlJykpOw0KDQoJCXAoJzwvcD4nKTsNCg0KCQlmb3JtZm9vdCgpOw0KDQoJfQ0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0VqZWN1dGFyIGNvbWFuZG8nKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnc2hlbGwnKTsNCg0KCWlmIChJU19XSU4gJiYgSVNfQ09NKSB7DQoNCgkJJGV4ZWNmdW5jZGIgPSBhcnJheSgncGhwZnVuYyc9PidwaHBmdW5jJywnd3NjcmlwdCc9Pid3c2NyaXB0JywncHJvY19vcGVuJz0+J3Byb2Nfb3BlbicpOw0KDQoJCW1ha2VzZWxlY3QoYXJyYXkoJ3RpdGxlJz0+J1VzZTonLCduYW1lJz0+J2V4ZWNmdW5jJywnb3B0aW9uJz0+JGV4ZWNmdW5jZGIsJ3NlbGVjdGVkJz0+JGV4ZWNmdW5jLCduZXdsaW5lJz0+MSkpOw0KDQoJfQ0KDQoJcCgnPHA+Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J0NvbWFuZG8nLCduYW1lJz0+J2NvbW1hbmQnLCd2YWx1ZSc9Pmh0bWxzcGVjaWFsY2hhcnMoJGNvbW1hbmQpKSk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnLCd0eXBlJz0+J3N1Ym1pdCcsJ3ZhbHVlJz0+J0VqZWN1dGFyJykpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCglpZiAoJGNvbW1hbmQpIHsNCg0KCQlwKCc8aHIgd2lkdGg9IjEwMCUiIG5vc2hhZGUgLz48cHJlPicpOw0KDQoJCWlmICgkZXhlY2Z1bmM9PSd3c2NyaXB0JyAmJiBJU19XSU4gJiYgSVNfQ09NKSB7DQoNCgkJCSR3c2ggPSBuZXcgQ09NKCdXU2NyaXB0LnNoZWxsJyk7DQoNCgkJCSRleGVjID0gJHdzaC0+ZXhlYygnY21kLmV4ZSAvYyAnLiRjb21tYW5kKTsNCg0KCQkJJHN0ZG91dCA9ICRleGVjLT5TdGRPdXQoKTsNCg0KCQkJJHN0cm91dHB1dCA9ICRzdGRvdXQtPlJlYWRBbGwoKTsNCg0KCQkJZWNobyAkc3Ryb3V0cHV0Ow0KDQoJCX0gZWxzZWlmICgkZXhlY2Z1bmM9PSdwcm9jX29wZW4nICYmIElTX1dJTiAmJiBJU19DT00pIHsNCg0KCQkJJGRlc2NyaXB0b3JzcGVjID0gYXJyYXkoDQoNCgkJCSAgIDAgPT4gYXJyYXkoJ3BpcGUnLCAncicpLA0KDQoJCQkgICAxID0+IGFycmF5KCdwaXBlJywgJ3cnKSwNCg0KCQkJICAgMiA9PiBhcnJheSgncGlwZScsICd3JykNCg0KCQkJKTsNCg0KCQkJJHByb2Nlc3MgPSBwcm9jX29wZW4oJF9TRVJWRVJbJ0NPTVNQRUMnXSwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMpOw0KDQoJCQlpZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7DQoNCgkJCQlmd3JpdGUoJHBpcGVzWzBdLCAkY29tbWFuZC4iXHJcbiIpOw0KDQoJCQkJZndyaXRlKCRwaXBlc1swXSwgImV4aXRcclxuIik7DQoNCgkJCQlmY2xvc2UoJHBpcGVzWzBdKTsNCg0KCQkJCXdoaWxlICghZmVvZigkcGlwZXNbMV0pKSB7DQoNCgkJCQkJZWNobyBmZ2V0cygkcGlwZXNbMV0sIDEwMjQpOw0KDQoJCQkJfQ0KDQoJCQkJZmNsb3NlKCRwaXBlc1sxXSk7DQoNCgkJCQl3aGlsZSAoIWZlb2YoJHBpcGVzWzJdKSkgew0KDQoJCQkJCWVjaG8gZmdldHMoJHBpcGVzWzJdLCAxMDI0KTsNCg0KCQkJCX0NCg0KCQkJCWZjbG9zZSgkcGlwZXNbMl0pOw0KDQoJCQkJcHJvY19jbG9zZSgkcHJvY2Vzcyk7DQoNCgkJCX0NCg0KCQl9IGVsc2Ugew0KDQoJCQllY2hvKGV4ZWN1dGUoJGNvbW1hbmQpKTsNCg0KCQl9DQoNCgkJcCgnPC9wcmU+Jyk7DQoNCgl9DQoNCn0vL2VuZCBzaGVsbA0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdwaHBlbnYnKSB7DQoNCgkkdXBzaXplPWdldGNmZygnZmlsZV91cGxvYWRzJykgPyBnZXRjZmcoJ3VwbG9hZF9tYXhfZmlsZXNpemUnKSA6ICdOb3QgYWxsb3dlZCc7DQoNCgkkYWRtaW5tYWlsPWlzc2V0KCRfU0VSVkVSWydTRVJWRVJfQURNSU4nXSkgPyAkX1NFUlZFUlsnU0VSVkVSX0FETUlOJ10gOiBnZXRjZmcoJ3NlbmRtYWlsX2Zyb20nKTsNCg0KCSEkZGlzX2Z1bmMgJiYgJGRpc19mdW5jID0gJ05vJzsJDQoNCgkkaW5mbyA9IGFycmF5KA0KDQoJCTEgPT4gYXJyYXkoJ0hvcmEgU2Vydmlkb3InLGRhdGUoJ1kvbS9kIGg6aTpzJywkdGltZXN0YW1wKSksDQoNCgkJMiA9PiBhcnJheSgnRG9taW5pbyBTZXJ2aWRvcicsJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pLA0KDQoJCTMgPT4gYXJyYXkoJ0lQIFNlcnZpZG9yJyxnZXRob3N0YnluYW1lKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKSksDQoNCgkJNCA9PiBhcnJheSgnT1MgU2Vydmlkb3InLFBIUF9PUyksDQoNCgkJNSA9PiBhcnJheSgnT1MgQ2hhcnNldCBTZXJ2aWRvcicsJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pLA0KDQoJCTYgPT4gYXJyYXkoJ1NvZnR3YXJlIFNlcnZpZG9yJywkX1NFUlZFUlsnU0VSVkVSX1NPRlRXQVJFJ10pLA0KDQoJCTcgPT4gYXJyYXkoJ1dlYiBQb3J0JywkX1NFUlZFUlsnU0VSVkVSX1BPUlQnXSksDQoNCgkJOCA9PiBhcnJheSgnTW9kbyBkZSBQSFAnLHN0cnRvdXBwZXIocGhwX3NhcGlfbmFtZSgpKSksDQoNCgkJOSA9PiBhcnJheSgnUnV0YSBTaGVsbCcsX19GSUxFX18pLA0KDQoNCg0KCQkxMCA9PiBhcnJheSgnUEhQIFZlcnNpb24nLFBIUF9WRVJTSU9OKSwNCg0KCQkxMSA9PiBhcnJheSgnUEhQSU5GTycsKElTX1BIUElORk8gPyAnPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbihcJ3BocGluZm9cJyk7Ij5ZZXM8L2E+JyA6ICdObycpKSwNCg0KCQkxMiA9PiBhcnJheSgnU2FmZSBNb2RlJyxnZXRjZmcoJ3NhZmVfbW9kZScpKSwNCg0KCQkxMyA9PiBhcnJheSgnQWRtaW5pc3RyYXRvcicsJGFkbWlubWFpbCksDQoNCgkJMTQgPT4gYXJyYXkoJ2FsbG93X3VybF9mb3BlbicsZ2V0Y2ZnKCdhbGxvd191cmxfZm9wZW4nKSksDQoNCgkJMTUgPT4gYXJyYXkoJ2VuYWJsZV9kbCcsZ2V0Y2ZnKCdlbmFibGVfZGwnKSksDQoNCgkJMTYgPT4gYXJyYXkoJ2Rpc3BsYXlfZXJyb3JzJyxnZXRjZmcoJ2Rpc3BsYXlfZXJyb3JzJykpLA0KDQoJCTE3ID0+IGFycmF5KCdyZWdpc3Rlcl9nbG9iYWxzJyxnZXRjZmcoJ3JlZ2lzdGVyX2dsb2JhbHMnKSksDQoNCgkJMTggPT4gYXJyYXkoJ21hZ2ljX3F1b3Rlc19ncGMnLGdldGNmZygnbWFnaWNfcXVvdGVzX2dwYycpKSwNCg0KCQkxOSA9PiBhcnJheSgnbWVtb3J5X2xpbWl0JyxnZXRjZmcoJ21lbW9yeV9saW1pdCcpKSwNCg0KCQkyMCA9PiBhcnJheSgncG9zdF9tYXhfc2l6ZScsZ2V0Y2ZnKCdwb3N0X21heF9zaXplJykpLA0KDQoJCTIxID0+IGFycmF5KCd1cGxvYWRfbWF4X2ZpbGVzaXplJywkdXBzaXplKSwNCg0KCQkyMiA9PiBhcnJheSgnbWF4X2V4ZWN1dGlvbl90aW1lJyxnZXRjZmcoJ21heF9leGVjdXRpb25fdGltZScpLicgc2Vjb25kKHMpJyksDQoNCgkJMjMgPT4gYXJyYXkoJ2Rpc2FibGVfZnVuY3Rpb25zJywkZGlzX2Z1bmMpLA0KDQoJKTsNCg0KDQoNCglpZigkcGhwdmFybmFtZSkgew0KDQoJCW0oJHBocHZhcm5hbWUgLicgOiAnLmdldGNmZygkcGhwdmFybmFtZSkpOw0KDQoJfQ0KDQoNCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidFbnRvcm5vIHNlcnZpZG9yJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3BocGVudicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidJbmdyZXNlIHVuIHBhcmFtZXRybyBQSFAoZWo6bWFnaWNfcXVvdGVzX2dwYyknLCduYW1lJz0+J3BocHZhcm5hbWUnLCd2YWx1ZSc9PiRwaHB2YXJuYW1lLCduZXdsaW5lJz0+MSkpOw0KDQoJZm9ybWZvb3RlcigpOw0KDQoNCg0KCSRocCA9IGFycmF5KDA9PiAnU2VydmVyJywgMT0+ICdQSFAnKTsNCg0KCWZvcigkYT0wOyRhPDI7JGErKykgew0KDQoJCXAoJzxoMj4nLiRocFskYV0uJyAmcmFxdW87PC9oMj4nKTsNCg0KCQlwKCc8dWwgY2xhc3M9ImluZm8iPicpOw0KDQoJCWlmICgkYT09MCkgew0KDQoJCQlmb3IoJGk9MTskaTw9OTskaSsrKSB7DQoNCgkJCQlwKCc8bGk+PHU+Jy4kaW5mb1skaV1bMF0uJzo8L3U+Jy4kaW5mb1skaV1bMV0uJzwvbGk+Jyk7DQoNCgkJCX0NCg0KCQl9IGVsc2VpZiAoJGEgPT0gMSkgew0KDQoJCQlmb3IoJGk9MTA7JGk8PTIzOyRpKyspIHsNCg0KCQkJCXAoJzxsaT48dT4nLiRpbmZvWyRpXVswXS4nOjwvdT4nLiRpbmZvWyRpXVsxXS4nPC9saT4nKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCQlwKCc8L3VsPicpOw0KDQoJfQ0KDQp9Ly9lbmQgcGhwZW52DQoNCg0KDQplbHNlIHsNCg0KCW0oJ1VuZGVmaW5lZCBBY3Rpb24nKTsNCg0KfQ0KDQoNCg0KPz4NCg0KPC90ZD48L3RyPjwvdGFibGU+DQoNCjxkaXYgc3R5bGU9InBhZGRpbmc6MTBweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZmZmO2JvcmRlci10b3A6MXB4IHNvbGlkICNkZGQ7YmFja2dyb3VuZDojZWVlOyI+DQoNCgk8c3BhbiBzdHlsZT0iZmxvYXQ6cmlnaHQ7Ij48P3BocCBkZWJ1Z2luZm8oKTtvYl9lbmRfZmx1c2goKTs/Pjwvc3Bhbj4NCg0KDQo8L2Rpdj4NCg0KPC9ib2R5Pg0KDQo8L2h0bWw+DQoNCg0KDQo8P3BocA0KDQoNCg0KZnVuY3Rpb24gbSgkbXNnKSB7DQoNCgllY2hvICc8ZGl2IHN0eWxlPSJiYWNrZ3JvdW5kOiNmMWYxZjE7Ym9yZGVyOjFweCBzb2xpZCAjZGRkO3BhZGRpbmc6MTVweDtmb250OjE0cHg7dGV4dC1hbGlnbjpjZW50ZXI7Zm9udC13ZWlnaHQ6Ym9sZDsiPic7DQoNCgllY2hvICRtc2c7DQoNCgllY2hvICc8L2Rpdj4nOw0KDQp9DQoNCmZ1bmN0aW9uIHNjb29raWUoJGtleSwgJHZhbHVlLCAkbGlmZSA9IDAsICRwcmVmaXggPSAxKSB7DQoNCglnbG9iYWwgJGFkbWluLCAkdGltZXN0YW1wLCAkX1NFUlZFUjsNCg0KCSRrZXkgPSAoJHByZWZpeCA/ICRhZG1pblsnY29va2llcHJlJ10gOiAnJykuJGtleTsNCg0KCSRsaWZlID0gJGxpZmUgPyAkbGlmZSA6ICRhZG1pblsnY29va2llbGlmZSddOw0KDQoJJHVzZXBvcnQgPSAkX1NFUlZFUlsnU0VSVkVSX1BPUlQnXSA9PSA0NDMgPyAxIDogMDsNCg0KCXNldGNvb2tpZSgka2V5LCAkdmFsdWUsICR0aW1lc3RhbXArJGxpZmUsICRhZG1pblsnY29va2llcGF0aCddLCAkYWRtaW5bJ2Nvb2tpZWRvbWFpbiddLCAkdXNlcG9ydCk7DQoNCn0JDQoNCmZ1bmN0aW9uIG11bHRpKCRudW0sICRwZXJwYWdlLCAkY3VycGFnZSwgJHRhYmxlbmFtZSkgew0KDQoJJG11bHRpcGFnZSA9ICcnOw0KDQoJaWYoJG51bSA+ICRwZXJwYWdlKSB7DQoNCgkJJHBhZ2UgPSAxMDsNCg0KCQkkb2Zmc2V0ID0gNTsNCg0KCQkkcGFnZXMgPSBAY2VpbCgkbnVtIC8gJHBlcnBhZ2UpOw0KDQoJCWlmKCRwYWdlID4gJHBhZ2VzKSB7DQoNCgkJCSRmcm9tID0gMTsNCg0KCQkJJHRvID0gJHBhZ2VzOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSRmcm9tID0gJGN1cnBhZ2UgLSAkb2Zmc2V0Ow0KDQoJCQkkdG8gPSAkY3VycGFnZSArICRwYWdlIC0gJG9mZnNldCAtIDE7DQoNCgkJCWlmKCRmcm9tIDwgMSkgew0KDQoJCQkJJHRvID0gJGN1cnBhZ2UgKyAxIC0gJGZyb207DQoNCgkJCQkkZnJvbSA9IDE7DQoNCgkJCQlpZigoJHRvIC0gJGZyb20pIDwgJHBhZ2UgJiYgKCR0byAtICRmcm9tKSA8ICRwYWdlcykgew0KDQoJCQkJCSR0byA9ICRwYWdlOw0KDQoJCQkJfQ0KDQoJCQl9IGVsc2VpZigkdG8gPiAkcGFnZXMpIHsNCg0KCQkJCSRmcm9tID0gJGN1cnBhZ2UgLSAkcGFnZXMgKyAkdG87DQoNCgkJCQkkdG8gPSAkcGFnZXM7DQoNCgkJCQlpZigoJHRvIC0gJGZyb20pIDwgJHBhZ2UgJiYgKCR0byAtICRmcm9tKSA8ICRwYWdlcykgew0KDQoJCQkJCSRmcm9tID0gJHBhZ2VzIC0gJHBhZ2UgKyAxOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJfQ0KDQoJCSRtdWx0aXBhZ2UgPSAoJGN1cnBhZ2UgLSAkb2Zmc2V0ID4gMSAmJiAkcGFnZXMgPiAkcGFnZSA/ICc8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgMSk7Ij5QcmltZXJhPC9hPiAnIDogJycpLigkY3VycGFnZSA+IDEgPyAnPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnXCcsICcuKCRjdXJwYWdlIC0gMSkuJyk7Ij5BbnRlcmlvcjwvYT4gJyA6ICcnKTsNCg0KCQlmb3IoJGkgPSAkZnJvbTsgJGkgPD0gJHRvOyAkaSsrKSB7DQoNCgkJCSRtdWx0aXBhZ2UgLj0gJGkgPT0gJGN1cnBhZ2UgPyAkaS4nICcgOiAnPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnXCcsICcuJGkuJyk7Ij5bJy4kaS4nXTwvYT4gJzsNCg0KCQl9DQoNCgkJJG11bHRpcGFnZSAuPSAoJGN1cnBhZ2UgPCAkcGFnZXMgPyAnPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnXCcsICcuKCRjdXJwYWdlICsgMSkuJyk7Ij5TaWd1aWVudGU8L2E+JyA6ICcnKS4oJHRvIDwgJHBhZ2VzID8gJyA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgJy4kcGFnZXMuJyk7Ij5VbHRpbWE8L2E+JyA6ICcnKTsNCg0KCQkkbXVsdGlwYWdlID0gJG11bHRpcGFnZSA/ICc8cD5QYWdlczogJy4kbXVsdGlwYWdlLic8L3A+JyA6ICcnOw0KDQoJfQ0KDQoJcmV0dXJuICRtdWx0aXBhZ2U7DQoNCn0NCg0KLy8gJiMxMjk7fyYjMTI5O38mIzE4OTsmIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KZnVuY3Rpb24gbG9naW5wYWdlKCkgew0KDQo/Pg0KDQoJPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KCWlucHV0IHtmb250OjExcHggVmVyZGFuYTtCQUNLR1JPVU5EOiAjRkZGRkZGO2hlaWdodDogMThweDtib3JkZXI6IDFweCBzb2xpZCAjNjY2NjY2O30NCg0KCTwvc3R5bGU+DQoNCgk8Zm9ybSBtZXRob2Q9IlBPU1QiIGFjdGlvbj0iIj4NCg0KCTxzcGFuIHN0eWxlPSJmb250OjExcHggVmVyZGFuYTsiPlBhc3N3b3JkOiA8L3NwYW4+PGlucHV0IG5hbWU9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgc2l6ZT0iMjAiPg0KDQoJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iZG9pbmciIHZhbHVlPSJsb2dpbiI+DQoNCgk8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iRW50cmFyIj4NCg0KCTwvZm9ybT4NCg0KPD9waHANCg0KCWV4aXQ7DQoNCn0vL2VuZCBsb2dpbnBhZ2UoKQ0KDQoNCg0KZnVuY3Rpb24gZXhlY3V0ZSgkY2ZlKSB7DQoNCgkkcmVzID0gJyc7DQoNCglpZiAoJGNmZSkgew0KDQoJCWlmKGZ1bmN0aW9uX2V4aXN0cygnZXhlYycpKSB7DQoNCgkJCUBleGVjKCRjZmUsJHJlcyk7DQoNCgkJCSRyZXMgPSBqb2luKCJcbiIsJHJlcyk7DQoNCgkJfSBlbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzaGVsbF9leGVjJykpIHsNCg0KCQkJJHJlcyA9IEBzaGVsbF9leGVjKCRjZmUpOw0KDQoJCX0gZWxzZWlmKGZ1bmN0aW9uX2V4aXN0cygnc3lzdGVtJykpIHsNCg0KCQkJQG9iX3N0YXJ0KCk7DQoNCgkJCUBzeXN0ZW0oJGNmZSk7DQoNCgkJCSRyZXMgPSBAb2JfZ2V0X2NvbnRlbnRzKCk7DQoNCgkJCUBvYl9lbmRfY2xlYW4oKTsNCg0KCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsNCg0KCQkJQG9iX3N0YXJ0KCk7DQoNCgkJCUBwYXNzdGhydSgkY2ZlKTsNCg0KCQkJJHJlcyA9IEBvYl9nZXRfY29udGVudHMoKTsNCg0KCQkJQG9iX2VuZF9jbGVhbigpOw0KDQoJCX0gZWxzZWlmKEBpc19yZXNvdXJjZSgkZiA9IEBwb3BlbigkY2ZlLCJyIikpKSB7DQoNCgkJCSRyZXMgPSAnJzsNCg0KCQkJd2hpbGUoIUBmZW9mKCRmKSkgew0KDQoJCQkJJHJlcyAuPSBAZnJlYWQoJGYsMTAyNCk7IA0KDQoJCQl9DQoNCgkJCUBwY2xvc2UoJGYpOw0KDQoJCX0NCg0KCX0NCg0KCXJldHVybiAkcmVzOw0KDQp9DQoNCmZ1bmN0aW9uIHdoaWNoKCRwcikgew0KDQoJJHBhdGggPSBleGVjdXRlKCJ3aGljaCAkcHIiKTsNCg0KCXJldHVybiAoJHBhdGggPyAkcGF0aCA6ICRwcik7IA0KDQp9DQoNCg0KDQpmdW5jdGlvbiBjZigkZm5hbWUsJHRleHQpew0KDQoJaWYoJGZwPUBmb3BlbigkZm5hbWUsJ3cnKSkgew0KDQoJCUBmcHV0cygkZnAsQGJhc2U2NF9kZWNvZGUoJHRleHQpKTsNCg0KCQlAZmNsb3NlKCRmcCk7DQoNCgl9DQoNCn0NCg0KZnVuY3Rpb24gZGlyc2l6ZSgkZGlyKSB7IA0KDQoJJGRoID0gQG9wZW5kaXIoJGRpcik7DQoNCgkkc2l6ZSA9IDA7DQoNCgl3aGlsZSgkZmlsZSA9IEByZWFkZGlyKCRkaCkpIHsNCg0KCQlpZiAoJGZpbGUgIT0gJy4nICYmICRmaWxlICE9ICcuLicpIHsNCg0KCQkJJHBhdGggPSAkZGlyLicvJy4kZmlsZTsNCg0KCQkJaWYgKEBpc19kaXIoJHBhdGgpKSB7DQoNCgkJCQkkc2l6ZSArPSBkaXJzaXplKCRwYXRoKTsNCg0KCQkJfSBlbHNlIHsNCg0KCQkJCSRzaXplICs9IEBmaWxlc2l6ZSgkcGF0aCk7DQoNCgkJCX0NCg0KCQl9DQoNCgl9DQoNCglAY2xvc2VkaXIoJGRoKTsNCg0KCXJldHVybiAkc2l6ZTsNCg0KfQ0KDQovLyAmIzEyMDM7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjOTk0Ow0KDQpmdW5jdGlvbiBkZWJ1Z2luZm8oKSB7DQoNCglnbG9iYWwgJHN0YXJ0dGltZTsNCg0KCSRtdGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7DQoNCgkkdG90YWx0aW1lID0gbnVtYmVyX2Zvcm1hdCgoJG10aW1lWzFdICsgJG10aW1lWzBdIC0gJHN0YXJ0dGltZSksIDYpOw0KDQoJZWNobyAnUHJvY2VzYWRvIGVuICcuJHRvdGFsdGltZS4nIHNlZ3VuZG8ocyknOw0KDQp9DQoNCg0KDQovLyYjMTI5O38mIzEyOTt/JiMxMjk7f01ZU1FMJiMxMjk7fyYjMTI5O38mIzE5MTk7JiMxMjk7fw0KDQpmdW5jdGlvbiBteWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lPScnLCRjaGFyc2V0PScnLCRkYnBvcnQ9JzMzMDYnKSB7DQoNCglnbG9iYWwgJGNoYXJzZXRkYjsNCg0KCWlmKCEkbGluayA9IEBteXNxbF9jb25uZWN0KCRkYmhvc3QuJzonLiRkYnBvcnQsICRkYnVzZXIsICRkYnBhc3MpKSB7DQoNCgkJcCgnPGgyPk5vIHNlIHB1ZG8gY29uZWN0YXIgYSBNeVNRTCBzZXJ2ZXI8L2gyPicpOw0KDQoJCWV4aXQ7DQoNCgl9DQoNCglpZigkbGluayAmJiAkZGJuYW1lKSB7DQoNCgkJaWYgKCFAbXlzcWxfc2VsZWN0X2RiKCRkYm5hbWUsICRsaW5rKSkgew0KDQoJCQlwKCc8aDI+RGF0YWJhc2Ugc2VsZWNjaW9uYWRhIGNvbiBlcnJvcmVzPC9oMj4nKTsNCg0KCQkJZXhpdDsNCg0KCQl9DQoNCgl9DQoNCglpZigkbGluayAmJiBteXNxbF9nZXRfc2VydmVyX2luZm8oKSA+ICc0LjEnKSB7DQoNCgkJaWYoaW5fYXJyYXkoc3RydG9sb3dlcigkY2hhcnNldCksICRjaGFyc2V0ZGIpKSB7DQoNCgkJCXEoIlNFVCBjaGFyYWN0ZXJfc2V0X2Nvbm5lY3Rpb249JGNoYXJzZXQsIGNoYXJhY3Rlcl9zZXRfcmVzdWx0cz0kY2hhcnNldCwgY2hhcmFjdGVyX3NldF9jbGllbnQ9YmluYXJ5OyIsICRsaW5rKTsNCg0KCQl9DQoNCgl9DQoNCglyZXR1cm4gJGxpbms7DQoNCn0NCg0KDQoNCi8vJiMxMjk7fyYjMTI5O38mIzEyOTt/TVNTUUwmIzEyOTt/JiMxMjk7fyYjMTkxOTsmIzEyOTt/DQoNCmZ1bmN0aW9uIG1zZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWU9JycpIHsNCg0KCWdsb2JhbCAkYWxyZWFkeW1zc3FsOw0KDQoJQGluaV9zZXQoJ21zc3FsLmNoYXJzZXQnLCAnVVRGLTgnKTsNCg0KCUBpbmlfc2V0KCdtc3NxbC50ZXh0bGltaXQnLCAyMTQ3NDgzNjQ3KTsNCg0KCUBpbmlfc2V0KCdtc3NxbC50ZXh0c2l6ZScsIDIxNDc0ODM2NDcpOw0KDQoJJGFscmVhZHltc3NxbCA9IDE7DQoNCglpZighJGxpbmsgPSBAbXNzcWxfY29ubmVjdCgkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCBmYWxzZSkpIHsNCg0KCQlwKCc8aDI+Jy5tc21zZygpLic8L2gyPicpOw0KDQoJCSRhbHJlYWR5bXNzcWwgPSAwOw0KDQoJCWV4aXQ7DQoNCgl9DQoNCglpZigkbGluayAmJiAkZGJuYW1lKSB7DQoNCgkJaWYgKCFAbXNzcWxfc2VsZWN0X2RiKCRkYm5hbWUsICRsaW5rKSkgew0KDQoJCQlwKCc8aDI+Jy5tc21zZygpLic8L2gyPicpOw0KDQoJCQkkYWxyZWFkeW1zc3FsID0gMDsNCg0KCQkJZXhpdDsNCg0KCQl9DQoNCgl9DQoNCglyZXR1cm4gJGxpbms7DQoNCn0NCg0KDQoNCi8vICYjNTQ5OyYjMTI5O38mIzEyOTt/JiMxNTE0OyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTQ2MzsmIzEyOTt/DQoNCmZ1bmN0aW9uIHNfYXJyYXkoJiRhcnJheSkgew0KDQoJaWYgKGlzX2FycmF5KCRhcnJheSkpIHsNCg0KCQlmb3JlYWNoICgkYXJyYXkgYXMgJGsgPT4gJHYpIHsNCg0KCQkJJGFycmF5WyRrXSA9IHNfYXJyYXkoJHYpOw0KDQoJCX0NCg0KCX0gZWxzZSBpZiAoaXNfc3RyaW5nKCRhcnJheSkpIHsNCg0KCQkkYXJyYXkgPSBzdHJpcHNsYXNoZXMoJGFycmF5KTsNCg0KCX0NCg0KCXJldHVybiAkYXJyYXk7DQoNCn0NCg0KDQoNCi8vICYjMTI5O38mIzEyOTt/JiMxMjk7f0hUTUwmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCmZ1bmN0aW9uIGh0bWxfY2xlYW4oJGNvbnRlbnQpIHsNCg0KCSRjb250ZW50ID0gaHRtbHNwZWNpYWxjaGFycygkY29udGVudCk7DQoNCgkkY29udGVudCA9IHN0cl9yZXBsYWNlKCJcbiIsICI8YnIgLz4iLCAkY29udGVudCk7DQoNCgkkY29udGVudCA9IHN0cl9yZXBsYWNlKCIgICIsICImbmJzcDsmbmJzcDsiLCAkY29udGVudCk7DQoNCgkkY29udGVudCA9IHN0cl9yZXBsYWNlKCJcdCIsICImbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsiLCAkY29udGVudCk7DQoNCglyZXR1cm4gJGNvbnRlbnQ7DQoNCn0NCg0KDQoNCi8vICYjMTI5O38mIzEyOTt/JiM1NDU7JiM1NTI7JiMxMjk7fyYjMTI5O38NCg0KZnVuY3Rpb24gZ2V0Q2htb2QoJGZpbGVwYXRoKXsNCg0KCXJldHVybiBzdWJzdHIoYmFzZV9jb252ZXJ0KEBmaWxlcGVybXMoJGZpbGVwYXRoKSwxMCw4KSwtNCk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIGdldFBlcm1zKCRmaWxlcGF0aCkgew0KDQoJJG1vZGUgPSBAZmlsZXBlcm1zKCRmaWxlcGF0aCk7DQoNCglpZiAoKCRtb2RlICYgMHhDMDAwKSA9PT0gMHhDMDAwKSB7JHR5cGUgPSAncyc7fQ0KDQoJZWxzZWlmICgoJG1vZGUgJiAweDQwMDApID09PSAweDQwMDApIHskdHlwZSA9ICdkJzt9DQoNCgllbHNlaWYgKCgkbW9kZSAmIDB4QTAwMCkgPT09IDB4QTAwMCkgeyR0eXBlID0gJ2wnO30NCg0KCWVsc2VpZiAoKCRtb2RlICYgMHg4MDAwKSA9PT0gMHg4MDAwKSB7JHR5cGUgPSAnLSc7fSANCg0KCWVsc2VpZiAoKCRtb2RlICYgMHg2MDAwKSA9PT0gMHg2MDAwKSB7JHR5cGUgPSAnYic7fQ0KDQoJZWxzZWlmICgoJG1vZGUgJiAweDIwMDApID09PSAweDIwMDApIHskdHlwZSA9ICdjJzt9DQoNCgllbHNlaWYgKCgkbW9kZSAmIDB4MTAwMCkgPT09IDB4MTAwMCkgeyR0eXBlID0gJ3AnO30NCg0KCWVsc2UgeyR0eXBlID0gJz8nO30NCg0KDQoNCgkkb3duZXJbJ3JlYWQnXSA9ICgkbW9kZSAmIDAwNDAwKSA/ICdyJyA6ICctJzsgDQoNCgkkb3duZXJbJ3dyaXRlJ10gPSAoJG1vZGUgJiAwMDIwMCkgPyAndycgOiAnLSc7IA0KDQoJJG93bmVyWydleGVjdXRlJ10gPSAoJG1vZGUgJiAwMDEwMCkgPyAneCcgOiAnLSc7IA0KDQoJJGdyb3VwWydyZWFkJ10gPSAoJG1vZGUgJiAwMDA0MCkgPyAncicgOiAnLSc7IA0KDQoJJGdyb3VwWyd3cml0ZSddID0gKCRtb2RlICYgMDAwMjApID8gJ3cnIDogJy0nOyANCg0KCSRncm91cFsnZXhlY3V0ZSddID0gKCRtb2RlICYgMDAwMTApID8gJ3gnIDogJy0nOyANCg0KCSR3b3JsZFsncmVhZCddID0gKCRtb2RlICYgMDAwMDQpID8gJ3InIDogJy0nOyANCg0KCSR3b3JsZFsnd3JpdGUnXSA9ICgkbW9kZSAmIDAwMDAyKSA/ICd3JyA6ICctJzsgDQoNCgkkd29ybGRbJ2V4ZWN1dGUnXSA9ICgkbW9kZSAmIDAwMDAxKSA/ICd4JyA6ICctJzsgDQoNCg0KDQoJaWYoICRtb2RlICYgMHg4MDAgKSB7JG93bmVyWydleGVjdXRlJ10gPSAoJG93bmVyWydleGVjdXRlJ109PSd4JykgPyAncycgOiAnUyc7fQ0KDQoJaWYoICRtb2RlICYgMHg0MDAgKSB7JGdyb3VwWydleGVjdXRlJ10gPSAoJGdyb3VwWydleGVjdXRlJ109PSd4JykgPyAncycgOiAnUyc7fQ0KDQoJaWYoICRtb2RlICYgMHgyMDAgKSB7JHdvcmxkWydleGVjdXRlJ10gPSAoJHdvcmxkWydleGVjdXRlJ109PSd4JykgPyAndCcgOiAnVCc7fQ0KDQogDQoNCglyZXR1cm4gJHR5cGUuJG93bmVyWydyZWFkJ10uJG93bmVyWyd3cml0ZSddLiRvd25lclsnZXhlY3V0ZSddLiRncm91cFsncmVhZCddLiRncm91cFsnd3JpdGUnXS4kZ3JvdXBbJ2V4ZWN1dGUnXS4kd29ybGRbJ3JlYWQnXS4kd29ybGRbJ3dyaXRlJ10uJHdvcmxkWydleGVjdXRlJ107DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIGdldFVzZXIoJGZpbGVwYXRoKQl7DQoNCglpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRwd3VpZCcpKSB7DQoNCgkJJGFycmF5ID0gQHBvc2l4X2dldHB3dWlkKEBmaWxlb3duZXIoJGZpbGVwYXRoKSk7DQoNCgkJaWYgKCRhcnJheSAmJiBpc19hcnJheSgkYXJyYXkpKSB7DQoNCgkJCXJldHVybiAnIC8gPGEgaHJlZj0iIyIgdGl0bGU9IlVzZXI6ICcuJGFycmF5WyduYW1lJ10uJyYjMTMmIzEwUGFzc3dkOiAnLiRhcnJheVsncGFzc3dkJ10uJyYjMTMmIzEwVWlkOiAnLiRhcnJheVsndWlkJ10uJyYjMTMmIzEwZ2lkOiAnLiRhcnJheVsnZ2lkJ10uJyYjMTMmIzEwR2Vjb3M6ICcuJGFycmF5WydnZWNvcyddLicmIzEzJiMxMERpcjogJy4kYXJyYXlbJ2RpciddLicmIzEzJiMxMFNoZWxsOiAnLiRhcnJheVsnc2hlbGwnXS4nIj4nLiRhcnJheVsnbmFtZSddLic8L2E+JzsNCg0KCQl9DQoNCgl9DQoNCglyZXR1cm4gJyc7DQoNCn0NCg0KDQoNCi8vICYjNjM4OyYjMTI5O38mIzEyOTt/JiMzMTk7JiMxODg7DQoNCmZ1bmN0aW9uIGRlbHRyZWUoJGRlbGRpcikgew0KDQoJJG15ZGlyPUBkaXIoJGRlbGRpcik7CQ0KDQoJd2hpbGUoJGZpbGU9JG15ZGlyLT5yZWFkKCkpCXsgCQkNCg0KCQlpZigoaXNfZGlyKCRkZWxkaXIuJy8nLiRmaWxlKSkgJiYgKCRmaWxlIT0nLicpICYmICgkZmlsZSE9Jy4uJykpIHsgDQoNCgkJCUBjaG1vZCgkZGVsZGlyLicvJy4kZmlsZSwwNzc3KTsNCg0KCQkJZGVsdHJlZSgkZGVsZGlyLicvJy4kZmlsZSk7IA0KDQoJCX0NCg0KCQlpZiAoaXNfZmlsZSgkZGVsZGlyLicvJy4kZmlsZSkpIHsNCg0KCQkJQGNobW9kKCRkZWxkaXIuJy8nLiRmaWxlLDA3NzcpOw0KDQoJCQlAdW5saW5rKCRkZWxkaXIuJy8nLiRmaWxlKTsNCg0KCQl9DQoNCgl9IA0KDQoJJG15ZGlyLT5jbG9zZSgpOyANCg0KCUBjaG1vZCgkZGVsZGlyLDA3NzcpOw0KDQoJcmV0dXJuIEBybWRpcigkZGVsZGlyKSA/IDEgOiAwOw0KDQp9DQoNCg0KDQovLyAmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/pyYjMjIyOyYjMTI5O38mIzMwNTsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzYxOTsmIzEyOTt/JiMxNTc7SQ0KDQpmdW5jdGlvbiBiZygpIHsNCg0KCWdsb2JhbCAkYmdjOw0KDQoJcmV0dXJuICgkYmdjKyslMj09MCkgPyAnYWx0MScgOiAnYWx0Mic7DQoNCn0NCg0KDQoNCi8vICYjMTI5O38mIzEyOTt/JiM1NDU7JiMxMjk7fyYjMTI5O38mIzQ5NjsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzMxNjsmIzEyOTt/JiMxMDEzOyYjODgzO6GAJiMxMjk7fyYjMTI5O38NCg0KZnVuY3Rpb24gZ2V0UGF0aCgkc2NyaXB0cGF0aCwgJG5vd3BhdGgpIHsNCg0KCWlmICgkbm93cGF0aCA9PSAnLicpIHsNCg0KCQkkbm93cGF0aCA9ICRzY3JpcHRwYXRoOw0KDQoJfQ0KDQoJJG5vd3BhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRub3dwYXRoKTsNCg0KCSRub3dwYXRoID0gc3RyX3JlcGxhY2UoJy8vJywgJy8nLCAkbm93cGF0aCk7DQoNCglpZiAoc3Vic3RyKCRub3dwYXRoLCAtMSkgIT0gJy8nKSB7DQoNCgkJJG5vd3BhdGggPSAkbm93cGF0aC4nLyc7DQoNCgl9DQoNCglyZXR1cm4gJG5vd3BhdGg7DQoNCn0NCg0KDQoNCi8vICYjMTI5O38mIzEyOTt/JiM1NDU7JiMxMjk7fyYjMTI5O38mIzQ5NjsmIzMxOTsmIzE4ODsmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEwMjA7JiMxMjk7fyYjMzE5OyYjMTg4Ow0KDQpmdW5jdGlvbiBnZXRVcFBhdGgoJG5vd3BhdGgpIHsNCg0KCSRwYXRoZGIgPSBleHBsb2RlKCcvJywgJG5vd3BhdGgpOw0KDQoJJG51bSA9IGNvdW50KCRwYXRoZGIpOw0KDQoJaWYgKCRudW0gPiAyKSB7DQoNCgkJdW5zZXQoJHBhdGhkYlskbnVtLTFdLCRwYXRoZGJbJG51bS0yXSk7DQoNCgl9DQoNCgkkdXBwYXRoID0gaW1wbG9kZSgnLycsICRwYXRoZGIpLicvJzsNCg0KCSR1cHBhdGggPSBzdHJfcmVwbGFjZSgnLy8nLCAnLycsICR1cHBhdGgpOw0KDQoJcmV0dXJuICR1cHBhdGg7DQoNCn0NCg0KDQoNCi8vICYjMTI5O38mIzEyOTt/JiMxMjk7f1BIUCYjMTI5O38mIzEyOTt/JiMxMjk7f5qwJiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCmZ1bmN0aW9uIGdldGNmZygkdmFybmFtZSkgew0KDQoJJHJlc3VsdCA9IGdldF9jZmdfdmFyKCR2YXJuYW1lKTsNCg0KCWlmICgkcmVzdWx0ID09IDApIHsNCg0KCQlyZXR1cm4gJ05vJzsNCg0KCX0gZWxzZWlmICgkcmVzdWx0ID09IDEpIHsNCg0KCQlyZXR1cm4gJ1llcyc7DQoNCgl9IGVsc2Ugew0KDQoJCXJldHVybiAkcmVzdWx0Ow0KDQoJfQ0KDQp9DQoNCg0KDQovLyAmIzEyOTt/JiMxMjk7f/xEJiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38NCg0KZnVuY3Rpb24gZ2V0ZnVuKCRmdW5OYW1lKSB7DQoNCglyZXR1cm4gKGZhbHNlICE9PSBmdW5jdGlvbl9leGlzdHMoJGZ1bk5hbWUpKSA/ICdZZXMnIDogJ05vJzsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZ2V0ZXh0ZW5zaW9uKCRmaWxlbmFtZSkgew0KDQoJJHBhdGhpbmZvID0gcGF0aGluZm8oJGZpbGVuYW1lKTsNCg0KCXJldHVybiAkcGF0aGluZm9bJ2V4dGVuc2lvbiddOw0KDQp9DQoNCg0KDQpmdW5jdGlvbiBHZXRXRGlyTGlzdCgkZGlyKXsNCg0KCWdsb2JhbCAkZGlyZGF0YSwkaiwkbm93cGF0aDsNCg0KCSEkaiAmJiAkaj0xOw0KDQoJaWYgKCRkaCA9IG9wZW5kaXIoJGRpcikpIHsNCg0KCQl3aGlsZSAoJGZpbGUgPSByZWFkZGlyKCRkaCkpIHsNCg0KCQkJJGY9c3RyX3JlcGxhY2UoJy8vJywnLycsJGRpci4nLycuJGZpbGUpOw0KDQoJCQlpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nICYmIGlzX2RpcigkZikpew0KDQoJCQkJaWYgKGlzX3dyaXRhYmxlKCRmKSkgew0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnZmlsZW5hbWUnXT1zdHJfcmVwbGFjZSgkbm93cGF0aCwnJywkZik7DQoNCgkJCQkJJGRpcmRhdGFbJGpdWydtdGltZSddPUBkYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRmKSk7DQoNCgkJCQkJJGRpcmRhdGFbJGpdWydkaXJjaG1vZCddPWdldENobW9kKCRmKTsNCg0KCQkJCQkkZGlyZGF0YVskal1bJ2RpcnBlcm0nXT1nZXRQZXJtcygkZik7DQoNCgkJCQkJJGRpcmRhdGFbJGpdWydkaXJsaW5rJ109dWUoJGRpcik7DQoNCgkJCQkJJGRpcmRhdGFbJGpdWydzZXJ2ZXJfbGluayddPSRmOw0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnY2xpZW50X2xpbmsnXT11ZSgkZik7DQoNCgkJCQkJJGorKzsNCg0KCQkJCX0NCg0KCQkJCUdldFdEaXJMaXN0KCRmKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCQljbG9zZWRpcigkZGgpOw0KDQoJCWNsZWFyc3RhdGNhY2hlKCk7DQoNCgkJcmV0dXJuICRkaXJkYXRhOw0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gYXJyYXkoKTsNCg0KCX0NCg0KfQ0KDQoNCg0KZnVuY3Rpb24gR2V0V0ZpbGVMaXN0KCRkaXIpew0KDQoJZ2xvYmFsICRmaWxlZGF0YSwkaiwkbm93cGF0aCwgJHdyaXRhYmxlZGI7DQoNCgkhJGogJiYgJGo9MTsNCg0KCWlmICgkZGggPSBvcGVuZGlyKCRkaXIpKSB7DQoNCgkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7DQoNCgkJCSRleHQgPSBnZXRleHRlbnNpb24oJGZpbGUpOw0KDQoJCQkkZj1zdHJfcmVwbGFjZSgnLy8nLCcvJywkZGlyLicvJy4kZmlsZSk7DQoNCgkJCWlmKCRmaWxlIT0nLicgJiYgJGZpbGUhPScuLicgJiYgaXNfZGlyKCRmKSl7DQoNCgkJCQlHZXRXRmlsZUxpc3QoJGYpOw0KDQoJCQl9IGVsc2VpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nICYmIGlzX2ZpbGUoJGYpICYmIGluX2FycmF5KCRleHQsIGV4cGxvZGUoJywnLCAkd3JpdGFibGVkYikpKXsNCg0KCQkJCWlmIChpc193cml0YWJsZSgkZikpIHsNCg0KCQkJCQkkZmlsZWRhdGFbJGpdWydmaWxlbmFtZSddPXN0cl9yZXBsYWNlKCRub3dwYXRoLCcnLCRmKTsNCg0KCQkJCQkkZmlsZWRhdGFbJGpdWydzaXplJ109c2l6ZWNvdW50KEBmaWxlc2l6ZSgkZikpOw0KDQoJCQkJCSRmaWxlZGF0YVskal1bJ210aW1lJ109QGRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJGYpKTsNCg0KCQkJCQkkZmlsZWRhdGFbJGpdWydmaWxlY2htb2QnXT1nZXRDaG1vZCgkZik7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZXBlcm0nXT1nZXRQZXJtcygkZik7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZW93bmVyJ109Z2V0VXNlcigkZik7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnZGlybGluayddPSRkaXI7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnc2VydmVyX2xpbmsnXT0kZjsNCg0KCQkJCQkkZmlsZWRhdGFbJGpdWydjbGllbnRfbGluayddPXVlKCRmKTsNCg0KCQkJCQkkaisrOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJfQ0KDQoJCWNsb3NlZGlyKCRkaCk7DQoNCgkJY2xlYXJzdGF0Y2FjaGUoKTsNCg0KCQlyZXR1cm4gJGZpbGVkYXRhOw0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gYXJyYXkoKTsNCg0KCX0NCg0KfQ0KDQoNCg0KZnVuY3Rpb24gR2V0U0ZpbGVMaXN0KCRkaXIsICRjb250ZW50LCAkcmUgPSAwKSB7DQoNCglnbG9iYWwgJGZpbGVkYXRhLCRqLCRub3dwYXRoLCAkd3JpdGFibGVkYjsNCg0KCSEkaiAmJiAkaj0xOw0KDQoJaWYgKCRkaCA9IG9wZW5kaXIoJGRpcikpIHsNCg0KCQl3aGlsZSAoJGZpbGUgPSByZWFkZGlyKCRkaCkpIHsNCg0KCQkJJGV4dCA9IGdldGV4dGVuc2lvbigkZmlsZSk7DQoNCgkJCSRmPXN0cl9yZXBsYWNlKCcvLycsJy8nLCRkaXIuJy8nLiRmaWxlKTsNCg0KCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19kaXIoJGYpKXsNCg0KCQkJCUdldFNGaWxlTGlzdCgkZiwgJGNvbnRlbnQsICRyZSA9IDApOw0KDQoJCQl9IGVsc2VpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nICYmIGlzX2ZpbGUoJGYpICYmIGluX2FycmF5KCRleHQsIGV4cGxvZGUoJywnLCAkd3JpdGFibGVkYikpKXsNCg0KCQkJCSRmaW5kID0gMDsNCg0KCQkJCWlmICgkcmUpIHsNCg0KCQkJCQlpZiAoIHByZWdfbWF0Y2goJ0AnLiRjb250ZW50LidAJywkZmlsZSkgfHwgcHJlZ19tYXRjaCgnQCcuJGNvbnRlbnQuJ0AnLCBAZmlsZV9nZXRfY29udGVudHMoJGYpKSApew0KDQoJCQkJCQkkZmluZCA9IDE7DQoNCgkJCQkJfQ0KDQoJCQkJfSBlbHNlIHsNCg0KCQkJCQlpZiAoIHN0cnN0cigkZmlsZSwgJGNvbnRlbnQpIHx8IHN0cnN0ciggQGZpbGVfZ2V0X2NvbnRlbnRzKCRmKSwkY29udGVudCApICkgew0KDQoJCQkJCQkkZmluZCA9IDE7DQoNCgkJCQkJfQ0KDQoJCQkJfQ0KDQoJCQkJaWYgKCRmaW5kKSB7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZW5hbWUnXT1zdHJfcmVwbGFjZSgkbm93cGF0aCwnJywkZik7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnc2l6ZSddPXNpemVjb3VudChAZmlsZXNpemUoJGYpKTsNCg0KCQkJCQkkZmlsZWRhdGFbJGpdWydtdGltZSddPUBkYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRmKSk7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZWNobW9kJ109Z2V0Q2htb2QoJGYpOw0KDQoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVwZXJtJ109Z2V0UGVybXMoJGYpOw0KDQoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVvd25lciddPWdldFVzZXIoJGYpOw0KDQoJCQkJCSRmaWxlZGF0YVskal1bJ2RpcmxpbmsnXT0kZGlyOw0KDQoJCQkJCSRmaWxlZGF0YVskal1bJ3NlcnZlcl9saW5rJ109JGY7DQoNCgkJCQkJJGZpbGVkYXRhWyRqXVsnY2xpZW50X2xpbmsnXT11ZSgkZik7DQoNCgkJCQkJJGorKzsNCg0KCQkJCX0NCg0KCQkJfQ0KDQoJCX0NCg0KCQljbG9zZWRpcigkZGgpOw0KDQoJCWNsZWFyc3RhdGNhY2hlKCk7DQoNCgkJcmV0dXJuICRmaWxlZGF0YTsNCg0KCX0gZWxzZSB7DQoNCgkJcmV0dXJuIGFycmF5KCk7DQoNCgl9DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIHF5KCRzcWwpIHsgDQoNCgkvL2VjaG8gJHNxbC4nPGJyPic7DQoNCgkkcmVzID0gJGVycm9yID0gJyc7DQoNCglpZighJHJlcyA9IEBteXNxbF9xdWVyeSgkc3FsKSkgeyANCg0KCQlyZXR1cm4gMDsNCg0KCX0gZWxzZSBpZihpc19yZXNvdXJjZSgkcmVzKSkgew0KDQoJCXJldHVybiAxOyANCg0KCX0gZWxzZSB7DQoNCgkJcmV0dXJuIDI7DQoNCgl9CQ0KDQoJcmV0dXJuIDA7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIHEoJHNxbCkgeyANCg0KCXJldHVybiBAbXlzcWxfcXVlcnkoJHNxbCk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIGZyKCRxeSl7DQoNCglteXNxbF9mcmVlX3Jlc3VsdCgkcXkpOw0KDQp9DQoNCg0KDQovL21zc3FsDQoNCmZ1bmN0aW9uIG1zcSgkc3FsKSB7IA0KDQoJcmV0dXJuIEBtc3NxbF9xdWVyeSgkc3FsKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gbXNmcigkcXkpew0KDQoJbXNzcWxfZnJlZV9yZXN1bHQoJHF5KTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gbXNtc2coKXsNCg0KCXJldHVybiBtc3NxbF9nZXRfbGFzdF9tZXNzYWdlKCk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIG1zcXkoJHNxbCkgeyANCg0KCS8vZWNobyAkc3FsLic8YnI+JzsNCg0KCSRyZXMgPSAkZXJyb3IgPSAnJzsNCg0KCWlmKCEkcmVzID0gQG1zc3FsX3F1ZXJ5KCRzcWwpKSB7IA0KDQoJCXJldHVybiAwOw0KDQoJfSBlbHNlIGlmKGlzX3Jlc291cmNlKCRyZXMpKSB7DQoNCgkJcmV0dXJuIDE7IA0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gMjsNCg0KCX0JDQoNCglyZXR1cm4gMDsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gc2l6ZWNvdW50KCRzaXplKSB7DQoNCglpZigkc2l6ZSA+IDEwNzM3NDE4MjQpIHsNCg0KCQkkc2l6ZSA9IHJvdW5kKCRzaXplIC8gMTA3Mzc0MTgyNCAqIDEwMCkgLyAxMDAgLiAnIEcnOw0KDQoJfSBlbHNlaWYoJHNpemUgPiAxMDQ4NTc2KSB7DQoNCgkJJHNpemUgPSByb3VuZCgkc2l6ZSAvIDEwNDg1NzYgKiAxMDApIC8gMTAwIC4gJyBNJzsNCg0KCX0gZWxzZWlmKCRzaXplID4gMTAyNCkgew0KDQoJCSRzaXplID0gcm91bmQoJHNpemUgLyAxMDI0ICogMTAwKSAvIDEwMCAuICcgSyc7DQoNCgl9IGVsc2Ugew0KDQoJCSRzaXplID0gJHNpemUgLiAnIEInOw0KDQoJfQ0KDQoJcmV0dXJuICRzaXplOw0KDQp9DQoNCg0KDQovLyAmIzExNDU7JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/DQoNCmNsYXNzIFBIUFppcHsNCg0KCXZhciAkb3V0PScnOw0KDQoJZnVuY3Rpb24gUEhQWmlwKCRkaXIpCXsNCg0KCQlpZiAoQGZ1bmN0aW9uX2V4aXN0cygnZ3pjb21wcmVzcycpKQl7DQoNCgkJCSRjdXJkaXIgPSBnZXRjd2QoKTsNCg0KCQkJaWYgKGlzX2FycmF5KCRkaXIpKSAkZmlsZWxpc3QgPSAkZGlyOw0KDQoJCQllbHNlew0KDQoJCQkJJGZpbGVsaXN0PSR0aGlzIC0+IEdldEZpbGVMaXN0KCRkaXIpOy8vJiMxMjk7fyYjMzE2OyYjMTI5O38mIzEyOTt/p9ImIzEyOTt/DQoNCgkJCQlmb3JlYWNoKCRmaWxlbGlzdCBhcyAkaz0+JHYpICRmaWxlbGlzdFtdPXN1YnN0cigkdixzdHJsZW4oJGRpcikrMSk7DQoNCgkJCX0NCg0KCQkJaWYgKCghZW1wdHkoJGRpcikpJiYoIWlzX2FycmF5KCRkaXIpKSYmKGZpbGVfZXhpc3RzKCRkaXIpKSkgY2hkaXIoJGRpcik7DQoNCgkJCWVsc2UgY2hkaXIoJGN1cmRpcik7DQoNCgkJCWlmIChjb3VudCgkZmlsZWxpc3QpPjApew0KDQoJCQkJZm9yZWFjaCgkZmlsZWxpc3QgYXMgJGZpbGVuYW1lKXsNCg0KCQkJCQlpZiAoaXNfZmlsZSgkZmlsZW5hbWUpKXsNCg0KCQkJCQkJJGZkID0gZm9wZW4gKCRmaWxlbmFtZSwgJ3InKTsNCg0KCQkJCQkJJGNvbnRlbnQgPSBAZnJlYWQgKCRmZCwgZmlsZXNpemUoJGZpbGVuYW1lKSk7DQoNCgkJCQkJCWZjbG9zZSAoJGZkKTsNCg0KCQkJCQkJaWYgKGlzX2FycmF5KCRkaXIpKSAkZmlsZW5hbWUgPSBiYXNlbmFtZSgkZmlsZW5hbWUpOw0KDQoJCQkJCQkkdGhpcyAtPiBhZGRGaWxlKCRjb250ZW50LCAkZmlsZW5hbWUpOw0KDQoJCQkJCX0NCg0KCQkJCX0NCg0KCQkJCSR0aGlzLT5vdXQgPSAkdGhpcyAtPiBmaWxlKCk7DQoNCgkJCQljaGRpcigkY3VyZGlyKTsNCg0KCQkJfQ0KDQoJCQlyZXR1cm4gMTsNCg0KCQl9DQoNCgkJZWxzZSByZXR1cm4gMDsNCg0KCX0NCg0KDQpmdW5jdGlvbiBHZXRGaWxlTGlzdCgkZGlyKXsNCg0KCQlzdGF0aWMgJGE7DQoNCgkJaWYgKGlzX2RpcigkZGlyKSkgew0KDQoJCQlpZiAoJGRoID0gb3BlbmRpcigkZGlyKSkgew0KDQoJCQkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7DQoNCgkJCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyl7DQoNCgkJCQkJCSRmPSRkaXIgLicvJy4gJGZpbGU7DQoNCgkJCQkJCWlmKGlzX2RpcigkZikpICR0aGlzLT5HZXRGaWxlTGlzdCgkZik7DQoNCgkJCQkJCSRhW109JGY7DQoNCgkJCQkJfQ0KDQoJCQkJfQ0KDQoJCQkJY2xvc2VkaXIoJGRoKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCQlyZXR1cm4gJGE7DQoNCgl9DQoNCg0KDQoJdmFyICRkYXRhc2VjICAgICAgPSBhcnJheSgpOw0KDQoJdmFyICRjdHJsX2RpciAgICAgPSBhcnJheSgpOw0KDQoJdmFyICRlb2ZfY3RybF9kaXIgPSAiXHg1MFx4NGJceDA1XHgwNlx4MDBceDAwXHgwMFx4MDAiOw0KDQoJdmFyICRvbGRfb2Zmc2V0ICAgPSAwOw0KDQoNCg0KCWZ1bmN0aW9uIHVuaXgyRG9zVGltZSgkdW5peHRpbWUgPSAwKSB7DQoNCgkJJHRpbWVhcnJheSA9ICgkdW5peHRpbWUgPT0gMCkgPyBnZXRkYXRlKCkgOiBnZXRkYXRlKCR1bml4dGltZSk7DQoNCgkJaWYgKCR0aW1lYXJyYXlbJ3llYXInXSA8IDE5ODApIHsNCg0KCQkJJHRpbWVhcnJheVsneWVhciddICAgID0gMTk4MDsNCg0KCQkJJHRpbWVhcnJheVsnbW9uJ10gICAgID0gMTsNCg0KCQkJJHRpbWVhcnJheVsnbWRheSddICAgID0gMTsNCg0KCQkJJHRpbWVhcnJheVsnaG91cnMnXSAgID0gMDsNCg0KCQkJJHRpbWVhcnJheVsnbWludXRlcyddID0gMDsNCg0KCQkJJHRpbWVhcnJheVsnc2Vjb25kcyddID0gMDsNCg0KCQl9IC8vIGVuZCBpZg0KDQoJCXJldHVybiAoKCR0aW1lYXJyYXlbJ3llYXInXSAtIDE5ODApIDw8IDI1KSB8ICgkdGltZWFycmF5Wydtb24nXSA8PCAyMSkgfCAoJHRpbWVhcnJheVsnbWRheSddIDw8IDE2KSB8DQoNCgkJCQkoJHRpbWVhcnJheVsnaG91cnMnXSA8PCAxMSkgfCAoJHRpbWVhcnJheVsnbWludXRlcyddIDw8IDUpIHwgKCR0aW1lYXJyYXlbJ3NlY29uZHMnXSA+PiAxKTsNCg0KCX0NCg0KDQoNCglmdW5jdGlvbiBhZGRGaWxlKCRkYXRhLCAkbmFtZSwgJHRpbWUgPSAwKSB7DQoNCgkJJG5hbWUgPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRuYW1lKTsNCg0KDQoNCgkJJGR0aW1lID0gZGVjaGV4KCR0aGlzLT51bml4MkRvc1RpbWUoJHRpbWUpKTsNCg0KCQkkaGV4ZHRpbWUJPSAnXHgnIC4gJGR0aW1lWzZdIC4gJGR0aW1lWzddDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzRdIC4gJGR0aW1lWzVdDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzJdIC4gJGR0aW1lWzNdDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzBdIC4gJGR0aW1lWzFdOw0KDQoJCWV2YWwoJyRoZXhkdGltZSA9ICInIC4gJGhleGR0aW1lIC4gJyI7Jyk7DQoNCgkJJGZyCT0gIlx4NTBceDRiXHgwM1x4MDQiOw0KDQoJCSRmcgkuPSAiXHgxNFx4MDAiOw0KDQoJCSRmcgkuPSAiXHgwMFx4MDAiOw0KDQoJCSRmcgkuPSAiXHgwOFx4MDAiOw0KDQoJCSRmcgkuPSAkaGV4ZHRpbWU7DQoNCg0KDQoJCSR1bmNfbGVuID0gc3RybGVuKCRkYXRhKTsNCg0KCQkkY3JjID0gY3JjMzIoJGRhdGEpOw0KDQoJCSR6ZGF0YSA9IGd6Y29tcHJlc3MoJGRhdGEpOw0KDQoJCSRjX2xlbiA9IHN0cmxlbigkemRhdGEpOw0KDQoJCSR6ZGF0YSA9IHN1YnN0cihzdWJzdHIoJHpkYXRhLCAwLCBzdHJsZW4oJHpkYXRhKSAtIDQpLCAyKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICRjcmMpOw0KDQoJCSRmciAuPSBwYWNrKCdWJywgJGNfbGVuKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCQkkZnIgLj0gcGFjaygndicsIHN0cmxlbigkbmFtZSkpOw0KDQoJCSRmciAuPSBwYWNrKCd2JywgMCk7DQoNCgkJJGZyIC49ICRuYW1lOw0KDQoJCSRmciAuPSAkemRhdGE7DQoNCgkJJGZyIC49IHBhY2soJ1YnLCAkY3JjKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICRjX2xlbik7DQoNCgkJJGZyIC49IHBhY2soJ1YnLCAkdW5jX2xlbik7DQoNCg0KDQoJCSR0aGlzIC0+IGRhdGFzZWNbXSA9ICRmcjsNCg0KCQkkbmV3X29mZnNldCA9IHN0cmxlbihpbXBsb2RlKCcnLCAkdGhpcy0+ZGF0YXNlYykpOw0KDQoNCg0KCQkkY2RyZWMgPSAiXHg1MFx4NGJceDAxXHgwMiI7DQoNCgkJJGNkcmVjIC49ICJceDAwXHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDE0XHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDAwXHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDA4XHgwMCI7DQoNCgkJJGNkcmVjIC49ICRoZXhkdGltZTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsICRjcmMpOw0KDQoJCSRjZHJlYyAuPSBwYWNrKCdWJywgJGNfbGVuKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIHN0cmxlbigkbmFtZSkgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsIDMyICk7DQoNCgkJJGNkcmVjIC49IHBhY2soJ1YnLCAkdGhpcyAtPiBvbGRfb2Zmc2V0ICk7DQoNCgkJJHRoaXMgLT4gb2xkX29mZnNldCA9ICRuZXdfb2Zmc2V0Ow0KDQoJCSRjZHJlYyAuPSAkbmFtZTsNCg0KDQoNCgkJJHRoaXMgLT4gY3RybF9kaXJbXSA9ICRjZHJlYzsNCg0KCX0NCg0KDQoNCglmdW5jdGlvbiBmaWxlKCkgew0KDQoJCSRkYXRhICAgID0gaW1wbG9kZSgnJywgJHRoaXMgLT4gZGF0YXNlYyk7DQoNCgkJJGN0cmxkaXIgPSBpbXBsb2RlKCcnLCAkdGhpcyAtPiBjdHJsX2Rpcik7DQoNCgkJcmV0dXJuICRkYXRhIC4gJGN0cmxkaXIgLiAkdGhpcyAtPiBlb2ZfY3RybF9kaXIgLiBwYWNrKCd2Jywgc2l6ZW9mKCR0aGlzIC0+IGN0cmxfZGlyKSkgLiBwYWNrKCd2Jywgc2l6ZW9mKCR0aGlzIC0+IGN0cmxfZGlyKSkgLglwYWNrKCdWJywgc3RybGVuKCRjdHJsZGlyKSkgLiBwYWNrKCdWJywgc3RybGVuKCRkYXRhKSkgLiAiXHgwMFx4MDAiOw0KDQoJfQ0KDQp9DQoNCg0KDQovLyAmIzEyOTt/JiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMjk7fyYjMTI5O38mIzE5MTk7JiMxMjk7fw0KDQpmdW5jdGlvbiBzcWxkdW1wdGFibGUoJHRhYmxlLCAkZnA9MCkgew0KDQoJJHRhYmxlZHVtcCA9ICJEUk9QIFRBQkxFIElGIEVYSVNUUyAkdGFibGU7XG4iOw0KDQoJJHRhYmxlZHVtcCAuPSAiQ1JFQVRFIFRBQkxFICR0YWJsZSAoXG4iOw0KDQoNCg0KCSRmaXJzdGZpZWxkPTE7DQoNCg0KDQoJJGZpZWxkcyA9IHEoIlNIT1cgRklFTERTIEZST00gJHRhYmxlIik7DQoNCgl3aGlsZSAoJGZpZWxkID0gbXlzcWxfZmV0Y2hfYXJyYXkoJGZpZWxkcykpIHsNCg0KCQlpZiAoISRmaXJzdGZpZWxkKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIixcbiI7DQoNCgkJfSBlbHNlIHsNCg0KCQkJJGZpcnN0ZmllbGQ9MDsNCg0KCQl9DQoNCgkJJHRhYmxlZHVtcCAuPSAiICAgJGZpZWxkW0ZpZWxkXSAkZmllbGRbVHlwZV0iOw0KDQoJCWlmICghZW1wdHkoJGZpZWxkWyJEZWZhdWx0Il0pKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiBERUZBVUxUICckZmllbGRbRGVmYXVsdF0nIjsNCg0KCQl9DQoNCgkJaWYgKCRmaWVsZFsnTnVsbCddICE9ICJZRVMiKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiBOT1QgTlVMTCI7DQoNCgkJfQ0KDQoJCWlmICgkZmllbGRbJ0V4dHJhJ10gIT0gIiIpIHsNCg0KCQkJJHRhYmxlZHVtcCAuPSAiICRmaWVsZFtFeHRyYV0iOw0KDQoJCX0NCg0KCX0NCg0KCWZyKCRmaWVsZHMpOw0KDQoNCg0KCSRrZXlzID0gcSgiU0hPVyBLRVlTIEZST00gJHRhYmxlIik7DQoNCgl3aGlsZSAoJGtleSA9IG15c3FsX2ZldGNoX2FycmF5KCRrZXlzKSkgew0KDQoJCSRrbmFtZT0ka2V5WydLZXlfbmFtZSddOw0KDQoJCWlmICgka25hbWUgIT0gIlBSSU1BUlkiICYmICRrZXlbJ05vbl91bmlxdWUnXSA9PSAwKSB7DQoNCgkJCSRrbmFtZT0iVU5JUVVFfCRrbmFtZSI7DQoNCgkJfQ0KDQoJCWlmKCFpc19hcnJheSgkaW5kZXhbJGtuYW1lXSkpIHsNCg0KCQkJJGluZGV4WyRrbmFtZV0gPSBhcnJheSgpOw0KDQoJCX0NCg0KCQkkaW5kZXhbJGtuYW1lXVtdID0gJGtleVsnQ29sdW1uX25hbWUnXTsNCg0KCX0NCg0KCWZyKCRrZXlzKTsNCg0KDQoNCgl3aGlsZShsaXN0KCRrbmFtZSwgJGNvbHVtbnMpID0gQGVhY2goJGluZGV4KSkgew0KDQoJCSR0YWJsZWR1bXAgLj0gIixcbiI7DQoNCgkJJGNvbG5hbWVzPWltcGxvZGUoJGNvbHVtbnMsIiwiKTsNCg0KDQoNCgkJaWYgKCRrbmFtZSA9PSAiUFJJTUFSWSIpIHsNCg0KCQkJJHRhYmxlZHVtcCAuPSAiICAgUFJJTUFSWSBLRVkgKCRjb2xuYW1lcykiOw0KDQoJCX0gZWxzZSB7DQoNCgkJCWlmIChzdWJzdHIoJGtuYW1lLDAsNikgPT0gIlVOSVFVRSIpIHsNCg0KCQkJCSRrbmFtZT1zdWJzdHIoJGtuYW1lLDcpOw0KDQoJCQl9DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiAgIEtFWSAka25hbWUgKCRjb2xuYW1lcykiOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgkkdGFibGVkdW1wIC49ICJcbik7XG5cbiI7DQoNCglpZiAoJGZwKSB7DQoNCgkJZndyaXRlKCRmcCwkdGFibGVkdW1wKTsNCg0KCX0gZWxzZSB7DQoNCgkJZWNobyAkdGFibGVkdW1wOw0KDQoJfQ0KDQoNCg0KCSRyb3dzID0gcSgiU0VMRUNUICogRlJPTSAkdGFibGUiKTsNCg0KCSRudW1maWVsZHMgPSBteXNxbF9udW1fZmllbGRzKCRyb3dzKTsNCg0KCXdoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJvd3MpKSB7DQoNCgkJJHRhYmxlZHVtcCA9ICJJTlNFUlQgSU5UTyAkdGFibGUgVkFMVUVTKCI7DQoNCg0KDQoJCSRmaWVsZGNvdW50ZXI9LTE7DQoNCgkJJGZpcnN0ZmllbGQ9MTsNCg0KCQl3aGlsZSAoKyskZmllbGRjb3VudGVyPCRudW1maWVsZHMpIHsNCg0KCQkJaWYgKCEkZmlyc3RmaWVsZCkgew0KDQoJCQkJJHRhYmxlZHVtcC49IiwgIjsNCg0KCQkJfSBlbHNlIHsNCg0KCQkJCSRmaXJzdGZpZWxkPTA7DQoNCgkJCX0NCg0KDQoNCgkJCWlmICghaXNzZXQoJHJvd1skZmllbGRjb3VudGVyXSkpIHsNCg0KCQkJCSR0YWJsZWR1bXAgLj0gIk5VTEwiOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJHRhYmxlZHVtcCAuPSAiJyIubXlzcWxfZXNjYXBlX3N0cmluZygkcm93WyRmaWVsZGNvdW50ZXJdKS4iJyI7DQoNCgkJCX0NCg0KCQl9DQoNCg0KDQoJCSR0YWJsZWR1bXAgLj0gIik7XG4iOw0KDQoNCg0KCQlpZiAoJGZwKSB7DQoNCgkJCWZ3cml0ZSgkZnAsJHRhYmxlZHVtcCk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJZWNobyAkdGFibGVkdW1wOw0KDQoJCX0NCg0KCX0NCg0KCWZyKCRyb3dzKTsNCg0KCWlmICgkZnApIHsNCg0KCQlmd3JpdGUoJGZwLCJcbiIpOw0KDQoJfSBlbHNlIHsNCg0KCQllY2hvICJcbiI7DQoNCgl9DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIHVlKCRzdHIpew0KDQoJcmV0dXJuIHVybGVuY29kZSgkc3RyKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gcCgkc3RyKXsNCg0KCWVjaG8gJHN0ci4iXG4iOw0KDQp9DQoNCg0KDQpmdW5jdGlvbiB0YmhlYWQoKSB7DQoNCglwKCc8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjQiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KfQ0KDQpmdW5jdGlvbiB0YmZvb3QoKXsNCg0KCXAoJzwvdGFibGU+Jyk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIG1ha2VoaWRlKCRuYW1lLCR2YWx1ZT0nJyl7DQoNCglwKCI8aW5wdXQgaWQ9XCIkbmFtZVwiIHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwiJG5hbWVcIiB2YWx1ZT1cIiR2YWx1ZVwiIC8+Iik7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIG1ha2VpbnB1dCgkYXJnID0gYXJyYXkoKSl7DQoNCgkkYXJnWydzaXplJ10gPSAkYXJnWydzaXplJ10gPiAwID8gInNpemU9XCIkYXJnW3NpemVdXCIiIDogInNpemU9XCIxMDBcIiI7DQoNCgkkYXJnWydleHRyYSddID0gJGFyZ1snZXh0cmEnXSA/ICRhcmdbJ2V4dHJhJ10gOiAnJzsNCg0KCSEkYXJnWyd0eXBlJ10gJiYgJGFyZ1sndHlwZSddID0gJ3RleHQnOw0KDQoJJGFyZ1sndGl0bGUnXSA9ICRhcmdbJ3RpdGxlJ10gPyAkYXJnWyd0aXRsZSddLic8YnIgLz4nIDogJyc7DQoNCgkkYXJnWydjbGFzcyddID0gJGFyZ1snY2xhc3MnXSA/ICRhcmdbJ2NsYXNzJ10gOiAnaW5wdXQnOw0KDQoJaWYgKCRhcmdbJ25ld2xpbmUnXSkgew0KDQoJCXAoIjxwPiRhcmdbdGl0bGVdPGlucHV0IGNsYXNzPVwiJGFyZ1tjbGFzc11cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIHZhbHVlPVwiJGFyZ1t2YWx1ZV1cIiB0eXBlPVwiJGFyZ1t0eXBlXVwiICRhcmdbc2l6ZV0gJGFyZ1tleHRyYV0gLz48L3A+Iik7DQoNCgl9IGVsc2Ugew0KDQoJCXAoIiRhcmdbdGl0bGVdPGlucHV0IGNsYXNzPVwiJGFyZ1tjbGFzc11cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIHZhbHVlPVwiJGFyZ1t2YWx1ZV1cIiB0eXBlPVwiJGFyZ1t0eXBlXVwiICRhcmdbc2l6ZV0gJGFyZ1tleHRyYV0gLz4iKTsNCg0KCX0NCg0KfQ0KDQoNCg0KZnVuY3Rpb24gbWFrZXNlbGVjdCgkYXJnID0gYXJyYXkoKSl7DQoNCglpZiAoJGFyZ1snb25jaGFuZ2UnXSkgew0KDQoJCSRvbmNoYW5nZSA9ICdvbmNoYW5nZT0iJy4kYXJnWydvbmNoYW5nZSddLiciJzsNCg0KCX0NCg0KCSRhcmdbJ3RpdGxlJ10gPSAkYXJnWyd0aXRsZSddID8gJGFyZ1sndGl0bGUnXSA6ICcnOw0KDQoJaWYgKCRhcmdbJ25ld2xpbmUnXSkgcCgnPHA+Jyk7DQoNCglwKCIkYXJnW3RpdGxlXSA8c2VsZWN0IGNsYXNzPVwiaW5wdXRcIiBpZD1cIiRhcmdbbmFtZV1cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiICRvbmNoYW5nZT4iKTsNCg0KCQlpZiAoaXNfYXJyYXkoJGFyZ1snb3B0aW9uJ10pKSB7DQoNCgkJCWlmICgkYXJnWydub2tleSddKSB7DQoNCgkJCQlmb3JlYWNoICgkYXJnWydvcHRpb24nXSBhcyAkdmFsdWUpIHsNCg0KCQkJCQlpZiAoJGFyZ1snc2VsZWN0ZWQnXT09JHZhbHVlKSB7DQoNCgkJCQkJCXAoIjxvcHRpb24gdmFsdWU9XCIkdmFsdWVcIiBzZWxlY3RlZD4kdmFsdWU8L29wdGlvbj4iKTsNCg0KCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJHZhbHVlXCI+JHZhbHVlPC9vcHRpb24+Iik7DQoNCgkJCQkJfQ0KDQoJCQkJfQ0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJZm9yZWFjaCAoJGFyZ1snb3B0aW9uJ10gYXMgJGtleT0+JHZhbHVlKSB7DQoNCgkJCQkJaWYgKCRhcmdbJ3NlbGVjdGVkJ109PSRrZXkpIHsNCg0KCQkJCQkJcCgiPG9wdGlvbiB2YWx1ZT1cIiRrZXlcIiBzZWxlY3RlZD4kdmFsdWU8L29wdGlvbj4iKTsNCg0KCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJGtleVwiPiR2YWx1ZTwvb3B0aW9uPiIpOw0KDQoJCQkJCX0NCg0KCQkJCX0NCg0KCQkJfQ0KDQoJCX0NCg0KCXAoIjwvc2VsZWN0PiIpOw0KDQoJaWYgKCRhcmdbJ25ld2xpbmUnXSkgcCgnPC9wPicpOw0KDQp9DQoNCmZ1bmN0aW9uIGZvcm1oZWFkKCRhcmcgPSBhcnJheSgpKSB7DQoNCglnbG9iYWwgJHNlbGY7DQoNCgkhJGFyZ1snbWV0aG9kJ10gJiYgJGFyZ1snbWV0aG9kJ10gPSAncG9zdCc7DQoNCgkhJGFyZ1snYWN0aW9uJ10gJiYgJGFyZ1snYWN0aW9uJ10gPSAkc2VsZjsNCg0KCSRhcmdbJ3RhcmdldCddID0gJGFyZ1sndGFyZ2V0J10gPyAidGFyZ2V0PVwiJGFyZ1t0YXJnZXRdXCIiIDogJyc7DQoNCgkhJGFyZ1snbmFtZSddICYmICRhcmdbJ25hbWUnXSA9ICdmb3JtMSc7DQoNCglwKCI8Zm9ybSBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIGFjdGlvbj1cIiRhcmdbYWN0aW9uXVwiIG1ldGhvZD1cIiRhcmdbbWV0aG9kXVwiICRhcmdbdGFyZ2V0XT4iKTsNCg0KCWlmICgkYXJnWyd0aXRsZSddKSB7DQoNCgkJcCgnPGgyPicuJGFyZ1sndGl0bGUnXS4nICZyYXF1bzs8L2gyPicpOw0KDQoJfQ0KDQp9DQoNCgkNCg0KZnVuY3Rpb24gbWFrZXRleHQoJGFyZyA9IGFycmF5KCkpew0KDQoJISRhcmdbJ2NvbHMnXSAmJiAkYXJnWydjb2xzJ10gPSAxMDA7DQoNCgkhJGFyZ1sncm93cyddICYmICRhcmdbJ3Jvd3MnXSA9IDI1Ow0KDQoJJGFyZ1sndGl0bGUnXSA9ICRhcmdbJ3RpdGxlJ10gPyAkYXJnWyd0aXRsZSddLic8YnIgLz4nIDogJyc7DQoNCglwKCI8cD4kYXJnW3RpdGxlXTx0ZXh0YXJlYSBjbGFzcz1cImFyZWFcIiBpZD1cIiRhcmdbbmFtZV1cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGNvbHM9XCIkYXJnW2NvbHNdXCIgcm93cz1cIiRhcmdbcm93c11cIiAkYXJnW2V4dHJhXT4kYXJnW3ZhbHVlXTwvdGV4dGFyZWE+PC9wPiIpOw0KDQp9DQoNCg0KDQpmdW5jdGlvbiBmb3JtZm9vdGVyKCRuYW1lID0gJycpew0KDQoJISRuYW1lICYmICRuYW1lID0gJ3N1Ym1pdCc7DQoNCglwKCc8cD48aW5wdXQgY2xhc3M9ImJ0IiBuYW1lPSInLiRuYW1lLiciIGlkPSInLiRuYW1lLiciIHR5cGU9InN1Ym1pdCIgdmFsdWU9IkVudmlhciI+PC9wPicpOw0KDQoJcCgnPC9mb3JtPicpOw0KDQp9DQoNCg0KDQpmdW5jdGlvbiBnb2JhY2soKXsNCg0KCWdsb2JhbCAkc2VsZiwgJG5vd3BhdGg7DQoNCglwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJwb3N0Ij48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJhY3Rpb24iIHZhbHVlPSJmaWxlIiAvPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImRpciIgdmFsdWU9IicuJG5vd3BhdGguJyIgLz48cD48aW5wdXQgY2xhc3M9ImJ0IiB0eXBlPSJzdWJtaXQiIHZhbHVlPSJSZWdyZXNhci4uLiI+PC9wPjwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZm9ybWZvb3QoKXsNCg0KCXAoJzwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KLy8gJiMxMjk7fyYjMTI5O38mIzEyOTt/JiMxMzM4OyYjMTI5O38mIzEyOTt/JiMxMjk7fw0KDQpmdW5jdGlvbiBwcigkYSkgew0KDQoJZWNobyAnPHByZT4nOw0KDQoJcHJpbnRfcigkYSk7DQoNCgllY2hvICc8L3ByZT4nOw0KDQp9DQoNCmVjaG8gIlxuIjsNCj8+DQo=")); ?> \ No newline at end of file diff --git a/composer.json b/composer.json deleted file mode 100644 index e1bccbca..00000000 --- a/composer.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "require": { - "cboden/ratchet": "dev-master", - "phpoffice/phpspreadsheet": "^1.28" - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 7895a2ec..00000000 --- a/composer.lock +++ /dev/null @@ -1,1837 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "a4a2429ec14ad8e9c5dbf55691a2c6f9", - "packages": [ - { - "name": "cboden/ratchet", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/ratchetphp/Ratchet.git", - "reference": "5012dc954541b40c5599d286fd40653f5716a38f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/5012dc954541b40c5599d286fd40653f5716a38f", - "reference": "5012dc954541b40c5599d286fd40653f5716a38f", - "shasum": "" - }, - "require": { - "guzzlehttp/psr7": "^1.7|^2.0", - "php": ">=5.4.2", - "ratchet/rfc6455": "^0.3.1", - "react/event-loop": ">=0.4", - "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5", - "symfony/http-foundation": "^2.6|^3.0|^4.0|^5.0|^6.0", - "symfony/routing": "^2.6|^3.0|^4.0|^5.0|^6.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "default-branch": true, - "type": "library", - "autoload": { - "psr-4": { - "Ratchet\\": "src/Ratchet" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "role": "Developer" - }, - { - "name": "Matt Bonneau", - "role": "Developer" - } - ], - "description": "PHP WebSocket library", - "homepage": "http://socketo.me", - "keywords": [ - "Ratchet", - "WebSockets", - "server", - "sockets", - "websocket" - ], - "support": { - "chat": "https://gitter.im/reactphp/reactphp", - "issues": "https://github.com/ratchetphp/Ratchet/issues", - "source": "https://github.com/ratchetphp/Ratchet/tree/v0.4.4" - }, - "time": "2021-12-14T00:20:41+00:00" - }, - { - "name": "evenement/evenement", - "version": "v3.0.1", - "source": { - "type": "git", - "url": "https://github.com/igorw/evenement.git", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Evenement": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - } - ], - "description": "Événement is a very simple event dispatching library for PHP", - "keywords": [ - "event-dispatcher", - "event-emitter" - ], - "support": { - "issues": "https://github.com/igorw/evenement/issues", - "source": "https://github.com/igorw/evenement/tree/master" - }, - "time": "2017-07-23T21:35:13+00:00" - }, - { - "name": "ezyang/htmlpurifier", - "version": "v4.16.0", - "source": { - "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8", - "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8", - "shasum": "" - }, - "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "require-dev": { - "cerdic/css-tidy": "^1.7 || ^2.0", - "simpletest/simpletest": "dev-master" - }, - "suggest": { - "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", - "ext-bcmath": "Used for unit conversion and imagecrash protection", - "ext-iconv": "Converts text to and from non-UTF-8 encodings", - "ext-tidy": "Used for pretty-printing HTML" - }, - "type": "library", - "autoload": { - "files": [ - "library/HTMLPurifier.composer.php" - ], - "psr-0": { - "HTMLPurifier": "library/" - }, - "exclude-from-classmap": [ - "/library/HTMLPurifier/Language/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" - } - ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ], - "support": { - "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0" - }, - "time": "2022-09-18T07:06:19+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.5.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ], - "time": "2023-04-17T16:11:26+00:00" - }, - { - "name": "maennchen/zipstream-php", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "b46726e666b5d2ad32959ae9492ee1034e798162" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/b46726e666b5d2ad32959ae9492ee1034e798162", - "reference": "b46726e666b5d2ad32959ae9492ee1034e798162", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-zlib": "*", - "php-64bit": "^8.1" - }, - "require-dev": { - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.16", - "guzzlehttp/guzzle": "^7.5", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.5", - "phpunit/phpunit": "^10.0", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "guzzlehttp/psr7": "^2.4", - "psr/http-message": "^2.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "ZipStream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paul Duncan", - "email": "pabs@pablotron.org" - }, - { - "name": "Jonatan Männchen", - "email": "jonatan@maennchen.ch" - }, - { - "name": "Jesse Donat", - "email": "donatj@gmail.com" - }, - { - "name": "András Kolesár", - "email": "kolesar@kolesar.hu" - } - ], - "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", - "keywords": [ - "stream", - "zip" - ], - "support": { - "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/maennchen", - "type": "github" - }, - { - "url": "https://opencollective.com/zipstream", - "type": "open_collective" - } - ], - "time": "2023-04-19T19:51:03+00:00" - }, - { - "name": "markbaker/complex", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPComplex.git", - "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", - "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "phpcompatibility/php-compatibility": "^9.3", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "squizlabs/php_codesniffer": "^3.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "Complex\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@lange.demon.co.uk" - } - ], - "description": "PHP Class for working with complex numbers", - "homepage": "https://github.com/MarkBaker/PHPComplex", - "keywords": [ - "complex", - "mathematics" - ], - "support": { - "issues": "https://github.com/MarkBaker/PHPComplex/issues", - "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" - }, - "time": "2022-12-06T16:21:08+00:00" - }, - { - "name": "markbaker/matrix", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPMatrix.git", - "reference": "728434227fe21be27ff6d86621a1b13107a2562c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", - "reference": "728434227fe21be27ff6d86621a1b13107a2562c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "phpcompatibility/php-compatibility": "^9.3", - "phpdocumentor/phpdocumentor": "2.*", - "phploc/phploc": "^4.0", - "phpmd/phpmd": "2.*", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "sebastian/phpcpd": "^4.0", - "squizlabs/php_codesniffer": "^3.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "Matrix\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@demon-angel.eu" - } - ], - "description": "PHP Class for working with matrices", - "homepage": "https://github.com/MarkBaker/PHPMatrix", - "keywords": [ - "mathematics", - "matrix", - "vector" - ], - "support": { - "issues": "https://github.com/MarkBaker/PHPMatrix/issues", - "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" - }, - "time": "2022-12-02T22:17:43+00:00" - }, - { - "name": "phpoffice/phpspreadsheet", - "version": "1.29.0", - "source": { - "type": "git", - "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/fde2ccf55eaef7e86021ff1acce26479160a0fa0", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-fileinfo": "*", - "ext-gd": "*", - "ext-iconv": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-xml": "*", - "ext-xmlreader": "*", - "ext-xmlwriter": "*", - "ext-zip": "*", - "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.15", - "maennchen/zipstream-php": "^2.1 || ^3.0", - "markbaker/complex": "^3.0", - "markbaker/matrix": "^3.0", - "php": "^7.4 || ^8.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-main", - "dompdf/dompdf": "^1.0 || ^2.0", - "friendsofphp/php-cs-fixer": "^3.2", - "mitoteam/jpgraph": "^10.3", - "mpdf/mpdf": "^8.1.1", - "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.0 || ^10.0", - "squizlabs/php_codesniffer": "^3.7", - "tecnickcom/tcpdf": "^6.5" - }, - "suggest": { - "dompdf/dompdf": "Option for rendering PDF with PDF Writer", - "ext-intl": "PHP Internationalization Functions", - "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", - "mpdf/mpdf": "Option for rendering PDF with PDF Writer", - "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" - }, - "type": "library", - "autoload": { - "psr-4": { - "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Maarten Balliauw", - "homepage": "https://blog.maartenballiauw.be" - }, - { - "name": "Mark Baker", - "homepage": "https://markbakeruk.net" - }, - { - "name": "Franck Lefevre", - "homepage": "https://rootslabs.net" - }, - { - "name": "Erik Tilt" - }, - { - "name": "Adrien Crivelli" - } - ], - "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", - "keywords": [ - "OpenXML", - "excel", - "gnumeric", - "ods", - "php", - "spreadsheet", - "xls", - "xlsx" - ], - "support": { - "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.0" - }, - "time": "2023-06-14T22:48:31+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], - "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" - }, - "time": "2023-04-10T20:12:12+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" - }, - "time": "2023-04-10T20:10:41+00:00" - }, - { - "name": "psr/http-message", - "version": "2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" - }, - "time": "2023-04-04T09:54:51+00:00" - }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "ratchet/rfc6455", - "version": "v0.3.1", - "source": { - "type": "git", - "url": "https://github.com/ratchetphp/RFC6455.git", - "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/7c964514e93456a52a99a20fcfa0de242a43ccdb", - "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb", - "shasum": "" - }, - "require": { - "guzzlehttp/psr7": "^2 || ^1.7", - "php": ">=5.4.2" - }, - "require-dev": { - "phpunit/phpunit": "^5.7", - "react/socket": "^1.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ratchet\\RFC6455\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "role": "Developer" - }, - { - "name": "Matt Bonneau", - "role": "Developer" - } - ], - "description": "RFC6455 WebSocket protocol handler", - "homepage": "http://socketo.me", - "keywords": [ - "WebSockets", - "rfc6455", - "websocket" - ], - "support": { - "chat": "https://gitter.im/reactphp/reactphp", - "issues": "https://github.com/ratchetphp/RFC6455/issues", - "source": "https://github.com/ratchetphp/RFC6455/tree/v0.3.1" - }, - "time": "2021-12-09T23:20:49+00:00" - }, - { - "name": "react/cache", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/cache.git", - "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", - "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/promise": "^3.0 || ^2.0 || ^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, Promise-based cache interface for ReactPHP", - "keywords": [ - "cache", - "caching", - "promise", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/cache/issues", - "source": "https://github.com/reactphp/cache/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2022-11-30T15:59:55+00:00" - }, - { - "name": "react/dns", - "version": "v1.11.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/dns.git", - "reference": "3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f", - "reference": "3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/cache": "^1.0 || ^0.6 || ^0.5", - "react/event-loop": "^1.2", - "react/promise": "^3.0 || ^2.7 || ^1.2.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^4.8.35", - "react/async": "^4 || ^3 || ^2", - "react/promise-timer": "^1.9" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Dns\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async DNS resolver for ReactPHP", - "keywords": [ - "async", - "dns", - "dns-resolver", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.11.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2023-06-02T12:45:26+00:00" - }, - { - "name": "react/event-loop", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/event-loop.git", - "reference": "6e7e587714fff7a83dcc7025aee42ab3b265ae05" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/6e7e587714fff7a83dcc7025aee42ab3b265ae05", - "reference": "6e7e587714fff7a83dcc7025aee42ab3b265ae05", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" - }, - "suggest": { - "ext-pcntl": "For signal handling support when using the StreamSelectLoop" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\EventLoop\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", - "keywords": [ - "asynchronous", - "event-loop" - ], - "support": { - "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.4.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2023-05-05T10:11:24+00:00" - }, - { - "name": "react/promise", - "version": "v2.10.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", - "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.36" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "keywords": [ - "promise", - "promises" - ], - "support": { - "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.10.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2023-05-02T15:15:43+00:00" - }, - { - "name": "react/socket", - "version": "v1.13.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/socket.git", - "reference": "cff482bbad5848ecbe8b57da57e4e213b03619aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/cff482bbad5848ecbe8b57da57e4e213b03619aa", - "reference": "cff482bbad5848ecbe8b57da57e4e213b03619aa", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.0", - "react/dns": "^1.11", - "react/event-loop": "^1.2", - "react/promise": "^3 || ^2.6 || ^1.2.1", - "react/stream": "^1.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", - "react/async": "^4 || ^3 || ^2", - "react/promise-stream": "^1.4", - "react/promise-timer": "^1.9" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Socket\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", - "keywords": [ - "Connection", - "Socket", - "async", - "reactphp", - "stream" - ], - "support": { - "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.13.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2023-06-07T10:28:34+00:00" - }, - { - "name": "react/stream", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/stream.git", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/7a423506ee1903e89f1e08ec5f0ed430ff784ae9", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.8", - "react/event-loop": "^1.2" - }, - "require-dev": { - "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Stream\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", - "keywords": [ - "event-driven", - "io", - "non-blocking", - "pipe", - "reactphp", - "readable", - "stream", - "writable" - ], - "support": { - "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-07-11T12:37:55+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "718a97ed430d34e5c568ea2c44eab708c6efbefb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/718a97ed430d34e5c568ea2c44eab708c6efbefb", - "reference": "718a97ed430d34e5c568ea2c44eab708c6efbefb", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" - }, - "conflict": { - "symfony/cache": "<6.2" - }, - "require-dev": { - "doctrine/dbal": "^2.13.1|^3.0", - "predis/predis": "^1.1|^2.0", - "symfony/cache": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^5.4|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-19T12:46:45+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php83", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "508c652ba3ccf69f8c97f251534f229791b52a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/508c652ba3ccf69f8c97f251534f229791b52a57", - "reference": "508c652ba3ccf69f8c97f251534f229791b52a57", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-php80": "^1.14" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/routing", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "827f59fdc67eecfc4dfff81f9c93bf4d98f0c89b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/827f59fdc67eecfc4dfff81f9c93bf4d98f0c89b", - "reference": "827f59fdc67eecfc4dfff81f9c93bf4d98f0c89b", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "conflict": { - "doctrine/annotations": "<1.12", - "symfony/config": "<6.2", - "symfony/dependency-injection": "<5.4", - "symfony/yaml": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.12|^2", - "psr/log": "^1|^2|^3", - "symfony/config": "^6.2", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Routing\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Maps an HTTP request to a set of configuration variables", - "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], - "support": { - "source": "https://github.com/symfony/routing/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-04-28T15:57:00+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "cboden/ratchet": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" -} diff --git a/conf/authz b/conf/authz deleted file mode 100644 index 90d88388..00000000 --- a/conf/authz +++ /dev/null @@ -1,32 +0,0 @@ -### This file is an example authorization file for svnserve. -### Its format is identical to that of mod_authz_svn authorization -### files. -### As shown below each section defines authorizations for the path and -### (optional) repository specified by the section name. -### The authorizations follow. An authorization line can refer to: -### - a single user, -### - a group of users defined in a special [groups] section, -### - an alias defined in a special [aliases] section, -### - all authenticated users, using the '$authenticated' token, -### - only anonymous users, using the '$anonymous' token, -### - anyone, using the '*' wildcard. -### -### A match can be inverted by prefixing the rule with '~'. Rules can -### grant read ('r') access, read-write ('rw') access, or no access -### (''). - -[aliases] -# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average - -[groups] -# harry_and_sally = harry,sally -# harry_sally_and_joe = harry,sally,&joe - -# [/foo/bar] -# harry = rw -# &joe = r -# * = - -# [repository:/baz/fuz] -# @harry_and_sally = rw -# * = r diff --git a/conf/bd b/conf/bd deleted file mode 100644 index d407e9ca..00000000 --- a/conf/bd +++ /dev/null @@ -1,9 +0,0 @@ -HOST_DB="127.0.0.1" -BASE_DB="pbx" -USUARIO="contacte" -SENHA="ctepgSQL" -PORTA_DB="5432" -HOST_SCK="192.168.115.11" -PORTA_SCK="5038" -USUARIO_SCK="manager" -SENHA_SCK="manager007" diff --git a/conf/bd.bak b/conf/bd.bak deleted file mode 100644 index 6912bf82..00000000 --- a/conf/bd.bak +++ /dev/null @@ -1,9 +0,0 @@ -HOST_DB="127.0.0.1" -BASE_DB="pbx" -USUARIO="contacte" -SENHA="ctepgSQL" -PORTA_DB="5432" -HOST_SCK="127.0.0.1" -PORTA_SCK="5038" -USUARIO_SCK="manager" -SENHA_SCK="manager007" diff --git a/conf/passwd b/conf/passwd deleted file mode 100644 index d22bafc5..00000000 --- a/conf/passwd +++ /dev/null @@ -1,8 +0,0 @@ -### This file is an example password file for svnserve. -### Its format is similar to that of svnserve.conf. As shown in the -### example below it contains one section labelled [users]. -### The name and password for each user follow, one account per line. - -[users] -# harry = harryssecret -# sally = sallyssecret diff --git a/conf/svnserve.conf b/conf/svnserve.conf deleted file mode 100644 index d22d6311..00000000 --- a/conf/svnserve.conf +++ /dev/null @@ -1,61 +0,0 @@ -### This file controls the configuration of the svnserve daemon, if you -### use it to allow access to this repository. (If you only allow -### access through http: and/or file: URLs, then this file is -### irrelevant.) - -### Visit http://subversion.apache.org/ for more information. - -[general] -### The anon-access and auth-access options control access to the -### repository for unauthenticated (a.k.a. anonymous) users and -### authenticated users, respectively. -### Valid values are "write", "read", and "none". -### Setting the value to "none" prohibits both reading and writing; -### "read" allows read-only access, and "write" allows complete -### read/write access to the repository. -### The sample settings below are the defaults and specify that anonymous -### users have read-only access to the repository, while authenticated -### users have read and write access to the repository. -# anon-access = read -# auth-access = write -### The password-db option controls the location of the password -### database file. Unless you specify a path starting with a /, -### the file's location is relative to the directory containing -### this configuration file. -### If SASL is enabled (see below), this file will NOT be used. -### Uncomment the line below to use the default password file. -# password-db = passwd -### The authz-db option controls the location of the authorization -### rules for path-based access control. Unless you specify a path -### starting with a /, the file's location is relative to the the -### directory containing this file. If you don't specify an -### authz-db, no path-based access control is done. -### Uncomment the line below to use the default authorization file. -# authz-db = authz -### This option specifies the authentication realm of the repository. -### If two repositories have the same authentication realm, they should -### have the same password database, and vice versa. The default realm -### is repository's uuid. -# realm = My First Repository -### The force-username-case option causes svnserve to case-normalize -### usernames before comparing them against the authorization rules in the -### authz-db file configured above. Valid values are "upper" (to upper- -### case the usernames), "lower" (to lowercase the usernames), and -### "none" (to compare usernames as-is without case conversion, which -### is the default behavior). -# force-username-case = none - -[sasl] -### This option specifies whether you want to use the Cyrus SASL -### library for authentication. Default is false. -### This section will be ignored if svnserve is not built with Cyrus -### SASL support; to check, run 'svnserve --version' and look for a line -### reading 'Cyrus SASL authentication is available.' -# use-sasl = true -### These options specify the desired strength of the security layer -### that you want SASL to provide. 0 means no encryption, 1 means -### integrity-checking only, values larger than 1 are correlated -### to the effective key length for encryption (e.g. 128 means 128-bit -### encryption). The values below are the defaults. -# min-encryption = 0 -# max-encryption = 256 diff --git a/info.php b/info.php deleted file mode 100644 index 27369576..00000000 --- a/info.php +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/queues_filas.conf b/queues_filas.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/seguranca/php.ini b/seguranca/php.ini deleted file mode 100644 index b78cd40e..00000000 --- a/seguranca/php.ini +++ /dev/null @@ -1,1221 +0,0 @@ -[PHP] - -;;;;;;;;;;;;;;;;;;; -; About php.ini ; -;;;;;;;;;;;;;;;;;;; -; This file controls many aspects of PHP's behavior. In order for PHP to -; read it, it must be named 'php.ini'. PHP looks for it in the current -; working directory, in the path designated by the environment variable -; PHPRC, and in the path that was defined in compile time (in that order). -; Under Windows, the compile-time path is the Windows directory. The -; path in which the php.ini file is looked for can be overridden using -; the -c argument in command line mode. -; -; The syntax of the file is extremely simple. Whitespace and Lines -; beginning with a semicolon are silently ignored (as you probably guessed). -; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. -; -; Directives are specified using the following syntax: -; directive = value -; Directive names are *case sensitive* - foo=bar is different from FOO=bar. -; -; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one -; of the INI constants (On, Off, True, False, Yes, No and None) or an expression -; (e.g. E_ALL & ~E_NOTICE), or a quoted string ("foo"). -; -; Expressions in the INI file are limited to bitwise operators and parentheses: -; | bitwise OR -; & bitwise AND -; ~ bitwise NOT -; ! boolean NOT -; -; Boolean flags can be turned on using the values 1, On, True or Yes. -; They can be turned off using the values 0, Off, False or No. -; -; An empty string can be denoted by simply not writing anything after the equal -; sign, or by using the None keyword: -; -; foo = ; sets foo to an empty string -; foo = none ; sets foo to an empty string -; foo = "none" ; sets foo to the string 'none' -; -; If you use constants in your value, and these constants belong to a -; dynamically loaded extension (either a PHP extension or a Zend extension), -; you may only use these constants *after* the line that loads the extension. -; -; -;;;;;;;;;;;;;;;;;;; -; About this file ; -;;;;;;;;;;;;;;;;;;; -; This is the recommended, PHP 5-style version of the php.ini-dist file. It -; sets some non standard settings, that make PHP more efficient, more secure, -; and encourage cleaner coding. -; -; The price is that with these settings, PHP may be incompatible with some -; applications, and sometimes, more difficult to develop with. Using this -; file is warmly recommended for production sites. As all of the changes from -; the standard settings are thoroughly documented, you can go over each one, -; and decide whether you want to use it or not. -; -; For general information about the php.ini file, please consult the php.ini-dist -; file, included in your PHP distribution. -; -; This file is different from the php.ini-dist file in the fact that it features -; different values for several directives, in order to improve performance, while -; possibly breaking compatibility with the standard out-of-the-box behavior of -; PHP. Please make sure you read what's different, and modify your scripts -; accordingly, if you decide to use this file instead. -; -; - register_globals = Off [Security, Performance] -; Global variables are no longer registered for input data (POST, GET, cookies, -; environment and other server variables). Instead of using $foo, you must use -; you can use $_REQUEST["foo"] (includes any variable that arrives through the -; request, namely, POST, GET and cookie variables), or use one of the specific -; $_GET["foo"], $_POST["foo"], $_COOKIE["foo"] or $_FILES["foo"], depending -; on where the input originates. Also, you can look at the -; import_request_variables() function. -; Note that register_globals is going to be depracated (i.e., turned off by -; default) in the next version of PHP, because it often leads to security bugs. -; Read http://php.net/manual/en/security.registerglobals.php for further -; information. -; - register_long_arrays = Off [Performance] -; Disables registration of the older (and deprecated) long predefined array -; variables ($HTTP_*_VARS). Instead, use the superglobals that were -; introduced in PHP 4.1.0 -; - display_errors = Off [Security] -; With this directive set to off, errors that occur during the execution of -; scripts will no longer be displayed as a part of the script output, and thus, -; will no longer be exposed to remote users. With some errors, the error message -; content may expose information about your script, web server, or database -; server that may be exploitable for hacking. Production sites should have this -; directive set to off. -; - log_errors = On [Security] -; This directive complements the above one. Any errors that occur during the -; execution of your script will be logged (typically, to your server's error log, -; but can be configured in several ways). Along with setting display_errors to off, -; this setup gives you the ability to fully understand what may have gone wrong, -; without exposing any sensitive information to remote users. -; - output_buffering = 4096 [Performance] -; Set a 4KB output buffer. Enabling output buffering typically results in less -; writes, and sometimes less packets sent on the wire, which can often lead to -; better performance. The gain this directive actually yields greatly depends -; on which Web server you're working with, and what kind of scripts you're using. -; - register_argc_argv = Off [Performance] -; Disables registration of the somewhat redundant $argv and $argc global -; variables. -; - magic_quotes_gpc = Off [Performance] -; Input data is no longer escaped with slashes so that it can be sent into -; SQL databases without further manipulation. Instead, you should use the -; function addslashes() on each input element you wish to send to a database. -; - variables_order = "GPCS" [Performance] -; The environment variables are not hashed into the $_ENV. To access -; environment variables, you can use getenv() instead. -; - error_reporting = E_ALL [Code Cleanliness, Security(?)] -; By default, PHP surpresses errors of type E_NOTICE. These error messages -; are emitted for non-critical errors, but that could be a symptom of a bigger -; problem. Most notably, this will cause error messages about the use -; of uninitialized variables to be displayed. -; - allow_call_time_pass_reference = Off [Code cleanliness] -; It's not possible to decide to force a variable to be passed by reference -; when calling a function. The PHP 4 style to do this is by making the -; function require the relevant argument by reference. - - -;;;;;;;;;;;;;;;;;;;; -; Language Options ; -;;;;;;;;;;;;;;;;;;;; - -; Enable the PHP scripting language engine under Apache. -engine = On - -; Enable compatibility mode with Zend Engine 1 (PHP 4.x) -zend.ze1_compatibility_mode = Off - -; Allow the tags are recognized. -; NOTE: Using short tags should be avoided when developing applications or -; libraries that are meant for redistribution, or deployment on PHP -; servers which are not under your control, because short tags may not -; be supported on the target server. For portable, redistributable code, -; be sure not to use short tags. -short_open_tag = On - -; Allow ASP-style <% %> tags. -asp_tags = Off - -; The number of significant digits displayed in floating point numbers. -precision = 14 - -; Enforce year 2000 compliance (will cause problems with non-compliant browsers) -y2k_compliance = On - -; Output buffering allows you to send header lines (including cookies) even -; after you send body content, at the price of slowing PHP's output layer a -; bit. You can enable output buffering during runtime by calling the output -; buffering functions. You can also enable output buffering for all files by -; setting this directive to On. If you wish to limit the size of the buffer -; to a certain size - you can use a maximum number of bytes instead of 'On', as -; a value for this directive (e.g., output_buffering=4096). -output_buffering = 4096 - -; You can redirect all of the output of your scripts to a function. For -; example, if you set output_handler to "mb_output_handler", character -; encoding will be transparently converted to the specified encoding. -; Setting any output handler automatically turns on output buffering. -; Note: People who wrote portable scripts should not depend on this ini -; directive. Instead, explicitly set the output handler using ob_start(). -; Using this ini directive may cause problems unless you know what script -; is doing. -; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler" -; and you cannot use both "ob_gzhandler" and "zlib.output_compression". -; Note: output_handler must be empty if this is set 'On' !!!! -; Instead you must use zlib.output_handler. -;output_handler = - -; Transparent output compression using the zlib library -; Valid values for this option are 'off', 'on', or a specific buffer size -; to be used for compression (default is 4KB) -; Note: Resulting chunk size may vary due to nature of compression. PHP -; outputs chunks that are few hundreds bytes each as a result of -; compression. If you prefer a larger chunk size for better -; performance, enable output_buffering in addition. -; Note: You need to use zlib.output_handler instead of the standard -; output_handler, or otherwise the output will be corrupted. -zlib.output_compression = Off - -; You cannot specify additional output handlers if zlib.output_compression -; is activated here. This setting does the same as output_handler but in -; a different order. -;zlib.output_handler = - -; Implicit flush tells PHP to tell the output layer to flush itself -; automatically after every output block. This is equivalent to calling the -; PHP function flush() after each and every call to print() or echo() and each -; and every HTML block. Turning this option on has serious performance -; implications and is generally recommended for debugging purposes only. -implicit_flush = Off - -; The unserialize callback function will be called (with the undefined class' -; name as parameter), if the unserializer finds an undefined class -; which should be instantiated. -; A warning appears if the specified function is not defined, or if the -; function doesn't include/implement the missing class. -; So only set this entry, if you really want to implement such a -; callback-function. -unserialize_callback_func= - -; When floats & doubles are serialized store serialize_precision significant -; digits after the floating point. The default value ensures that when floats -; are decoded with unserialize, the data will remain the same. -serialize_precision = 100 - -; Whether to enable the ability to force arguments to be passed by reference -; at function call time. This method is deprecated and is likely to be -; unsupported in future versions of PHP/Zend. The encouraged method of -; specifying which arguments should be passed by reference is in the function -; declaration. You're encouraged to try and turn this option Off and make -; sure your scripts work properly with it in order to ensure they will work -; with future versions of the language (you will receive a warning each time -; you use this feature, and the argument will be passed by value instead of by -; reference). -allow_call_time_pass_reference = Off - -; -; Safe Mode -; -safe_mode = Off - -; By default, Safe Mode does a UID compare check when -; opening files. If you want to relax this to a GID compare, -; then turn on safe_mode_gid. -safe_mode_gid = Off - -; When safe_mode is on, UID/GID checks are bypassed when -; including files from this directory and its subdirectories. -; (directory must also be in include_path or full path must -; be used when including) -safe_mode_include_dir = - -; When safe_mode is on, only executables located in the safe_mode_exec_dir -; will be allowed to be executed via the exec family of functions. -safe_mode_exec_dir = - -; Setting certain environment variables may be a potential security breach. -; This directive contains a comma-delimited list of prefixes. In Safe Mode, -; the user may only alter environment variables whose names begin with the -; prefixes supplied here. By default, users will only be able to set -; environment variables that begin with PHP_ (e.g. PHP_FOO=BAR). -; -; Note: If this directive is empty, PHP will let the user modify ANY -; environment variable! -safe_mode_allowed_env_vars = PHP_ - -; This directive contains a comma-delimited list of environment variables that -; the end user won't be able to change using putenv(). These variables will be -; protected even if safe_mode_allowed_env_vars is set to allow to change them. -safe_mode_protected_env_vars = LD_LIBRARY_PATH - -; open_basedir, if set, limits all file operations to the defined directory -; and below. This directive makes most sense if used in a per-directory -; or per-virtualhost web server configuration file. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -;open_basedir = - -; This directive allows you to disable certain functions for security reasons. -; It receives a comma-delimited list of function names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -disable_functions = - -; This directive allows you to disable certain classes for security reasons. -; It receives a comma-delimited list of class names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -disable_classes = - -; Colors for Syntax Highlighting mode. Anything that's acceptable in -; would work. -;highlight.string = #DD0000 -;highlight.comment = #FF9900 -;highlight.keyword = #007700 -;highlight.bg = #FFFFFF -;highlight.default = #0000BB -;highlight.html = #000000 - -; If enabled, the request will be allowed to complete even if the user aborts -; the request. Consider enabling it if executing long request, which may end up -; being interrupted by the user or a browser timing out. -; ignore_user_abort = On - -; Determines the size of the realpath cache to be used by PHP. This value should -; be increased on systems where PHP opens many files to reflect the quantity of -; the file operations performed. -; realpath_cache_size=16k - -; Duration of time, in seconds for which to cache realpath information for a given -; file or directory. For systems with rarely changing files, consider increasing this -; value. -; realpath_cache_ttl=120 - -; -; Misc -; -; Decides whether PHP may expose the fact that it is installed on the server -; (e.g. by adding its signature to the Web server header). It is no security -; threat in any way, but it makes it possible to determine whether you use PHP -; on your server or not. -expose_php = On - - -;;;;;;;;;;;;;;;;;;; -; Resource Limits ; -;;;;;;;;;;;;;;;;;;; - -max_execution_time = 15 ; Maximum execution time of each script, in seconds -max_input_time = 300 ; Maximum amount of time each script may spend parsing request data -memory_limit = 64M ; Maximum amount of memory a script may consume - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Error handling and logging ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; error_reporting is a bit-field. Or each number up to get desired error -; reporting level -; E_ALL - All errors and warnings (doesn't include E_STRICT) -; E_ERROR - fatal run-time errors -; E_WARNING - run-time warnings (non-fatal errors) -; E_PARSE - compile-time parse errors -; E_NOTICE - run-time notices (these are warnings which often result -; from a bug in your code, but it's possible that it was -; intentional (e.g., using an uninitialized variable and -; relying on the fact it's automatically initialized to an -; empty string) -; E_STRICT - run-time notices, enable to have PHP suggest changes -; to your code which will ensure the best interoperability -; and forward compatibility of your code -; E_CORE_ERROR - fatal errors that occur during PHP's initial startup -; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's -; initial startup -; E_COMPILE_ERROR - fatal compile-time errors -; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) -; E_USER_ERROR - user-generated error message -; E_USER_WARNING - user-generated warning message -; E_USER_NOTICE - user-generated notice message -; -; Examples: -; -; - Show all errors, except for notices and coding standards warnings -; -;error_reporting = E_ALL & ~E_NOTICE -; -; - Show all errors, except for notices -; -;error_reporting = E_ALL & ~E_NOTICE | E_STRICT -; -; - Show only errors -; -;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR -; -; - Show all errors, except coding standards warnings -; -error_reporting = E_ALL & ~E_NOTICE - -; Print out errors (as a part of the output). For production web sites, -; you're strongly encouraged to turn this feature off, and use error logging -; instead (see below). Keeping display_errors enabled on a production web site -; may reveal security information to end users, such as file paths on your Web -; server, your database schema or other information. -display_errors = On - -; Even when display_errors is on, errors that occur during PHP's startup -; sequence are not displayed. It's strongly recommended to keep -; display_startup_errors off, except for when debugging. -display_startup_errors = Off - -; Log errors into a log file (server-specific log, stderr, or error_log (below)) -; As stated above, you're strongly advised to use error logging in place of -; error displaying on production web sites. -log_errors = On - -; Set maximum length of log_errors. In error_log information about the source is -; added. The default is 1024 and 0 allows to not apply any maximum length at all. -log_errors_max_len = 1024 - -; Do not log repeated messages. Repeated errors must occur in same file on same -; line until ignore_repeated_source is set true. -ignore_repeated_errors = Off - -; Ignore source of message when ignoring repeated messages. When this setting -; is On you will not log errors with repeated messages from different files or -; sourcelines. -ignore_repeated_source = Off - -; If this parameter is set to Off, then memory leaks will not be shown (on -; stdout or in the log). This has only effect in a debug compile, and if -; error reporting includes E_WARNING in the allowed list -report_memleaks = On - -; Store the last error/warning message in $php_errormsg (boolean). -track_errors = Off - -; Disable the inclusion of HTML tags in error messages. -; Note: Never use this feature for production boxes. -;html_errors = Off - -; If html_errors is set On PHP produces clickable error messages that direct -; to a page describing the error or function causing the error in detail. -; You can download a copy of the PHP manual from http://www.php.net/docs.php -; and change docref_root to the base URL of your local copy including the -; leading '/'. You must also specify the file extension being used including -; the dot. -; Note: Never use this feature for production boxes. -;docref_root = "/phpmanual/" -;docref_ext = .html - -; String to output before an error message. -;error_prepend_string = "" - -; String to output after an error message. -;error_append_string = "" - -; Log errors to specified file. -;error_log = filename - -; Log errors to syslog (Event Log on NT, not valid in Windows 95). -;error_log = syslog - - -;;;;;;;;;;;;;;;;; -; Data Handling ; -;;;;;;;;;;;;;;;;; -; -; Note - track_vars is ALWAYS enabled as of PHP 4.0.3 - -; The separator used in PHP generated URLs to separate arguments. -; Default is "&". -;arg_separator.output = "&" - -; List of separator(s) used by PHP to parse input URLs into variables. -; Default is "&". -; NOTE: Every character in this directive is considered as separator! -;arg_separator.input = ";&" - -; This directive describes the order in which PHP registers GET, POST, Cookie, -; Environment and Built-in variables (G, P, C, E & S respectively, often -; referred to as EGPCS or GPC). Registration is done from left to right, newer -; values override older values. -variables_order = "EGPCS" - -; Whether or not to register the EGPCS variables as global variables. You may -; want to turn this off if you don't want to clutter your scripts' global scope -; with user data. This makes most sense when coupled with track_vars - in which -; case you can access all of the GPC variables through the $HTTP_*_VARS[], -; variables. -; -; You should do your best to write your scripts so that they do not require -; register_globals to be on; Using form variables as globals can easily lead -; to possible security problems, if the code is not very well thought of. -register_globals = Off - -; Whether or not to register the old-style input arrays, HTTP_GET_VARS -; and friends. If you're not using them, it's recommended to turn them off, -; for performance reasons. -register_long_arrays = Off - -; This directive tells PHP whether to declare the argv&argc variables (that -; would contain the GET information). If you don't use these variables, you -; should turn it off for increased performance. -register_argc_argv = Off - -; When enabled, the SERVER and ENV variables are created when they're first -; used (Just In Time) instead of when the script starts. If these variables -; are not used within a script, having this directive on will result in a -; performance gain. The PHP directives register_globals, register_long_arrays, -; and register_argc_argv must be disabled for this directive to have any affect. -auto_globals_jit = On - -; Maximum size of POST data that PHP will accept. -post_max_size = 8M - -; Magic quotes -; - -; Magic quotes for incoming GET/POST/Cookie data. -magic_quotes_gpc = Off - -; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. -magic_quotes_runtime = Off - -; Use Sybase-style magic quotes (escape ' with '' instead of \'). -magic_quotes_sybase = Off - -; Automatically add files before or after any PHP document. -auto_prepend_file = -auto_append_file = - -; As of 4.0b4, PHP always outputs a character encoding by default in -; the Content-type: header. To disable sending of the charset, simply -; set it to be empty. -; -; PHP's built-in default is text/html -default_mimetype = "text/html" -default_charset = "iso-8859-1" - -; Always populate the $HTTP_RAW_POST_DATA variable. -;always_populate_raw_post_data = On - - -;;;;;;;;;;;;;;;;;;;;;;;;; -; Paths and Directories ; -;;;;;;;;;;;;;;;;;;;;;;;;; - -; UNIX: "/path1:/path2" -;include_path = ".:/php/includes" -; -; Windows: "\path1;\path2" -;include_path = ".;c:\php\includes" - -; The root of the PHP pages, used only if nonempty. -; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root -; if you are running php as a CGI under any web server (other than IIS) -; see documentation for security issues. The alternate is to use the -; cgi.force_redirect configuration below -doc_root = - -; The directory under which PHP opens the script using /~username used only -; if nonempty. -user_dir = - -; Directory in which the loadable extensions (modules) reside. -extension_dir = "/usr/lib/php/modules" - -; Whether or not to enable the dl() function. The dl() function does NOT work -; properly in multithreaded servers, such as IIS or Zeus, and is automatically -; disabled on them. -enable_dl = On - -; cgi.force_redirect is necessary to provide security running PHP as a CGI under -; most web servers. Left undefined, PHP turns this on by default. You can -; turn it off here AT YOUR OWN RISK -; **You CAN safely turn this off for IIS, in fact, you MUST.** -; cgi.force_redirect = 1 - -; if cgi.nph is enabled it will force cgi to always sent Status: 200 with -; every request. -; cgi.nph = 1 - -; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape -; (iPlanet) web servers, you MAY need to set an environment variable name that PHP -; will look for to know it is OK to continue execution. Setting this variable MAY -; cause security issues, KNOW WHAT YOU ARE DOING FIRST. -; cgi.redirect_status_env = ; - -; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate -; security tokens of the calling client. This allows IIS to define the -; security context that the request runs under. mod_fastcgi under Apache -; does not currently support this feature (03/17/2002) -; Set to 1 if running under IIS. Default is zero. -; fastcgi.impersonate = 1; - -; Disable logging through FastCGI connection -; fastcgi.log = 0 - -; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If it's set 0 PHP sends Status: header that -; is supported by Apache. When this option is set to 1 PHP will send -; RFC2616 compliant header. -; Default is zero. -;cgi.rfc2616_headers = 0 - - -;;;;;;;;;;;;;;;; -; File Uploads ; -;;;;;;;;;;;;;;;; - -; Whether to allow HTTP file uploads. -file_uploads = On - -; Temporary directory for HTTP uploaded files (will use system default if not -; specified). -;upload_tmp_dir = - -; Maximum allowed size for uploaded files. -upload_max_filesize = 50M - - -;;;;;;;;;;;;;;;;;; -; Fopen wrappers ; -;;;;;;;;;;;;;;;;;; - -; Whether to allow the treatment of URLs (like http:// or ftp://) as files. -allow_url_fopen = On - -; Define the anonymous ftp password (your email address) -;from="john@doe.com" - -; Define the User-Agent string -; user_agent="PHP" - -; Default timeout for socket based streams (seconds) -default_socket_timeout = 60 - -; If your scripts have to deal with files from Macintosh systems, -; or you are running on a Mac and need to deal with files from -; unix or win32 systems, setting this flag will cause PHP to -; automatically detect the EOL character in those files so that -; fgets() and file() will work regardless of the source of the file. -; auto_detect_line_endings = Off - - -;;;;;;;;;;;;;;;;;;;;;; -; Dynamic Extensions ; -;;;;;;;;;;;;;;;;;;;;;; -; -; If you wish to have an extension loaded automatically, use the following -; syntax: -; -; extension=modulename.extension -; -; For example: -; -; extension=msql.so -; -; Note that it should be the name of the module only; no directory information -; needs to go here. Specify the location of the extension with the -; extension_dir directive above. - - -;;;; -; Note: packaged extension modules are now loaded via the .ini files -; found in the directory /etc/php.d; these are loaded by default. -;;;; - - -;;;;;;;;;;;;;;;;;;; -; Module Settings ; -;;;;;;;;;;;;;;;;;;; - -[Date] -; Defines the default timezone used by the date functions -;date.timezone = - -[Syslog] -; Whether or not to define the various syslog variables (e.g. $LOG_PID, -; $LOG_CRON, etc.). Turning it off is a good idea performance-wise. In -; runtime, you can define these variables by calling define_syslog_variables(). -define_syslog_variables = Off - -[mail function] -; For Win32 only. -SMTP = localhost -smtp_port = 25 - -; For Win32 only. -;sendmail_from = me@example.com - -; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). -sendmail_path = /usr/sbin/sendmail -t -i - -; Force the addition of the specified parameters to be passed as extra parameters -; to the sendmail binary. These parameters will always replace the value of -; the 5th parameter to mail(), even in safe mode. -;mail.force_extra_parameters = - -[SQL] -sql.safe_mode = Off - -[ODBC] -;odbc.default_db = Not yet implemented -;odbc.default_user = Not yet implemented -;odbc.default_pw = Not yet implemented - -; Allow or prevent persistent links. -odbc.allow_persistent = On - -; Check that a connection is still valid before reuse. -odbc.check_persistent = On - -; Maximum number of persistent links. -1 means no limit. -odbc.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -odbc.max_links = -1 - -; Handling of LONG fields. Returns number of bytes to variables. 0 means -; passthru. -odbc.defaultlrl = 4096 - -; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char. -; See the documentation on odbc_binmode and odbc_longreadlen for an explanation -; of uodbc.defaultlrl and uodbc.defaultbinmode -odbc.defaultbinmode = 1 - -[MySQL] -; Allow or prevent persistent links. -mysql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -mysql.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -mysql.max_links = -1 - -; Default port number for mysql_connect(). If unset, mysql_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -mysql.default_port = - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -mysql.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -mysql.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -mysql.default_user = - -; Default password for mysql_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -mysql.default_password = - -; Maximum time (in secondes) for connect timeout. -1 means no limit -mysql.connect_timeout = 60 - -; Trace mode. When trace_mode is active (=On), warnings for table/index scans and -; SQL-Errors will be displayed. -mysql.trace_mode = Off - -[MySQLi] - -; Maximum number of links. -1 means no limit. -mysqli.max_links = -1 - -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -mysqli.default_port = 3306 - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -mysqli.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -mysqli.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -mysqli.default_user = - -; Default password for mysqli_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -mysqli.default_pw = - -; Allow or prevent reconnect -mysqli.reconnect = Off - -[mSQL] -; Allow or prevent persistent links. -msql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -msql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -msql.max_links = -1 - -[PostgresSQL] -; Allow or prevent persistent links. -pgsql.allow_persistent = On - -; Detect broken persistent links always with pg_pconnect(). -; Auto reset feature requires a little overheads. -pgsql.auto_reset_persistent = Off - -; Maximum number of persistent links. -1 means no limit. -pgsql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -pgsql.max_links = -1 - -; Ignore PostgreSQL backends Notice message or not. -; Notice message logging require a little overheads. -pgsql.ignore_notice = 0 - -; Log PostgreSQL backends Noitce message or not. -; Unless pgsql.ignore_notice=0, module cannot log notice message. -pgsql.log_notice = 0 - -[Sybase] -; Allow or prevent persistent links. -sybase.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -sybase.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -sybase.max_links = -1 - -;sybase.interface_file = "/usr/sybase/interfaces" - -; Minimum error severity to display. -sybase.min_error_severity = 10 - -; Minimum message severity to display. -sybase.min_message_severity = 10 - -; Compatability mode with old versions of PHP 3.0. -; If on, this will cause PHP to automatically assign types to results according -; to their Sybase type, instead of treating them all as strings. This -; compatability mode will probably not stay around forever, so try applying -; whatever necessary changes to your code, and turn it off. -sybase.compatability_mode = Off - -[Sybase-CT] -; Allow or prevent persistent links. -sybct.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -sybct.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -sybct.max_links = -1 - -; Minimum server message severity to display. -sybct.min_server_severity = 10 - -; Minimum client message severity to display. -sybct.min_client_severity = 10 - -[bcmath] -; Number of decimal digits for all bcmath functions. -bcmath.scale = 0 - -[browscap] -;browscap = extra/browscap.ini - -[Informix] -; Default host for ifx_connect() (doesn't apply in safe mode). -ifx.default_host = - -; Default user for ifx_connect() (doesn't apply in safe mode). -ifx.default_user = - -; Default password for ifx_connect() (doesn't apply in safe mode). -ifx.default_password = - -; Allow or prevent persistent links. -ifx.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -ifx.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -ifx.max_links = -1 - -; If on, select statements return the contents of a text blob instead of its id. -ifx.textasvarchar = 0 - -; If on, select statements return the contents of a byte blob instead of its id. -ifx.byteasvarchar = 0 - -; Trailing blanks are stripped from fixed-length char columns. May help the -; life of Informix SE users. -ifx.charasvarchar = 0 - -; If on, the contents of text and byte blobs are dumped to a file instead of -; keeping them in memory. -ifx.blobinfile = 0 - -; NULL's are returned as empty strings, unless this is set to 1. In that case, -; NULL's are returned as string 'NULL'. -ifx.nullformat = 0 - -[Session] -; Handler used to store/retrieve data. -session.save_handler = files - -; Argument passed to save_handler. In the case of files, this is the path -; where data files are stored. Note: Windows users have to change this -; variable in order to use PHP's session functions. -; -; As of PHP 4.0.1, you can define the path as: -; -; session.save_path = "N;/path" -; -; where N is an integer. Instead of storing all the session files in -; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if you -; or your OS have problems with lots of files in one directory, and is -; a more efficient layout for servers that handle lots of sessions. -; -; NOTE 1: PHP will not create this directory structure automatically. -; You can use the script in the ext/session dir for that purpose. -; NOTE 2: See the section on garbage collection below if you choose to -; use subdirectories for session storage -; -; The file storage module creates files using mode 600 by default. -; You can change that by using -; -; session.save_path = "N;MODE;/path" -; -; where MODE is the octal representation of the mode. Note that this -; does not overwrite the process's umask. -session.save_path = "/var/lib/php/session" - -; Whether to use cookies. -session.use_cookies = 1 - -; This option enables administrators to make their users invulnerable to -; attacks which involve passing session ids in URLs; defaults to 0. -; session.use_only_cookies = 1 - -; Name of the session (used as cookie name). -session.name = PHPSESSID - -; Initialize session on request startup. -session.auto_start = 0 - -; Lifetime in seconds of cookie or, if 0, until browser is restarted. -session.cookie_lifetime = 0 - -; The path for which the cookie is valid. -session.cookie_path = / - -; The domain for which the cookie is valid. -session.cookie_domain = - -; Handler used to serialize data. php is the standard serializer of PHP. -session.serialize_handler = php - -; Define the probability that the 'garbage collection' process is started -; on every session initialization. -; The probability is calculated by using gc_probability/gc_divisor, -; e.g. 1/100 means there is a 1% chance that the GC process starts -; on each request. - -session.gc_probability = 1 -session.gc_divisor = 1000 - -; After this number of seconds, stored data will be seen as 'garbage' and -; cleaned up by the garbage collection process. -session.gc_maxlifetime = 1440 - -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script would is the equivalent of -; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; cd /path/to/sessions; find -cmin +24 | xargs rm - -; PHP 4.2 and less have an undocumented feature/bug that allows you to -; to initialize a session variable in the global scope, albeit register_globals -; is disabled. PHP 4.3 and later will warn you, if this feature is used. -; You can disable the feature and the warning separately. At this time, -; the warning is only displayed, if bug_compat_42 is enabled. - -session.bug_compat_42 = 0 -session.bug_compat_warn = 1 - -; Check HTTP Referer to invalidate externally stored URLs containing ids. -; HTTP_REFERER has to contain this substring for the session to be -; considered as valid. -session.referer_check = - -; How many bytes to read from the file. -session.entropy_length = 0 - -; Specified here to create the session id. -session.entropy_file = - -;session.entropy_length = 16 - -;session.entropy_file = /dev/urandom - -; Set to {nocache,private,public,} to determine HTTP caching aspects -; or leave this empty to avoid sending anti-caching headers. -session.cache_limiter = nocache - -; Document expires after n minutes. -session.cache_expire = 180 - -; trans sid support is disabled by default. -; Use of trans sid may risk your users security. -; Use this option with caution. -; - User may send URL contains active session ID -; to other person via. email/irc/etc. -; - URL that contains active session ID may be stored -; in publically accessible computer. -; - User may access your site with the same session ID -; always using URL stored in browser's history or bookmarks. -session.use_trans_sid = 0 - -; Select a hash function -; 0: MD5 (128 bits) -; 1: SHA-1 (160 bits) -session.hash_function = 0 - -; Define how many bits are stored in each character when converting -; the binary hash data to something readable. -; -; 4 bits: 0-9, a-f -; 5 bits: 0-9, a-v -; 6 bits: 0-9, a-z, A-Z, "-", "," -session.hash_bits_per_character = 5 - -; The URL rewriter will look for URLs in a defined set of HTML tags. -; form/fieldset are special; if you include them here, the rewriter will -; add a hidden field with the info which is otherwise appended -; to URLs. If you want XHTML conformity, remove the form entry. -; Note that all valid entries require a "=", even if no value follows. -url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" - -[MSSQL] -; Allow or prevent persistent links. -mssql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -mssql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -mssql.max_links = -1 - -; Minimum error severity to display. -mssql.min_error_severity = 10 - -; Minimum message severity to display. -mssql.min_message_severity = 10 - -; Compatability mode with old versions of PHP 3.0. -mssql.compatability_mode = Off - -; Connect timeout -;mssql.connect_timeout = 5 - -; Query timeout -;mssql.timeout = 60 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textlimit = 4096 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textsize = 4096 - -; Limits the number of records in each batch. 0 = all records in one batch. -;mssql.batchsize = 0 - -; Specify how datetime and datetim4 columns are returned -; On => Returns data converted to SQL server settings -; Off => Returns values as YYYY-MM-DD hh:mm:ss -;mssql.datetimeconvert = On - -; Use NT authentication when connecting to the server -mssql.secure_connection = Off - -; Specify max number of processes. -1 = library default -; msdlib defaults to 25 -; FreeTDS defaults to 4096 -;mssql.max_procs = -1 - -; Specify client character set. -; If empty or not set the client charset from freetds.comf is used -; This is only used when compiled with FreeTDS -;mssql.charset = "ISO-8859-1" - -[Assertion] -; Assert(expr); active by default. -;assert.active = On - -; Issue a PHP warning for each failed assertion. -;assert.warning = On - -; Don't bail out by default. -;assert.bail = Off - -; User-function to be called if an assertion fails. -;assert.callback = 0 - -; Eval the expression with current error_reporting(). Set to true if you want -; error_reporting(0) around the eval(). -;assert.quiet_eval = 0 - -[Verisign Payflow Pro] -; Default Payflow Pro server. -pfpro.defaulthost = "test-payflow.verisign.com" - -; Default port to connect to. -pfpro.defaultport = 443 - -; Default timeout in seconds. -pfpro.defaulttimeout = 30 - -; Default proxy IP address (if required). -;pfpro.proxyaddress = - -; Default proxy port. -;pfpro.proxyport = - -; Default proxy logon. -;pfpro.proxylogon = - -; Default proxy password. -;pfpro.proxypassword = - -[COM] -; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs -;com.typelib_file = -; allow Distributed-COM calls -;com.allow_dcom = true -; autoregister constants of a components typlib on com_load() -;com.autoregister_typelib = true -; register constants casesensitive -;com.autoregister_casesensitive = false -; show warnings on duplicate constat registrations -;com.autoregister_verbose = true - -[mbstring] -; language for internal character representation. -;mbstring.language = Japanese - -; internal/script encoding. -; Some encoding cannot work as internal encoding. -; (e.g. SJIS, BIG5, ISO-2022-*) -;mbstring.internal_encoding = EUC-JP - -; http input encoding. -;mbstring.http_input = auto - -; http output encoding. mb_output_handler must be -; registered as output buffer to function -;mbstring.http_output = SJIS - -; enable automatic encoding translation according to -; mbstring.internal_encoding setting. Input chars are -; converted to internal encoding by setting this to On. -; Note: Do _not_ use automatic encoding translation for -; portable libs/applications. -;mbstring.encoding_translation = Off - -; automatic encoding detection order. -; auto means -;mbstring.detect_order = auto - -; substitute_character used when character cannot be converted -; one from another -;mbstring.substitute_character = none; - -; overload(replace) single byte functions by mbstring functions. -; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), -; etc. Possible values are 0,1,2,4 or combination of them. -; For example, 7 for overload everything. -; 0: No overload -; 1: Overload mail() function -; 2: Overload str*() functions -; 4: Overload ereg*() functions -;mbstring.func_overload = 0 - -; enable strict encoding detection. -;mbstring.strict_encoding = Off - -[FrontBase] -;fbsql.allow_persistent = On -;fbsql.autocommit = On -;fbsql.default_database = -;fbsql.default_database_password = -;fbsql.default_host = -;fbsql.default_password = -;fbsql.default_user = "_SYSTEM" -;fbsql.generate_warnings = Off -;fbsql.max_connections = 128 -;fbsql.max_links = 128 -;fbsql.max_persistent = -1 -;fbsql.max_results = 128 -;fbsql.batchSize = 1000 - -[gd] -; Tell the jpeg decode to libjpeg warnings and try to create -; a gd image. The warning will then be displayed as notices -; disabled by default -;gd.jpeg_ignore_warning = 0 - -[exif] -; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS. -; With mbstring support this will automatically be converted into the encoding -; given by corresponding encode setting. When empty mbstring.internal_encoding -; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. -;exif.encode_unicode = ISO-8859-15 -;exif.decode_unicode_motorola = UCS-2BE -;exif.decode_unicode_intel = UCS-2LE -;exif.encode_jis = -;exif.decode_jis_motorola = JIS -;exif.decode_jis_intel = JIS - -[Tidy] -; The path to a default tidy configuration file to use when using tidy -;tidy.default_config = /usr/local/lib/php/default.tcfg - -; Should tidy clean and repair output automatically? -; WARNING: Do not use this option if you are generating non-html content -; such as dynamic images -tidy.clean_output = Off - -[soap] -; Enables or disables WSDL caching feature. -soap.wsdl_cache_enabled=1 -; Sets the directory name where SOAP extension will put cache files. -soap.wsdl_cache_dir="/tmp" -; (time to live) Sets the number of second while cached file will be used -; instead of original one. -soap.wsdl_cache_ttl=86400 - -; Local Variables: -; tab-width: 4 -; End: diff --git a/sip_ramais.conf b/sip_ramais.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/sip_register.conf b/sip_register.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/voicemail.conf b/voicemail.conf deleted file mode 100644 index 2f24b41c..00000000 --- a/voicemail.conf +++ /dev/null @@ -1,4 +0,0 @@ -[general] - -[default] -