Não consigo ler arquivo de retorno com HB34+hwgui

Projeto HwGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Não consigo ler arquivo de retorno com HB34+hwgui

Mensagem por gilbertosilverio »

Ola Amigos,

Alguém poderia me dizer o que esta errado nesta classe, pois com XHB+HWGUI+WVT+BCC51 funciona normalmente, mais compilando somente com HWGUI+HB34+GCC, não retorna nada de jeito algum...

Ja fiz de tudo, mais não retorna nada...

Código: Selecionar todos

FUNCTION RETORNO_BRADESCO()
    PRIVATE Nosso_Numero, Vencimento, DataProcessa, Valor, Multa, DocumentoNo, xDESCONTO
    PRIVATE BancoPgto, Agencia, Ocorrencia, Descricao, CodigoRejei
    PRIVATE xPA, xPROCESSA, xBAIXA

    PRIVATE vLOJA:=1, MATA:={}

    cFile := Hwg_Selectfile( {"Arquivo de Retorno( *.Ret)", " ALL Files( *.*)"}, { "*.ret","*.*"} )

    HWG_MSGINFO(cFILE)

    IF EMPTY(cFILE)
       HWG_MSGINFO([Nenhum arquivo foi selecionado... Retorno abortado],[Aviso do sistema])
       DBCLOSEALL()
       RETURN NIL
    ENDIF

    oRet := oRetorno([237], @cFILE)

    HWG_MSGINFO( oRet:cCodBco)

    IF oRet:cCodBco == "237"
       DO WHILE !oRet:eof()
           IF oRet:isPago == .t.
              xPA := [PAGO] ; xBAIXA:=[X] //? "o Titulo abaixo foi pago"
           ELSE
              xPA := [    ] ; xBAIXA:=[ ]
           ENDIF
           IF oRet:isOk  == .t. //? "o Titulo foi processado"
              xPROCESSA:=[SIM]
           ELSE
              xPROCESSA:=[   ]
           ENDIF
           Nosso_Numero := oRet:cNossoNumero
           Vencimento   := dtoc(oRet:DtVenc)
           DataProcessa := dtoc(oRet:DtPagto)
           Valor        := str(oRet:nValor)
           Multa        := str(oRet:nMulta)
           xDesconto    := str(oRet:nDesconto)
           Docume       := oRet:cNumDoc
           BancoPgto    := oRet:cBcoPag
           Agencia      := oRet:cNumAgencia
           Ocorrencia   := oRet:cOcorrencia
           Descricao    := oRet:cDescOcorrencia
           CodigoRejei  := oRet:cRejeicao
           ContaCorrente:= oRET:cContaCor
           oRet:Next()
           //              1     2       3           4            5           6           7      8        9       10         11        12         13            14           15           16
           AADD( MATA, { xBAIXA, xPA, xPROCESSA, Nosso_Numero, Vencimento, DataProcessa, Valor, Multa, Docume, BancoPgto, Agencia, Ocorrencia, Descricao, CodigoRejei, ContaCorrente, xDESCONTO })
       ENDDO
       IF LEN(MATA) > 0
          TITULO:={ [B], [Pago], [Entra], [Nosso_Numero], [Vencimento], [DataProcessa], [ValorRecebido], [Juros], [Docume ], [BancoPgto], [Agencia], [Ocorrencia], [Descricao], [CodigoRejeicao],[C/C], [Desconto] }
          HWG_MSGINFO(STR(LEN(MATA)))
          TROCA_DIR(vLOJA)
       ENDIF
    ELSE
       HWG_MSGINFO([Este arquivo de retorno nao percente ao BRADESCO])
    ENDIF
RETURN NIL

Código: Selecionar todos

#include "harbourboleto.ch"
#include "fileio.ch"
#include "hbclass.ch"

CLASS oRetorno

DATA cLine           INIT ""  PROTECTED

DATA nHandle         INIT 0   PROTECTED  // link - Arquivo Retorno (Fopen)
DATA nLen            INIT 0   PROTECTED  // tamanho do arquivo de retorno em bytes

DATA cCodBco         INIT ""  READONLY
DATA cNomeBco        INIT ""  READONLY
DATA DtVenc          INIT ctod("") READONLY   // Data de vencimento no Formato data
DATA DtPagto         INIT ctod("") READONLY   // Data de pagamento no Formato data
DATA nValor          INIT 0   READONLY   // Valor Recebido
DATA nMulta          INIT 0   READONLY   // Valor da Multa
DATA nDesconto       INIT 0   READONLY   // Valor do desconto
DATA cNumDoc         INIT ""  READONLY
DATA cNossoNumero    INIT ""  READONLY
DATA cBcoPag         INIT ""  READONLY // Banco onde foi feito o pagamento
DATA cNumAgencia     INIT ""  READONLY //  Agencia onde foi feito o pagamento
DATA cRejeicao       INIT ""  READONLY // codigo da ocorrencia
DATA cOcorrencia     INIT ""  READONLY // descri‡Æo das ocorrencias
DATA cDescOcorrencia INIT ""  READONLY // descri‡Æo das ocorrencias
DATA isPago          INIT .f. READONLY //  Titulo foi pago
DATA isOk            INIT .f. READONLY //  titulo processado normalmente

DATA cContaCor       INIT "" READONLY  //  N da conta corrente

DATA CNAB400         INIT .T.          // .T. = CNAB400 ou .F. = CNAB240(Febraban)


METHOD New( cBco, cArq ) CONSTRUCTOR
METHOD Next()
METHOD eof()
METHOD Close()
METHOD Readln(nBytes) PROTECTED
METHOD OcorrenciaExt() PROTECTED
ENDCLASS

/* -------------------------------------------------------------------------- */

METHOD new( cBco, cArq ) CLASS oRetorno
   local nBytes
   DEFAULT cBco TO "237"
   IF file(cArq)
      ::nHandle :=fopen(cArq)
      ::nLen    := FSEEK(::nHandle,0,FS_END )
      FSEEK(::nHandle,0 )
      HB_FReadLine(::nHandle,@::cLine)
      ::CNAB400:=(len(::cLine) == 400)
      FSEEK(::nHandle,0 )
      IF ::CNAB400
	 DO CASE
	    CASE cBco == "237"
	      ::READLN(402)
	       IF SUBS(::cLine,077 ,3) == cBco
		  ::cNomeBco:= "BRADESCO"
		  ::cCodBco := cBco
	       endif
	    CASE cBco == "341"
	       ::READLN(402)
	       IF SUBS(::cLine,077  ,3) == cBco
		  ::cNomeBco:= "BANCO ITAU  SA"
		  ::cCodBco := cBco
                  ::cContaCor   :=SUBS(::cLine,033,07)
	       endif
	    CASE cBco == "409"
	       ::cNomeBco   := "UNIBANCO"
	       ::cCodBco := cBco
	    CASE cBco == "422"
	       ::cNomeBco := "Safra"
	       ::cCodBco := cBco
	    OTHERWISE
	       ::nLen:=0
	 ENDCASE
	 ::cNomeBco := PAD(::cNomeBco, 15)
      else
        ::READLN(242)
        ::cNomeBco := subs(::cLine,103,40)
        ::cCodBco  := subs(::cLine,1,3)
      ENDIF
      ::Next()
   ENDIF

RETURN Self

/* -------------------------------------------------------------------------- */

METHOD Next( ) CLASS oRetorno
   local cIDreg:=""
   ::isPago :=.F.
   ::isOk   :=.F.
   IF ::CNAB400
      DO CASE
         CASE ::cCodBco == "237"
	      DO WHILE cIDreg # "1" .and. .not. ::eof()
		 ::READLN(402)
		 cIDreg:=SUBS(::cLine,1,1)
	      ENDDO
	      IF ::Eof()
		 ::Close()
	      ELSE
                 ::DtVenc      :=ctod(trans(SUBS(::cLine,147,6) ,"@R 99/99/2099"))
		 ::DtPagto     :=ctod(trans(SUBS(::cLine,111,6) ,"@R 99/99/2099"))
		 ::nValor      :=val(SUBS(::cLine,254,13))/100
		 ::nMulta      :=val(SUBS(::cLine,267,13))/100
                 ::nDesconto   :=val(SUBS(::cLine,241,13))/100
		 ::cNumDoc     :=SUBS(::cLine,117,10)
		 ::cNossoNumero:=SUBS(::cLine,071,12)
		 ::cBcoPag     :=SUBS(::cLine,166,3)
		 ::cNumAgencia :=SUBS(::cLine,169,5)
		 ::cOcorrencia :=SUBS(::cLine,109,2)
		 ::cRejeicao   :=SUBS(::cLine,319,10)
                 ::cContaCor   :=SUBS(::cLine,31,07)
		 IF ::cOcorrencia == "06"     //"06" $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ELSEIF ::cOcorrencia == "15" //"06" $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ELSEIF ::cOcorrencia == "17" //"06" $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ENDIF
		 ::OcorrenciaExt()
	      ENDIF
	 CASE ::cCodBco == "341"
	      DO WHILE cIDreg # "1" .and. .not. ::eof()
		 ::READLN(402)
		 cIDreg:=SUBS(::cLine,1,1)
	      ENDDO
	      IF ::Eof()
		 ::Close()
	      ELSE
		 ::DtVenc      :=ctod(trans(SUBS(::cLine,147,6) ,"@R 99/99/2099"))
		 ::DtPagto     :=ctod(trans(SUBS(::cLine,296,6) ,"@R 99/99/2099"))
		 ::nValor      :=val(SUBS(::cLine,153 ,13))/100
		 ::nMulta      :=val(SUBS(::cLine,267,13))/100
		 ::cNumDoc     :=SUBS(::cLine,038,25)
		 ::cNossoNumero:="0000"+SUBS(::cLine,063,08)
		 ::cBcoPag     :=SUBS(::cLine,166,03)
		 ::cNumAgencia :=SUBS(::cLine,169,05)
		 ::cOcorrencia :=SUBS(::cLine,109,02)
		 ::cRejeicao   :=SUBS(::cLine,378,08)
		 IF ::cOcorrencia == "06"     //"06" PAGTO NORMAL     $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ELSEIF ::cOcorrencia == "08" //"08" PAGO EM CARTORIO $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ELSEIF ::cOcorrencia == "15" //"06" $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ELSEIF ::cOcorrencia == "17" //"06" $ ::cRejeicao .or."17" $ ::cOcorrencia
		    ::isPago :=.t.
		 ENDIF
		 ::cDescOcorrencia:=""
	       ENDIF
	 CASE ::cCodBco == "409"
       DO WHILE cIDreg # "1" .and. .not. ::eof()
          ::READLN(402)
          cIDreg:=SUBS(::cLine,1,1)
       ENDDO
       IF ::Eof()
          ::Close()
       ELSE
         ::DtVenc      :=ctod(trans(SUBS(::cLine,147,6) ,"@R 99/99/2099"))
         ::DtPagto     :=ctod(trans(SUBS(::cLine,111,6) ,"@R 99/99/2099"))
         ::nValor      :=val(SUBS(::cLine,254,13))/100
         ::nMulta      :=val(SUBS(::cLine,267,13))/100
         ::cNumDoc     :=SUBS(::cLine,117,12)
         ::cNossoNumero:=SUBS(::cLine,063,15)
         ::cBcoPag     :=SUBS(::cLine,166,3)
         ::cNumAgencia :=SUBS(::cLine,169,5)
         ::cOcorrencia :=SUBS(::cLine,109,2)
         ::cRejeicao   := ""//SUBS(::cLine,319,10)
         //IF left(::cOcorrencia,2) $ "06 17"
           ::isPago :=.t.
         //ENDIF
         // temos aqui o problema de acentuacao ANSI/OEM
         // algo para ser resolvido ...
         ::OcorrenciaExt()
       ENDIF
	 CASE ::cCodBco == "422"
	      DO WHILE cIDreg # "1" .and. .not. ::eof()
		 ::READLN(402)
		 cIDreg:=SUBS(::cLine,1,1)
	      ENDDO
	      IF ::Eof()
		 ::Close()
	      ELSE
		 ::DtVenc      :=ctod(trans(SUBS(::cLine,147,6) ,"@R 99/99/2099"))
		 ::DtPagto     :=ctod(trans(SUBS(::cLine,111,6) ,"@R 99/99/2099"))
		 ::nValor      :=val(SUBS(::cLine,153 ,13))/100
		 ::nMulta      :=val(SUBS(::cLine,267,13))/100
		 ::cNumDoc     :=SUBS(::cLine,117,10)
		 IF SUBS(::cLine,108,1) =="6"
		    ::cNossoNumero:=SUBS(::cLine,38,17)+" "
		 ELSE
		    ::cNossoNumero:="000"+SUBS(::cLine,63,9)
		 ENDIF
		 ::cBcoPag     := ""
		 ::cNumAgencia := ""
		    ::isPago :=.t.
		 ::cOcorrencia :=SUBS(::cLine,109,2)
		 ::cRejeicao   :=SUBS(::cLine,105,3)
		 ::cDescOcorrencia:=""
		 IF "06" $ ::cOcorrencia
		    ::isPago :=.t.
		 ENDIF
	       ENDIF
      ENDCASE

   ELSE // CNAB240

     If ::cCodBco == "104"

        DO WHILE cIDreg # "3" .and. .not. ::eof()
           ::READLN(242)
           cIDreg:=SUBS(::cLine,8,1)
        ENDDO

        IF ::Eof()
           ::Close()
        ELSE

          Seg := SUBS(::cLine,14,1) // Segmento Detalhe (T) (U)

          If Seg == "T"
             ::cOcorrencia  := SUBS(::cLine,16,2)
             ::cNossoNumero := SUBS(::cLine,40,17)
             ::cNumDoc      := SUBS(::cLine,59,11)
             ::DtVenc       := CTOD(Tran(SUBS(::cLine,74,8)  ,"@R 99/99/9999"))
             ::nValor       := VAL(SUBS(::cLine,82,15))/100
             ::cBcoPag      := SUBS(::cLine,97,3)
             ::cNumAgencia  := SUBS(::cLine,100,5)
             ::cRejeicao    := SUBS(::cLine,214,10)
          Endif

          If Seg == "U"
             ::DtPagto      := CTOD(Tran(SUBS(::cLine,138,8) ,"@R 99/99/9999"))
             ::nMulta       := VAL(SUBS(::cLine,18,15))/100
          Endif

          ::isPago       := ( ::cOcorrencia == "06" )
          ::OcorrenciaExt()

        ENDIF

     Else  // Outros

        DO WHILE cIDreg # "3" .and. .not. ::eof()
           ::READLN(242)
           cIDreg:=SUBS(::cLine,8,1)
        ENDDO
        IF ::Eof()
           ::Close()
        ELSE
           ::DtVenc      :=ctod(trans(SUBS(::cLine,72,8) ,"@R 99/99/9999"))
           ::DtPagto     :=date()
           ::nValor      :=val(SUBS(::cLine,80,15))/100
           ::nMulta      :=val(SUBS(::cLine,110,15))/100
           ::cNumDoc     :=SUBS(::cLine,59,13)
           ::cNossoNumero:=SUBS(::cLine,047,10)
           ::cBcoPag     :=SUBS(::cLine,095,3)
           ::cNumAgencia :=SUBS(::cLine,098,6)
           ::cOcorrencia :=SUBS(::cLine,016,2)
           ::cRejeicao   :=SUBS(::cLine,226,10)
           ::isPago :=( ::cOcorrencia =="06" )
           ::OcorrenciaExt()
        ENDIF

     Endif

   ENDIF

RETURN Self

/* -------------------------------------------------------------------------- */
METHOD eof( ) CLASS oRetorno
return (::nLen == 0)

/* -------------------------------------------------------------------------- */
METHOD Close( ) CLASS oRetorno
   fclose(::nHandle)
RETURN Self

/* -------------------------------------------------------------------------- */
METHOD Readln(nBytes) CLASS oRetorno
   ::cLine:=space(nBytes)
   FREAD(::nHandle,@::cLine,nBytes)
   ::nLen-=nBytes
return ::cLine

/* -------------------------------------------------------------------------- */
METHOD OcorrenciaExt() CLASS oRetorno
      DO CASE
         CASE ::cOcorrencia == "02"
              ::cDescOcorrencia:="Entrada Confirmada"
              ::isOk   :=.t.
         CASE ::cOcorrencia == "03"
              ::cDescOcorrencia:="Entrada Rejeitada motivo "+::cRejeicao
         CASE ::cOcorrencia == "06"
              ::cDescOcorrencia:="Liquida‡Æo normal                                   "
         CASE ::cOcorrencia == "09"
              ::cDescOcorrencia:="Baixado Automat. via Arquivo motivo "+::cRejeicao
         CASE ::cOcorrencia == "10"
              ::cDescOcorrencia:="Baixado conforme instru‡äes da Agˆncia motivo "+::cRejeicao
         CASE ::cOcorrencia == "11"
              ::cDescOcorrencia:="Em Ser - Arquivo de T¡tulos pendentes"
         CASE ::cOcorrencia == "12"
              ::cDescOcorrencia:="Abatimento Concedido"
         CASE ::cOcorrencia == "13"
              ::cDescOcorrencia:="Abatimento Cancelado"
         CASE ::cOcorrencia == "14"
              ::cDescOcorrencia:="Vencimento Alterado"
         CASE ::cOcorrencia == "15"
              ::cDescOcorrencia:="Liquidacao em Cartorio"
         CASE ::cOcorrencia == "16"
              ::cDescOcorrencia:="Titulo Pago em Cheque Vinculado"
         CASE ::cOcorrencia == "17"
              ::cDescOcorrencia:="Liquida‡Æo apos baixa ou Titulo nao registrado"
         CASE ::cOcorrencia == "18"
              ::cDescOcorrencia:="Acerto de Deposit ria"
         CASE ::cOcorrencia == "19"
              ::cDescOcorrencia:="Confirma‡ao Receb. Inst. de Protesto motivo "+::cRejeicao
         CASE ::cOcorrencia == "20"
              ::cDescOcorrencia:="Confirma‡ao Recebimento Instru‡Æo Susta‡ao de Protesto"
         CASE ::cOcorrencia == "21"
              ::cDescOcorrencia:="Acerto do Controle do Participante"
         CASE ::cOcorrencia == "22"
              ::cDescOcorrencia:="Titulo Com Pagamento Cancelado"
         CASE ::cOcorrencia == "23"
              ::cDescOcorrencia:="Entrada do Titulo em Cartorio"
         CASE ::cOcorrencia == "24"
              ::cDescOcorrencia:="Entrada rejeitada por CEP Irregular motivo "+::cRejeicao
         CASE ::cOcorrencia == "27"
              ::cDescOcorrencia:="Baixa Rejeitada motivo "+::cRejeicao
         CASE ::cOcorrencia == "28"
              ::cDescOcorrencia:="Debito de tarifas/custas motivo "+::cRejeicao
         CASE ::cOcorrencia == "30"
              ::cDescOcorrencia:="Altera‡ao de Outros Dados Rejeitados motivo "+::cRejeicao
         CASE ::cOcorrencia == "32"
              ::cDescOcorrencia:="Instru‡ao Rejeitada motivo "+::cRejeicao
         CASE ::cOcorrencia == "33"
              ::cDescOcorrencia:="Confirma‡ao Pedido Alteracao Outros Dados"
         CASE ::cOcorrencia == "34"
              ::cDescOcorrencia:="Retirado de Cartorio e Manutencao Carteira"
         CASE ::cOcorrencia == "35"
              ::cDescOcorrencia:="Desagendamento do debito autom tico motivo "+::cRejeicao
         CASE ::cOcorrencia == "68"
              ::cDescOcorrencia:="Acerto dos dados do rateio de Credito"
         CASE ::cOcorrencia == "69"
              ::cDescOcorrencia:="Cancelamento dos dados do rateio"
         OTHERWISE
              ::cDescOcorrencia:=""
      ENDCASE
return ::cDescOcorrencia
Agradeço a ajuda.
Anexos
oRET:cCodBco =  Branci
oRET:cCodBco = Branci
Capturar1.JPG (11.22 KiB) Exibido 1331 vezes
Arquivo que estou tentando ler
Arquivo que estou tentando ler
Capturar.JPG (13.54 KiB) Exibido 1331 vezes
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Não consigo ler arquivo de retorno com HB34+hwgui

Mensagem por gilbertosilverio »

Ola Amigos,

Olhando uns tutoriais do Mestres Quintas, descobri por que não funciona na HB34 e necessário que esteja assim:

Código: Selecionar todos

oRet := oRetorno():NEW( [237], ALLTRIM(@cFILE) )
O duro e que no xhb funciona como estava...

Para uns cabeças de pudim que nem eu, e froide, meio dia de serviço atrasado... kkkkk
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Não consigo ler arquivo de retorno com HB34+hwgui

Mensagem por JoséQuintas »

Pera aí....

Você usa uma função da HWGUI pra retornar o nome do arquivo, o nome do arquivo precisou de AllTrim(), e a culpa é do Harbour 3.4?

Muito provavelmente a função da HWGUI não contém as padronizações do Harbour 3.4, e retorna com o Chr(0) que a API Windows costuma adicionar no final de strings.

Faça o teste se não vai encontrar uma letra a mais contendo Chr(0)...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Não consigo ler arquivo de retorno com HB34+hwgui

Mensagem por gilbertosilverio »

Ola Quintas,

Me desculpe, não soube me explicar...

O alltrim() eu coloquei pra ver se o retorno da hwg_selectfile() não estava retornado com algo a mais, e esqueci de tirar, na postagem da correção.

O por que de não funcionar na hb34 e a falta da oRetorno():New(

No XHB passa desta maneira oRetorno( [237], @cFILE ), ele não precisa do ():new()

Como sou uma anta, faço tudo por tentativa e erro, lendo um post teu, inclui o oRetorno():New() e retornou os dados.

E são essa coisas, que creio que o pessoal vai melhorando, mais que perde a compatibilidade entre as versões.
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Não consigo ler arquivo de retorno com HB34+hwgui

Mensagem por JoséQuintas »

ok. mas também não precisa do @.

Foi comentada essa mudança há muitos anos atrás, de precisar o :New().

E sinceramente... x := Funcao() ou x := Funcao():New()
Fica fácil identificar no fonte que uma é classe e a outra não.
Já pensou... se matar procurando uma function nos fontes... e não é function.....
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder