Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.05.20;
Скачать: [xml.tar.bz2];

Вниз

Чтение многострочного ключа ini-файла   Найти похожие ветки 

 
Kostafey ©   (2007-04-27 17:25) [0]

Подкажите пожалуйста существует ли возможность чтения/записи многстрочных ключей ini-файлов ?
Т.е. что бы вместо

[section1]
key1="жили у бабуси 2 веселых гуся"
key2=...

можно было писать:

[section1]
key="жили у
    бабуси 2
    веселых
    гуся"
key2=...


 
tesseract ©   (2007-04-27 17:27) [1]

существует, измени ко конечного автомата у TIniFile


 
clickmaker ©   (2007-04-27 17:38) [2]

Stream := TStringStream.Create(MultiLineText);
IniFile.WriteBinaryStream("Section1", "key", Stream);


 
Loginov Dmitry ©   (2007-04-27 17:47) [3]

Если так нужно, чтобы в инишке хранился многострочный текст, то можно записать его в виде одной строки:
Ini.WriteString("section1", "key1",
 StringReplace(S, sLineBreak, "\n", [rfReplaceAll]));

Читать так:
S := StringReplace(Ini.ReadString("section1", "key1", ""), "\n", sLineBreak, [rfReplaceAll]);

Но учти, что длина строки в ини ограничена и не может быть больше 2048 символов. Если не хочешь иметь проблем с подобными ограничениями, используй TMemIniFile.


 
Kostafey ©   (2007-04-27 18:19) [4]

> существует, измени ко конечного автомата у TIniFile

А как?


> Stream := TStringStream.Create(MultiLineText);

К сожалению не приходилось еще иметь дело с потоками.
Как же правильно считать данные?

 IniFile.ReadBinaryStream("Section1", "key", Stream);
 Stream.Position:=0;
 Showmessage(Stream.ReadString(100));

Выдает набор символов


> [3] Loginov Dmitry ©   (27.04.07 17:47)

Вообще, но я хотел иметь возможность ручного редактирования ini,
а при таком подходе это не удобно.

> ини ограничена и не может быть больше 2048 символов.

В справке упоминаний об этом я не видел, похоже действительно
нужно работать с TMemIniFile. Спасибо.


 
clickmaker ©   (2007-04-27 18:20) [5]


> IniFile.ReadBinaryStream("Section1", "key", Stream);

ShowMessage(Stream.DataString);


 
Kostafey ©   (2007-04-27 18:29) [6]

> [5] clickmaker ©   (27.04.07 18:20)

Пробую для однострочного варианта:

var
 ttstr:string;
...
Stream := TStringStream.Create(ttstr);
IniFile.ReadBinaryStream("Section1", "key", Stream);
ShowMessage(Stream.DataString);

Выдает:
юp-
p-
p-
p-
p-
p-
p-
p-
p-
p-


 
clickmaker ©   (2007-04-27 18:42) [7]

при чтении
Stream := TStringStream.Create("");

и как записываешь?


 
Kostafey ©   (2007-04-27 18:50) [8]

> и как записываешь?

А пока пытаюсь просто прочесть:

 Stream := TStringStream.Create("");
 IniFile.ReadBinaryStream("Query0", "SQL", Stream);
 ShowMessage(Stream.DataString);

Реальное содержание ini-файла:

[Query0]
sql="Select * from Dogovor, Subject where Dogovor.D_S_id = Subject.S_id"

И выдает [6]

Если просто

ShowMessage(IniFile.ReadString("Query0", "SQL", ""));

то все OK


 
Kostafey ©   (2007-04-27 20:22) [9]

Вот так да.
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=fileini&id=10302
не работает.
Строки загружаются пустые.


 
clickmaker ©   (2007-04-28 15:14) [10]


> [8] Kostafey ©   (27.04.07 18:50)

ну ё... чтобы прочесть как двоичный поток, данные и записаны должны быть как двоичный поток
Ты уж определись


 
Kostafey ©   (2007-04-28 16:45) [11]

> ну ё... чтобы прочесть как двоичный поток, данные и записаны
> должны быть как двоичный поток
> Ты уж определись

Ну да, по поводу [8] Kostafey © я молчу - глупость.

А если даже и запись потока делать - тоже самое получается.
В http://kladovka.net.ru/delphibase/?action=viewfunc&topic=fileini&id=10302
как раз такой пример приводится. И он не работает.

Вообще, идея несколько в другом. Я хотел чтобы ini-файл можно было бы читать и
вручную (по F4). Если файл, становится нечитаемым в ручном режиме,
то разницы нет, можно и как [3] Loginov Dmitry ©   (27.04.07 17:47)
предложил сделать.

Или уж вообще тогда читать файл не как ini, а в двоичном режиме,
если, конечно нет лучших вариантов?


 
clickmaker ©   (2007-04-28 17:39) [12]


> А если даже и запись потока делать - тоже самое получается.


вот так делаешь?

procedure TForm1.Button1Click(Sender: TObject);
var
 IniFile: TIniFile;
 Stream: TStringStream;
begin
 IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, ".ini"));
 Stream := TStringStream.Create(Memo1.Text);
 try
   IniFile.WriteBinaryStream("Section1", "key", Stream);
 finally
   IniFile.Free;
   Stream.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 IniFile: TIniFile;
 Stream: TStringStream;
begin
 IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, ".ini"));
 Stream := TStringStream.Create("");
 try
   IniFile.ReadBinaryStream("Section1", "key", Stream);
   Memo2.Text := Stream.DataString;
 finally
   IniFile.Free;
   Stream.Free;
 end;
end;


 
Kostafey ©   (2007-04-28 20:16) [13]

> [12] clickmaker ©   (28.04.07 17:39)

Пример [12] работает.
Теперь понял в чем ошибка.
Если вместо TIniFile использовать TMemIniFile, то при записи потока
(неважно TStringStream или TMemoryStream) ничего записано не будет.
Вообще.

При использовании TIniFile - для записи, TMemIniFile - для чтения все
работает хорошо.
Будет ли существовать в таком случае при записи с использованием TIniFile
ограничение в 2048 символов ?


 
Ketmar ©   (2007-04-28 20:21) [14]

берём Lua. используем. получаем помимо читабельных инишек ещё и скриптовый язык задаром. %-)


 
Kostafey ©   (2007-04-28 20:27) [15]

> [14] Ketmar ©   (28.04.07 20:21)

Lua, lua... что-то знакомое.
Не приходилось пользоваться. Не подскажете где документацию по нему поискать ?

З.Ы. Google, Yandex уже шуршат...


 
Ketmar ©   (2007-04-28 20:36) [16]

http://www.lua.org/

правда, оно щаз на maintenance. в понедельник поднимется. там и исходники, и доки, и ссылки, и вообще много вкусного. только вменяемого модуля для Delphi/FPC нет. у меня свой. тоже кривой. %-)


 
Kostafey ©   (2007-04-28 20:55) [17]

Жесть, это же целый скриптовый язык.

Несомненно, он применим сам по себе, но что ж такого особенного
в нем, что позволяет использовать его для хранения небольшого количества информации?

Если использовать средства Lua, то это ж надо искать соотвествующие примеры
кода/компоненты для Delphi.
А если их не использовать, то игра и свеч не стоит.

а к нему еще и интерпритатор устанавливать надо


 
Loginov Dmitry ©   (2007-04-28 21:34) [18]

> Будет ли существовать в таком случае при записи с использованием
> TIniFile
> ограничение в 2048 символов ?


Вообще нет ограничения на длину строки при записи. Такое ограничение действует только при чтении.


 
Ketmar ©   (2007-04-28 22:11) [19]

> Kostafey © (28.04.07 20:55) [17]
> Жесть, это же целый скриптовый язык.

угу. и очень изящный, к тому же. и очень быстрый.
у меня на pIII/600 конфиги объёмом в 200-300 кил читает практически мгновенно. %-)

> Несомненно, он применим сам по себе, но что ж такого особенного
> в нем, что позволяет использовать его для хранения небольшого
> количества информации?

а ничего особенного. просто красиво и удобно. и на халяву встроеный язык получаешь. %-)
опять же -- инкрементальный GC. халявная структуризация конфигов (а реализация ассоциативных массивов в Lua ОЧЕНЬ шустрая).

я за своим более-менее большим софтом заметил такую тенденцию: со временем всё больше функционала мигрирует из Delphi/C в Lua. на Lua удобно "прототипировать" новый код -- быстро отлаживается (есть отличная штука -- ldb: отладчик Lua на самой Lua, похож на gdb; монтируем в программу консоль (можно и по telnet"у общаться тогда %-) -- и отладка в руках; без перекомпиляции). а когда отлажено -- как-то уже и лениво переводить на "родной" язык. так и остаётся на Lua.

> Если использовать средства Lua, то это ж надо искать соотвествующие
> примеры кода/компоненты для Delphi.
> А если их не использовать, то игра и свеч не стоит.

нифига. там настолько простое и внятное API, что достаточно почитать мануал и примеры на C. а модулем для Delphi/FPC я могу поделиться, нет проблем. и простыми примерами тоже. и примерами создания библиотек расширения в виде .DLL или сразу в своём коде.

> а к нему еще и интерпритатор устанавливать надо
одна DLL, размером менее 200 килобайт. в принципе -- можно извратиться и собрать на BCC как набор .obj, после чего и DLL не нужна будет.


 
Ketmar ©   (2007-04-28 22:12) [20]

вдогон: вообще, Lua родилась именно как язык для конфигов. а потом уже "повзрослела". %-)


 
Kostafey ©   (2007-04-29 00:05) [21]

> Вообще нет ограничения на длину строки при записи. Такое
> ограничение действует только при чтении.

Спасибо, а  что же действительно запись в поток TMemIniFile невозможна ?


> на pIII/600 конфиги объёмом в 200-300 кил читает практически
> мгновенно

Впечатляет !


> я за своим более-менее большим софтом...

Функционал в скрипте? Гм. Вы меня заинтересовали.


> нифига. там настолько простое и внятное API, что достаточно
> почитать мануал и примеры на C. а модулем для Delphi/FPC
> я могу поделиться, нет проблем. и простыми примерами тоже.
> и примерами создания библиотек расширения в виде .DLL или
> сразу в своём коде.

Вы говорите о FPC, имеется в виду Lazarus?
Что касается модуля... модуля от Ketmar"a??? Я ж в нем буду до 2-го пришествия разбираться.
Впрочем, если не сложно, отправьте пожалуйста какие-нибудь простые примеры записи/чтения
конфигоподобных файлов Lua.

С dll я работал. Как на СPP, так и Delphi, так что все равно для dll или exe код.
А вот с obj иметь дело не доводилось, так что разберусь я в этом навряд ли.

<offtop>
помниться в старой инфе у вас было сказано что-то вроде:
"не люблю, когда говорят спасибо"
</offtop>

P.S. Документации немного набрал. Буду разбираться.


 
Ketmar ©   (2007-04-29 00:24) [22]

> Kostafey © (29.04.07 00:05) [21]
> Функционал в скрипте? Гм. Вы меня заинтересовали.

а отчего бы и да? %-) удобно, гибко настраивается и вообще здорово.

> Вы говорите о FPC, имеется в виду Lazarus?
нет. имея в виду FPC. ибо модуль -- он просто wraper для DLL/so. я ведь и в консольном/WinAPI/Linux libc софте использую Lua. %-)

собственно, я вообще сейчас достаточно много мелкого утиля пишу на "чистом" Lua (с допбиблиотеками %-). имея биндинги к сокетам, GTK и прочим вкусностям можно не заморачиваться всякими сями и паскалями. %-)

более того, для Lua есть LuaJIT. который добавляет к .DLL где-то 50-60 кил, но скорость увеличивает ощутимо. и не накладывает никаких ограничений на язык. только не знаю, портанул ли его SuperMike под 5.1.2.

> Что касается модуля... модуля от Ketmar"a??? Я ж в нем буду
> до 2-го пришествия разбираться.

неа. это straightforward трансляция сишных хидеров.

> Впрочем, если не сложно, отправьте пожалуйста какие-нибудь
> простые примеры записи/чтения
> конфигоподобных файлов Lua.

надо тогда напомнить мне завтра в аську -- 43443522. накропаю.

на самом деле если учитывать, что у меня обычно (как я и говорил) масса функционала непосредственно на Lua сделана, то многие конфиги в самих скриптах и используются, до "родного" кода не добираясь. %-)

но я поищу -- была где-то софтинка, которая читает "структурированые" конфиги и потом их можно получиать при помощи функций типа CfgGetIntKey("server.proxy.port");.

хотя потом я перешёл к варианту, который разбирает конфиг сам (Lua-скрипт) и настраивает софтину при помощи всяких штук типа SetProxyPort(8080); из самого скрипта.

а потом и вовсе к server.proxy.port = 8080;, что автоматически вызывает SetProxyPort(8080) в "родном" коде. и, соотвтетсвенно, print(server.proxy.port); вызывает GetProxyPort();. и опять получается конфиг в виде plain text. %-)

> С dll я работал. Как на СPP, так и Delphi, так что все равно
> для dll или exe код.

я имел в виду пример использования API и оформления DLL так, чтобы Lua его поняла как внешний модуль и подключила при помощи require "module". оно с первого раза не совсем "прозрачно".

> А вот с obj иметь дело не доводилось, так что разберусь
> я в этом навряд ли.

Lua без напильника собирается при помощи BCC. в DLL. %-) а отсюда уже не так далеко до просто .obj и {$LINK xxx.obj}. только пару стандартных Lua-библиотек придётся написать на Delphi, чтобы не тянуть с собой C runtime.

"не люблю, когда говорят спасибо"
само слово. от благодарностей в виде tnx и спиртосодержащих не отказываюсь. %-)

P.S. Документации немного набрал. Буду разбираться.
если что -- можно стукать в асю. при нужде попытаюсь пинком задать верное направление. %-)


 
Kostafey ©   (2007-04-29 01:05) [23]

> нет. имея в виду FPC. ибо модуль -- он просто wraper для
> DLL/so. я ведь и в консольном/WinAPI/Linux libc софте использую
> Lua. %-)

понял... с 4-го прочтения...


> собственно, я вообще сейчас достаточно много мелкого утиля
> пишу на "чистом" Lua (с допбиблиотеками %-). имея биндинги
> к сокетам, GTK и прочим вкусностям можно не заморачиваться
> всякими сями и паскалями. %-)

Тоже понял. Пока мне это ни к чему.


> straightforward трансляция сишных хидеров

Ну с таким же успехлм мне можно было написать
Заджикали заджикали Все тенали бороговы (с)Льюис Кэрролл
не понял ни слова. :)


> надо тогда напомнить мне завтра в аську -- 43443522. накропаю.

OK


> но я поищу -- была где-то софтинка, которая читает "структурированые" конфиги и потом их можно получиать при помощи функций типа > CfgGetIntKey("server.proxy.port");.

Было бы здорово. Но это ж нужно незнамо как настраивать пользовательскую машину при установке.


> хотя потом я перешёл к варианту, который разбирает конфиг
> сам (Lua-скрипт) и настраивает софтину при помощи всяких
> штук типа SetProxyPort(8080); из самого скрипта.
>
> а потом и вовсе к server.proxy.port = 8080;, что автоматически
> вызывает SetProxyPort(8080) в "родном" коде. и, соотвтетсвенно,
> print(server.proxy.port); вызывает GetProxyPort();. и опять
> получается конфиг в виде plain text. %-)

Ох да. я даже в Delphi не знаю как это делается.


> я имел в виду пример использования API и оформления DLL
> так, чтобы Lua его поняла как внешний модуль и подключила
> при помощи require "module". оно с первого раза не совсем
> "прозрачно".

Как впрочем и со второго :)


> само слово. от благодарностей в виде tnx и спиртосодержащих
> не отказываюсь. %-)

Первое не знаю что такое, а что касается вторго, то все зависит в каком городе
вы находитесь/будете находится :))).


> при нужде попытаюсь пинком задать верное направление. %-)

Тоже правильно :)


 
Ketmar ©   (2007-04-29 01:18) [24]

> Kostafey © (29.04.07 01:05) [23]
> не понял ни слова. :)
просто перевод заголовочного файла с импортами из DLL. с сей на паскаль.

> Было бы здорово. Но это ж нужно незнамо как настраивать
> пользовательскую машину при установке.

положить lua5.dll в тот же каталог, где твоя софтина лежит. %-)

а дефолтные конфиги должны идти с софтиной. или она должна уметь их делать сама.

> Ох да. я даже в Delphi не знаю как это делается.
классами и свойствами. %-)

> Первое не знаю что такое
tnx==thanx==thank you.


 
Kostafey ©   (2007-04-29 01:33) [25]

> положить lua5.dll в тот же каталог, где твоя софтина лежит.
> %-)

Да я про настройку прокси сервера. Хорошо бы без этого.
Вдруг у них уже сеть есть.

Кто говорит что у них есть, кто нет, никто ничего не понимаент,
а почтой однако пользуются, мда... без комментариев...

> а дефолтные конфиги должны идти с софтиной. или она должна
> уметь их делать сама.

это-то само собой


> классами и свойствами. %-)

А, черный юмор ;]


 
Ketmar ©   (2007-04-29 02:20) [26]

да я пример с прокси так привёл, "с потолка". с проксей -- это вообще куски из in-house проекта. %-)


 
Kostafey ©   (2007-04-30 21:04) [27]

Ситуация такая.

Компиляция.

При обработке строк .bat - файла, например:
cl /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DLUA_BUILD_AS_DLL l*.c
выдает: Программа не умещается в памяти.

Ну да ладно, скомпилоровалось в Visual Studio 2005.
Скомпилировался файл lua5.1.dll, а lua51U.pas просит lua51.dll.
ну да ладно lua51.dll есть в любой готовой компиляции.
Запускаем приложение на Delphi - просит msvcr80d.dll.
Ищем msvcr80d.dll - их куча.
Подходящая в C:\Program Files\Microsoft Visual Studio 8\VC\ce\Dll\x86\.
Запускаем - просит CORE.dll. Находим CORE.dll, запускаем - все рушится (не найдена такая-то строка в CORE.dll).

Ладно, есть готовые компиляции всей библиотеки. Например, lua5_1_2_Win32_dll7_lib.zip.
Берем от туда lua5.1.dll и lua51.dll - все, приложение работает.
Вопрос: на другом PC понадобятся какие-либо еще библиотеки помимо этих двух ?

Что до самого Lua.
Я хотел бы хранить там информацию типа:

#Sql.lua

--Количество запросов
Count=1

--Список запросов
Query_1 = {}
Query_1.Name="Запрос №1"
Query_1.SQL=[[
Select *
From Dogovor, Subject
Where ?Param_1 and ?Param_2
 and Dogovor.D_S_id = Subject.S_id"
]]
--
Query_1.Params={}
Query_1.Params.Count=2
Query_1.Params.Param_1={}
Query_1.Params.Param_1.Name="Data"
Query_1.Params.Param_1.FieldName="Dogovor.Data"
Query_1.Params.Param_1.Operation="between"
Query_1.Params.Param_1.Operand1=""
Query_1.Params.Param_1.Operand2=""
--
Query_1.Params.Param_2={}
Query_1.Params.Param_2.Name="Familiya"
Query_1.Params.Param_2.FieldName="Subject.Familiya"
Query_1.Params.Param_2.Operation="="
Query_1.Params.Param_2.Operand1=""

Получается по-другому ее не записать (структур я в языке не нашел) ?

Обработка команд
Вот что непонятно:

procedure TForm1.Button4Click(Sender: TObject);
var LuaS: PLuaState;
begin
 LuaS := lua_open();
 showmessage(inttostr(luaL_dostring(LuaS, "print(print("Hellow World"))")));
end;

Выводит в диалоге "2".
В модуле lua51U.pas: LUA_ERRRUN    = 2;
Как мне кажется вернуть он наверное должен 0, и на консоль вывести Hellow World ?

Считывание из файла
API довольно непривычный. Получается, чтобы считать из файла нужно сначала записть
в стек, а затем считывать в программу.

Если с переменными все OK:

LuaS := lua_open();
luaL_dofile(LuaS, ExtractFilePath(Application.ExeName) + "\sql.lua");
lua_getglobal(LuaS, "Count");
ShowMessage(lua_tostring(LuaS, 1));

То как привильно считывать таблицы я так и не понял.

lua_gettable на сколько я понял передает таблицу в стек. Но какую и как потом из нее извлекать значения ?


 
Kostafey ©   (2007-04-30 21:11) [28]

> showmessage(inttostr(luaL_dostring(LuaS, "print(print("Hellow > World"))")));

showmessage(inttostr(luaL_dostring(LuaS, "print("Hellow World")")));


 
Ketmar ©   (2007-04-30 21:59) [29]

барин, не надо извращений. %-)

>Скомпилировался файл lua5.1.dll, а lua51U.pas просит lua51.dll.
для кого в .pas константа сделана с именем библиотеки?

>Вопрос: на другом PC понадобятся какие-либо еще библиотеки помимо этих двух ?
собери нормально. или скачай вменяемую. нужна только одна -- lua*.dll.

>Получается по-другому ее не записать (структур я в языке не нашел) ?
таблицы -- это и массивы, и структуры, и классы, и словари и ещё много чего. да. %-)

а зачем тебе Params.Count? массивы -- они и числовые индексы принимают. если начинать с 1, то длина массива -- #<var>. и никаких ручных _1, _2, ...

>Выводит в диалоге "2".
и что неясно? медитируем:
print(print("zzz"));
кто тебе наврал, что print() возвращает какой-то результат? напиши так: WriteLn(WriteLn("text"));. не удивительная ли конструкция? %-)

>Получается, чтобы считать из файла нужно сначала записть
в стек, а затем считывать в программу.

да. для чего делается функция-"обёртка". один раз. и потом весело юзается.

>То как привильно считывать таблицы я так и не понял.
искать в районе lua_getfield(). которую применять на table в стеке. %-)
а lua_gettable() -- это для нумерованых индексов в таблице. внимательно кури мануал, там всё написано. %-)


 
Ketmar ©   (2007-04-30 22:00) [30]

пардон. забыл тэг закрыть. %-)


 
Kostafey ©   (2007-04-30 22:24) [31]

> напиши так: WriteLn(WriteLn("text"));. не удивительная ли
> конструкция? %-)

Я ж исправился: [28] Kostafey ©   (30.04.07 21:11):
showmessage(inttostr(luaL_dostring(LuaS, "print("Hellow World")")));


> кто тебе наврал, что print() возвращает какой-то результат?

Результат возвращает не print, а luaL_dostring - успешно/неуспешно.

По поводу таблиц попробую еще с мануалом поколдовать...


 
Kostafey ©   (2007-04-30 23:36) [32]

все же не понятно:

void lua_gettable (lua_State *L, int index); - Pushes onto the stack the value t[k]
получается, что мы читаем значение [k] из таблицы, которая уже должна находится в стеке

А как же таблицу в стек помещать ? lua_pushtable - то нет

void lua_getfield (lua_State *L, int index, const char *k); - Pushes onto the stack the value t[k]
Опять получается поже самое, только для ассоциативного массива.

Саму таблицу-то как загружать ?


 
Kostafey ©   (2007-05-01 14:09) [33]

> [32] Kostafey ©   (30.04.07 23:36)

Все, разобрался.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.05.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.043 c
2-1177570386
Ega23
2007-04-26 10:53
2007.05.20
property в interface


2-1177533362
Gambler131221
2007-04-26 00:36
2007.05.20
COlor


2-1177022043
Германн
2007-04-20 02:34
2007.05.20
Непонятки с OnResize


15-1177340432
oldman
2007-04-23 19:00
2007.05.20
По мотивам веток про Гитлера и про Ельцина...


2-1177444555
tigraman
2007-04-24 23:55
2007.05.20
IdTCPClient





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский