Jump to content

O que é um arquivo?


joao_o grande
 Share

Recommended Posts

Boa noite,

eu tenho algumas (aliás muitas) dúvidas relativamente aos arquivos.

Do pouco que percebo de arquivos sei que o record regista temporariamente ate o programa se fechar e os arquivos ficam gravados mesmo depois de fechar.

Aqui vão:

(type identificador-do-tipo = file of tipo;)

o que é que é o 'identificador-do-tipo' e o 'tipo'??

o que é que é um arquivo? assemelha-se a uma pasta ou a um documento?

(assign(nome-do-arquivo,'nome-externo')

Li num tutorial qualquer que dizia que era preciso associar o programa pascal ao conteúdo externo! Será isto?

Existem arquivos do tipo texto, binario,.... Quantos e quais existem?

Esta secção dos arquivos é toda muito subjetiva para mim e pedia que quem me esclarece-se compara-se os arquivos com pastas e ficheiros por exemplo.

PS: Para que serve o EoF ?

Edited by joao_o grande
Link to comment
Share on other sites

Boa tarde.

Há aqui algumas noções de hardware a ter em conta.

Quando um programa abre, as suas funções e variáveis são carregadas em memória RAM, a memória temporária que é apagada quando deixa de haver corrente eléctrica. Já os documentos com que trabalhas no dia-a-dia e os próprios sistemas operativos e programas estão guardados de forma permanente no disco rígido.

Em Pascal, e em qualquer outra linguagem, o programa que implementaste está no disco rígido e quando o abres, como referi, tudo o que é necessário ao seu funcionamento - inclusive variáveis - é colocado em memória RAM.

type é uma palavra reservada que te permite definir um novo tipo de dados. Um tipo de dados é uma forma de representar um valor ou conjunto de valores - por exemplo, um número inteiro é do tipo integer.

type TPessoa = record
       nome  : string;
       idade : integer;
    end;

var joao_o_grande : TPessoa;

Um ficheiro (aquilo a que tu chamas arquivo) é um conjunto de dados que se encontram guardados permanentemente no disco rígido. Um programa pode aceder, criar e eliminar ficheiros no disco rígido.

Ora, o Pascal precisa de algo que lhe permita conseguir comunicar com ficheiros. Esse "algo" é uma variável de um tipo de dados especial que cria aquilo que chamamos de stream.

Existem dois tipos de ficheiros:

  1. Ficheiro de texto - contém apenas texto plano (por exemplo, um ficheiro TXT): acedidos com um stream do tipo text:
    var ficheiro : Text;   // stream para um ficheiro de texto
    


  2. Ficheiro binário - contém dados de um determinado tipo de dados: acedidos com um stream do tipo file of tipo_de_dados:
    var f_int : file of integer;   // stream para um ficheiro que contém uma série de inteiros (tipo 'Integer')
       f_num : file of real;      // e este é para um ficheiro de contém números reais (tipo 'Real')
    


    Seguindo o que diz o inglês, este stream diz-te "de caras" o que contém o ficheiro: file of integer lê-se literalmente "ficheiro de inteiros".

Para trabalhar com um ficheiro, tens de "assinar" ao stream o ficheiro com que queres trabalhar:

Assign(ficheiro, 'coisas.txt');   // o stream 'ficheiro' irá manipular o ficheiro de texto "coisas.txt"

Depois há mais funções, como Reset, Rewrite ou Append que definem as funções que irão ser realizadas com o ficheiro.

Por fim, para a tua última questão, eof é a sigla de end of file e é uma função que verifica se chegaste ao fim do ficheiro.

program exemplo;

var ficheiro : Text;

begin
  // Este código lê o conteúdo do ficheiro "coisas.txt" e mostra no ecrã o seu conteúdo, linha-a-linha

  Assign(ficheiro, 'coisas.txt');
  Reset(ficheiro);   // Abre o ficheiro em modo de leitura (read-only)

  while not eof(ficheiro) do begin
     readln(ficheiro, linha);
     writeln(linha);
  end;
  writeln('Fim do ficheiro');

  Close(ficheiro);   // Fechar o stream - obrigatório!
end.

Cumprimentos.

Edited by thoga31
  • Vote 2

Knowledge is free!

Link to comment
Share on other sites

ola,

muito obrigado pela sua resposta (que deve ter dado trabalho) e empenho. No entanto, eu continuo com dúvidas nisso do stream.

Passando à frente, o meu objetivo é fazer um programa com o jogo da roleta e não sei se a zona de declarações é a mais correta a realizar:

Program roleta_casino ;

type jogador = record
		   nome:string [10];
Dinheiro: longint;
rondas_ganhas: integer;
rondas_perdidas:integer;
PIN:string [4];
end;

label Menu, Menu_Consulta, Menu_Jogadores, Menu_N_Jogador, Inicio_Jogo;

var n_a, r, i:byte;
registo : array [1..8] of jogador;
Arquivo : file of registo;
opcao:byte;

Vai haver um menu com consulta de dados, outro para criar o jogador. O array 1 a 8 representa o max de jogadores que é possível registar, ou seja, 8. o Piin vai ser um codigo necessario para jogar. Isto vai ser uma espécie de conta.

Como tenho dados do tipo integer e string qual devo escolher para o ficheiro externo?

Estará isto bem? Se for preciso envio o resto do programa.

Bem,

Aqui vai o programa completo:

Program roleta_casino ;

type jogador = record
		   nome:string [10];
Dinheiro: longint;
rondas_ganhas: integer;
rondas_perdidas:integer;
PIN:string [4];
end;

label Menu, Menu_Consulta, Menu_Jogadores, Menu_N_Jogador, Inicio_Jogo;

var n_a, r, i:byte;
registo : array [1..8] of jogador;
Arquivo : file of registo;
opcao:byte;

Procedure Pinta_Fundo_Letras();
var x,y:byte;
BEGIN		  
 For x:= 0 to 80 do
 Begin
For y:= 0 to 25 do
Begin
  gotoxy (x,y);
  textbackground (lightgreen);
  write (#255);
  textcolor (white);
End;
 End;
END;

Procedure CriaCampo_Num_1a36();

label numeros_6em6,
  Espacos_Conforme_num;
var num, contador_l, contador_c, n_repeticoes:byte;

BEGIN
 clrscr;
 n_repeticoes:=0;
 contador_c:=10;
 contador_l:=5;

 repeat
gotoxy (contador_c, contador_l);
Writeln('|');
contador_l:=contador_l+1;
n_repeticoes:=n_repeticoes+1;
 until n_repeticoes=12;

 n_repeticoes:=0;
 contador_c:=10;
 contador_l:=5;

 repeat
gotoxy(contador_c, contador_l);
Write ('|----|----|----|----|----|----|');
contador_l:= contador_l+2;
n_repeticoes:=n_repeticoes+1;
 until n_repeticoes=7;

 contador_c:=12;
 contador_l:=6;
 num:=1;



 numeros_6em6: repeat
gotoxy (contador_c, contador_l);
If (num>=1) and (num<10) then
begin
  Write (num, '  |');
end
else
begin
  Write(num, ' |' );
end;
contador_c:= contador_c+5;
num:=num+1;
 until (num=7) or (num=13) or (num=19) or (num=25) or (num=31) or (num=37);



 Case num of
 7: begin contador_l:= 8; contador_c:=12; num:=7; goto numeros_6em6; end;
 13: begin contador_l:= 10; contador_c:=12; num:=13; goto numeros_6em6; end;
 19: begin contador_l:= 12; contador_c:=12; num:=19; goto numeros_6em6; end;
 25: begin contador_l:= 14; contador_c:=12; num:=25; goto numeros_6em6; end;
 31: begin contador_l:= 16; contador_c:=12; num:=31; goto numeros_6em6; end;
 end;
END;



Function Escolhe_num_aleatorio(n_a : integer) : integer ;
var i, num, contador_c, contador_l:byte;

Begin
 randomize;
 n_a:=random (35);
 n_a:=n_a+1;
 gotoxy (1,1);

 for i:=1 to n_a do
  begin
If i<10 then
 begin
  gotoxy (12,20);
  Write ('O número escolhido é: 0', i);
  delay (150);
 end
else
begin
  gotoxy(34,20);
Write (i);
delay (150);
end;
  end;	
 Escolhe_num_aleatorio:=n_a;
End;


// Início do programa //

BEGIN
 Pinta_Fundo_Letras();


Repeat	
Menu: ClrScr;
  WriteLn ('Menu - Jogo da Roleta');  
  WriteLn;  
WriteLn ('1. Novo Jogo');  
WriteLn ('2. Novo Jogador');  
WriteLn ('3. Consulta de dados');  
WriteLn ('0. Sair');  
WriteLn;  
Write ('Opcao: '); ReadLn (opcao);
Until (opcao=1) or (opcao=2) or (opcao=3) or (opcao=0);	
Case opcao of  
 1 : begin
  goto Inicio_Jogo;
		end;

   2 : Begin  
			 Menu_n_Jogador: clrscr;
							 Writeln ('Menu < Novo Jogador');
							 Writeln;
  Writeln ('Nº de jogadores a registar:');
  Readln (i);

	for r:=1 to i do
		  begin
	  clrscr;
	  Writeln ('Processo: ',r);
Writeln ('Nome: '); Read (registo[r].nome);
	 Writeln ('Dinheiro: '); registo[r].Dinheiro:=5000; Write(registo[r].Dinheiro);
	Writeln ('PIN (Máx. 4 carcteres): '); Read (registo[r].PIN);
	registo[r].rondas_ganhas:=0;
	registo[r].rondas_perdidas:=0;
	  Writeln ('Registo ',r,' de ',i,' realizado.');
 end;

Writeln;
Writeln ('Press any key to go back to Menu');
goto Menu;
	 End;

  3 : Begin  
		   ClrScr;  
		   WriteLn ('Menu < Consulta de dados');  
		   WriteLn;  
		   Writeln ('Write your name: '); Read (registo[r].nome);
		Writeln;
		Writeln ('Dados:');
		Writeln;
		Writeln ('Processo: ',r);
		Writeln ('Nome: ', registo[r].nome);
		Writeln ('Dinheiro: ',registo[r].Dinheiro);
Writeln ('PIN (Máx. 4 carcteres): ', registo[r].PIN);
Writeln ('Rondas Ganhas: ', registo[r].rondas_ganhas);
Writeln ('Rondas Perdidas: ', registo[r].rondas_perdidas);
readkey;
goto Menu;
   End;  

 0 : Exit;

End;







Menu_Jogadores: clrscr;
		   gotoxy(25,10);
		   Writeln ('--------- Jogador A ----------');
		   gotoxy(25,11);
		   Readln (Jogador_A);
		   Gotoxy (25,13);
			 Writeln ('---------- Jogador B ----------');
		   gotoxy(25,14);
		   Readln (Jogador_B);
		   gotoxy(25,15);
		   Writeln ('------------------------------');
  If Jogador_A=Jogador_B then goto Menu_Jogadores;



Inicio_Jogo: CriaCampo_Num_1a36();



readkey;
END.
Edited by joao_o grande
Tags code + GeSHi
Link to comment
Share on other sites

Eu não vou analisar o programa completo, simplesmente não tenho tempo para isso. Contudo, reparei em algo que me deu sérios arrepios: o uso extensivo de labels e gotos. Jamais em tempo algum o uso que estás a fazer das labels e gotos será positivo. Estás a criar aquilo a que chamamos de código esparguete.

Antes de Pascal, programaste noutra linguagem? Se sim, qual? Se não, quem te ensinou labels e gotos e a programar desta forma?

Por favor, prefere usar procedimentos e funções, inclusive para os menus. Faz uso de passagem de argumentos a estas estruturas e a variáveis locais e não globais.

Acerca dos ficheiros, 1) que dúvidas tens acerca dos streams (sem estas dúvidas esclarecidas não vou tentar explicar aspectos mais específicos e avançados) e 2) o que pretendes guardar no ficheiro?

Se pretendes guardar os dados completos dos jogadores, podes usar isto:

var fich : file of jogador;   // o ficheiro vai guardar os Records inteiros - sim, isto é possível!

Cumprimentos.

  • Vote 1

Knowledge is free!

Link to comment
Share on other sites

eu tbm não pedi para ver tudo. só queria que desse uma olhadela na zona das declarações, tendo em conta os objetivos que eu disse anteriormente.

Eu sei o que é isso dos procedimentos e funções , gosto de usá-los e uso-os. No entanto, aprendi a usar gotos e labels e decidi experimentar ( e olha que até nem deu mau resultado). Também li que usar isso em demasia é prejudicial ao bom funcionamento do programa.

Bem, em relação à segunda questão eu tenho aulas mas não tenho paciência para a velocidade de caracol do stôr e decidi explorar por mim próprio (na net claro). Achei mais giro e interessante. Pascal é a minha primeira linguagem de programação pois sempre ouvi dizer que é o ABC da programação.

1) vou ver o que é isso das streams.

2)o meu objetivo é ter um ficheiro que guarde no máximo informações de oito jogadores, nomeadamente: nome, dinheiro, rondas ganhas, rondas perdidas, código de acesso.

Agora a pergunta é:

Esta zona de declarações é boa para começar afazer isso?

Program roleta_casino ;

type jogador = record
		   nome:string [10];
Dinheiro: longint;
rondas_ganhas: integer;
rondas_perdidas:integer;
PIN:string [4];
end;

label Menu, Menu_Consulta, Menu_Jogadores, Menu_N_Jogador, Inicio_Jogo;

var n_a, r, i:byte;
registo : array [1..8] of jogador;
Arquivo : file of registo;
opcao:byte;

Cumprimentos e obrigado pela dedicação.

Edited by joao_o grande
Link to comment
Share on other sites

No funcionamento do programa as labels e os gotos não apresentam maus resultados, mas o código gerado é péssimo. A utilização destas ferramentas deve ser limitada, sempre que possível, a situações em que náo há qualquer alternativa viável disponível. Menus e submenus são muito facilmente constrídos usando procedimentos e funções encadeados.

Acerca da declaração de variáveis, a tua questão não tem uma resposta definitiva "sim" nem "não". Repara que a programação possibilita imensas formas de resolver o mesmíssimo problema, pelo que as tuas variáveis podem fazer todo o sentido para a abordagem que estás a fazer ao problema, mas ser desaqueado à abordagem que eu ou outra pessoa faria.

Desta forma, eu não posso dizer "sim, está bem" ou o inverso. O máximo que posso dizer é que, dentro do problema apresentado, vejo com agrado a utilização de tipos de dados estruturados (como os records) que são precisamente muito úteis nestas situações. Mais que isto eu não consigo comentar.

Acerca dos ficheiros e, em particular, de streams. Imagina um ficheiro que está no disco rígido como uma conta bancária e o programa é o titular dessa conta bancária. O titular da conta bancária não pode fazer operações na conta sem "algo" no meio que permita esta gestão: vamos considerar aqui, portanto, o gestor de conta.

Essencialmente um stream faz o papel do gestor de conta: quando o programa pretende mexer no ficheiro, fá-lo recorrendo ao stream, da mesma forma que tu fazes operações como criar uma conta a prazo através de um gestor de conta.

Antes de abrires o ficheiro, tens de indicar ao stream qual o ficheiro com que queres trabalhar:

var fich : Text;
// ...
Assign(fich, 'batatas.txt');  // Hey, stream fich!, vou precisar de trabalhar com o ficheiro batatas.txt!

Depois tens de dizer o que pretendes fazer com o ficheiro:

// Olha, eu vou precisar de [escolher um dos seguintes]:
Rewrite(fich);   // Reesecrever todo o ficheiro do zero.
Reset(fich);     // Ler apenas o conteúdo do ficheiro (read-only).
Append(fich);    // Adicionar coisas ao ficheiros.

Desta forma, o stream fich está encarregue de ser o "gestor de conta" do ficheiro "batatas.txt".

Sempre que quiseres ler uma linha do ficheiro "batatas.txt", tens de indicar ao ReadLn o stream:

ReadLn(fich, linha);  // Ler uma linha do ficheiro associado a "fich".

Quando já não precisas de trabalhar mais com o ficheiro, "libertas" o stream das suas funções:

Close(fich);

É extremamente importante abrir e fechar os streams pois são eles que selam os ficheiros de serem alterados por outros programas enquanto o nosso programa trabalha com eles! Além disso, sem os streams devidamente abertos, é impossível trabalhar com um ficheiro.

Uma curiosidade: o teclado e o monitor têm streams próprios, mas eles estão "ocultos"! Quando escrevemos...

WriteLn('Linha de texto');

... estamos, na realidade, a fazer isto:

WriteLn(output, 'Linha de texto');

Onde output é o stream que gere a colocação de dados no monitor.

Em 1971 tínhamos de declarar obrigatoriamente estes streams:

program coisas (input, output);

Mas hoje em dia isso é totalmente arcaico.

Um stream é um canal através do qual o programa vai realizar operações I/O (input/output, entrada/saída de dados). Se queres escrever dados num ficheiro, tens de indicar qual o "canal" (o stream) que o programa deverá usar para o fazer. Daí a importância de abrir e fechar os streams: é necessário abrir o canal quando necessitamos dele e fechá-lo no final!

Espero que isto ajuda numa melhor compreensão dos streams.

Nota: Tipicamente os professores nunca falam do conceito de streaming em Pascal, mas eu sou da opinião que é importante saber este conceito para que se compreenda devidamente a necessidade de todos aqueles métodos (Assign, Reset, Rewrite, Close, etc...).

Cumprimentos.

  • Vote 1

Knowledge is free!

Link to comment
Share on other sites

Permitam-me só fazer 2 Obs,

eu tbm não pedi para ver tudo. só queria que desse uma olhadela na zona das declarações, tendo em conta os objetivos que eu disse anteriormente.

Eu sei o que é isso dos procedimentos e funções , gosto de usá-los e uso-os. No entanto, aprendi a usar gotos e labels e decidi experimentar ( e olha que até nem deu mau resultado). Também li que usar isso em demasia é prejudicial ao bom funcionamento do programa.

Convém dizer que o GotoXY, nada tem a haver com o Goto ou Label. Quando muito a tradução da palavra, o GoToXY, vai para um sitio no ecran e o GoTo para um sitio no código.

Em relação à utilização deles, 1 já é demais 🙂

Tentando não complicar... Quando corres um programa, existe uma coisinha que se chama cursor, que vai correndo todas as linhas de código que escreveste desde o inicio e executando o programa, mas de forma predefinida. Por exemplo, ele sabe que quando executas um Procedimento ou uma Função, ainda que de maneiras diferentes, ele executa o que tem para executar, mesmo que dentro destes execute outros, mas irá sempre voltar ao ponto onde alterou o percurso.

Quando Inseres um GoTo, estás a alterar esse percurso e a maneira predefinida de execução, de forma propositada, que pode levar a perda de localização do mesmo. 🙂 ... Podes imprimir o código e seguir com a ponta da caneta desde o inicio para ver o efeito 🙂

Imagina que tens um Rio a correr, e fazes uma desvio(para fazer algo) que vai desaguar a esse mesmo rio(Procedure, Function), é bem diferente de abrires um Canal(GoTo) para ir ter a um lago(para fazer algo) e depois teres de abrir outro canal para voltar a ir ter ao Rio (GoTo) 🙂 ...

Bem, em relação à segunda questão eu tenho aulas mas não tenho paciência para a velocidade de caracol do stôr e decidi explorar por mim próprio (na net claro). Achei mais giro e interessante. Pascal é a minha primeira linguagem de programação pois sempre ouvi dizer que é o ABC da programação.

Isto é muito bom 👍 ... Em 20 alunos, normalmente uma turma, torna-se complicado mesmo que os Professores queiram, gerir a "velocidade" com que se dá a matéria, porque haverá sempre alguém que gostaria que se fosse mais devagar e sempre alguém que gostaria que se fosse mais rápido... O importante é fazeres o que fizeste. Quem quiser aprender mais, e mais rápido, procurar outras formas de o fazer. Parabéns e continua o bom trabalho 🙂

Edited by CrominhO
  • Vote 1

As mentes humanas são realmente um local estranho!

Link to comment
Share on other sites

Obrigado aos dois!!

Thoga31, fiquei muito mais esclarecido, mas agora tenho de pesquisar mais um pouco para clarificar tudo a 100%

então um stream pode abrir mais do que um ficheiro record desde que sejam do mesmo tipo (ambos integer, por exemplo)?

CrominhO, obrigado pelo esclarecimento! Eu sei que não se deve usar goto e tento não usar, mas é como um fumador que quer deixar de fumar... "Só mais um...Só mais um..." !!!!!

Outra duvida:

è possivel escrever isto:

Gotoxy (5,5);
Writeln ('ola');

de maneira mais abreviada?

Edited by joao_o grande
Link to comment
Share on other sites

Um stream pode aceder a mais que um ficheiro que guarda informação do tipo de dados com o qual está preparado para trabalhar. Ou seja, um stream que leia ficheiros com dados do tipo Double poderá abrir qualquer ficheiro deste género.

Contudo, e acho que é aqui que está a tua dúvida, um stream só pode trabalhar com um ficheiro de cada vez.

Portanto, para usar o mesmo stream em dois ficheiros diferentes, tens de fechar primeiro a "sessão" no primeiro para poder "abrir" o segundo, like so:

Assign(f, 'cebolas.txt');
Reset(f);
// whatever...
Close(f);

Assign(f, 'batatas.txt');
Rewrite(f);
// whatever again...
Close(f);

Não podes fazer Assign a um stream que já esteja a trabalhar com um ficheiro.

Se precisas de trabalhar com mais que um ficheiro ao mesmo tempo, irás necessitar de tantos streams quantos os ficheiros que deverão estar abertos no mesmo momento.

è possivel escrever isto:

Gotoxy (5,5);
Writeln ('ola');

de maneira mais abreviada?

Para isso existem procedimentos e funções: para sistematizar tarefas repetitivas.

Portanto, que tal criares um procedimento para o efeito? 😉

Edited by thoga31

Knowledge is free!

Link to comment
Share on other sites

Outra duvida:

è possivel escrever isto:

Gotoxy (5,5);
Writeln ('ola');

de maneira mais abreviada?

Usando um procedimento assim:

Procedure EscreveXY (var x,y:integer, var s:string);
begin
 gotoxy(x,y);
 write(s);
end;

....

//em qualquer parte do programa apenas tens de escrever o que queres
EscreveXY(5,5,"Olá");
EscreveXY(6,7,"...e olá outra vez");

Se queres embelezar mais a coisa então podes-lhe dar cor:

Procedure EscreveCorXY (var CorFundo,CorTexto:byte; var x,y:integer, var s:string);
begin
 TextBackground(CorFundo);
 TextColor(CorTexto);
 gotoxy(x,y);
 write(s);
end;

....

//em qualquer parte do programa apenas tens de escrever o que queres
EscreveCorXY(Red,Yellow,3,5,"Fundo vermelho letras amarelas");
EscreveXY(Blue,White,3,8,"Fundo azul letras brancas");
Link to comment
Share on other sites

Se ele não souber um q é um procedural não vai perceber patavina dos exemplos, caso contrário pode ser que lhe desbloqueie alguma barreira q possa ter neste conceito. No início pode haver dificuldades q nos parecem triviais, foi nesse sentido q deixei o código.

Acho que as questões colocadas pelo @pwseo iam nesse sentido - perceber o conhecimento do OP e, conforme esse mesmo, explicar os conceitos subjacentes com exemplos adequados - é o que fazemos há mais de 5 anos.

"Não dês o peixe, ensina a pescar."

Edited by thoga31

Knowledge is free!

Link to comment
Share on other sites

ola,

Sabes o que é, para que serve, e como se cria um procedure? Se conseguires responder a estas 3 questões, saberás o que fazer.

sim, sei o que é e também sei usar os parametros de um procedure.

Usando um procedimento assim:

Procedure EscreveXY (var x,y:integer, var s:string);
begin
 gotoxy(x,y);
 write(s);
end;

....

//em qualquer parte do programa apenas tens de escrever o que queres
EscreveXY(5,5,"Olá");
EscreveXY(6,7,"...e olá outra vez");

Se queres embelezar mais a coisa então podes-lhe dar cor:

Procedure EscreveCorXY (var CorFundo,CorTexto:byte; var x,y:integer, var s:string);
begin
 TextBackground(CorFundo);
 TextColor(CorTexto);
 gotoxy(x,y);
 write(s);
end;

....

//em qualquer parte do programa apenas tens de escrever o que queres
EscreveCorXY(Red,Yellow,3,5,"Fundo vermelho letras amarelas");
EscreveXY(Blue,White,3,8,"Fundo azul letras brancas");

Obrigado por me esclareceres aquilo do Gotoxy, realmente é mt mais abreviado.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.