Заголовок сообщения: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 12:09 [quote="Prof1983"]При реализации AIKernel столкнулся с проблемой передачи строк в виде параметров между модулями. Есть несколько вариантов: char* (PChar), string (класс Си++), string (массив символов с указанием длины). Но строки в разных компиляторах реализованы по разному. Кроме PChar, но при использование PChar не очень удобное и могут возникать проблемы, если в строке присутствуют нулевые символы. Поэтому я решил передачу строк реализовать так же как это сделано в GTK. А именно использовать структуру: [code]type AString_Type = packed record Str: PWideChar; Len: AInteger; end;[/code]или[code]struct AString_Type { wchar* Str; int Len; }[/code]При этом строки реализовывать с WideChar, а не с Char. Хотелось бы узнать мнение других программистов на этот счет.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 17:58 [quote="victorst"]http://ru.wikipedia.org/wiki/Base64 как один из вариантов. Тогда можно смело пользоваться нуль-терминальной строкой. И еще - желательно UTF8 строками обмениваться: UTF8->Base64->канал связи->Base64->UTF8[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 18:15 [quote="Prof1983"][quote="victorst"]http://ru.wikipedia.org/wiki/Base64 как один из вариантов. Тогда можно смело пользоваться нуль-терминальной строкой. И еще - желательно UTF8 строками обмениваться: UTF8->Base64->канал связи->Base64->UTF8[/quote] Идея интересная. Для передачи данных по сети или для сокрытия данных подойдет. Но для передачи строки, как параметров функции будут слишком большие накладные расходы времени на кодирование/раскодирование строки. По этой же причине UTF-8 не подходит. Для хранения информации UTF-8 хороший формат, а для работы внутри программы UTF-8 лучше переводить в формат с одинаковым размером на каждый символ. Хм... Кстати. Интересный вопрос всплыл, ответ на который я не знаю. А wchar_t - это двухбайтовый символ. А какой это стандарт? UTF-16?[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 18:25 [quote="Prof1983"][quote]Таким образом, первая версия Юникода представляла собой кодировку с фиксированным размером символа в 16 бит, то есть общее число кодов было 216 (65 536). Отсюда происходит практика обозначения символов четырьмя шестнадцатеричными цифрами (например, U+0410). При этом в Юникоде планировалось кодировать не все существующие символы, а только те, которые необходимы в повседневном обиходе. Редко используемые символы должны были размещаться в «области пользовательских символов» (private use area), которая первоначально занимала коды U+D800…U+F8FF. Чтобы использовать Юникод также и в качестве промежуточного звена при преобразовании разных кодировок друг в друга, в него включили все символы, представленные во всех наиболее известных кодировках. В дальнейшем, однако, было принято решение кодировать все символы и в связи с этим значительно расширить кодовую область. Одновременно с этим, коды символов стали рассматриваться не как 16-битные значения, а как абстрактные числа, которые в компьютере могут представляться множеством разных способов (см. Способы представления).[/quote] [url=http://ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4]ru.wikipedia.org[/url] Интересно еще как реализовано хранение строк в Java и в C#. На сколько мне известно там строки хранятся в виде последовательности двухбайтовых символов. Где каждый первый байт символа указывает кодовую страницу, а второй байт - символ.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 18:52 [quote="Prof1983"][quote]В Microsoft Windows NT и основанных на ней системах Windows 2000 и Windows XP в основном используется форма UTF-16LE. В UNIX-подобных операционных системах GNU/Linux, BSD и Mac OS X принята форма UTF-8 для файлов и UTF-32 или UTF-8 для обработки символов в оперативной памяти.[/quote] [quote]В операционных системах семейства Windows NT для внутреннего представления имён файлов и других системных строк используется двухбайтовая кодировка UTF-16LE. Системные вызовы, принимающие строковые параметры, существуют в однобайтном и двухбайтном вариантах. Подробнее см. в статье Юникод в операционных системах Microsoft. UNIX-подобные операционные системы, в том числе GNU/Linux, BSD, Mac OS X, используют для представления Юникода кодировку UTF-8. Большинство программ могут работать с UTF-8 как с традиционными однобайтными кодировками, не обращая внимания на то, что символ представляется как несколько последовательных байт. Для работы с отдельными символами строки обычно перекодируются в UCS-4, так что каждому символу соответствует машинное слово. Одной из первых успешных коммерческих реализаций Юникода стала среда программирования Java. В ней принципиально отказались от 8-битного представления символов в пользу 16-битного. Сейчас большинство языков программирования поддерживают строки Юникода, хотя их представление может различаться в зависимости от реализации.[/quote] А вот собственно ответ про wchar_t [quote]wchar_t — это тип данных стандарта ANSI/ISO C (а также использующийся в других языках программирования) для представления широких символов. «ANSI/ISO C оставляет семантику широких символов на усмотрение конкретной реализации» «размер типа wchar_t определяется компилятором, вплоть до минимальных 8 бит. Соответственно, приложения, которым требуется сохранять переносимость на различных C и C++ компиляторах, не должны использовать wchar_t для хранения Unicode-текста. Тип wchar_t предназначен для хранения широких символов в том виде, в котором их понимают конкретные компиляторы, и это может не соответствовать Юникоду». В Windows API, тип wchar_t имеет размер 16 бит. Windows API нарушает стандарт ANSI/ISO C, который требует, чтобы символьный тип wchar_t поддерживал все представимые в системе символы в одном объекте wchar_t. Вместо этого, wchar_t в Windows представляет собой символы (либо часть символа) в кодировке UTF-16. В GNU/Linux тип wchar_t имеет размер 32 бита.[/quote] [url=http://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%80%D0%BE%D0%BA%D0%B8%D0%B9_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB]Широкий символ[/url] Так может быть для AIKernel закрепить передачу строк в виде UTF-32? То есть [code]type AString_Type = packed record Str: Pointer; // Указатель на массив 32-битных символов Unicode Len: Integer; end;[/code][/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 19:38 [quote="victorst"][quote="Prof1983"]Так может быть для AIKernel закрепить передачу строк в виде UTF-32?[/quote]И чем это лучше UTF-8? В UTF-32 кроме одного преимущества - одноширинности каждого символа других я не вижу. Недостатки - нужно перекодировать и не каждая система корректно его переведет во внутреннее представление, гигантская избыточность - будет около 3 байт в каждом символе неиспользуемы. Я в AIAssistant использую UTF-8 и доволен как слон. Чего и вам желаю.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 20:04 [quote="Prof1983"]Да. Наверное UTF-8 использовать лучше, чем другие варианты. Причины я вижу такие: 1. Могут быть потенциальные проблемы с wchar_t, т.к. в Windows и в *nix разные стандарты на wchar_t. Кроме этого разные реализации в разных компиляторах. По этой причине от WideChar лучше отказаться совсем. 2. Одинаковое кол-во байтов на один символ - это удобно. Удобно делать обращение к символам по индексу. Но в этом нет большой необходимости. Всегда можно преобразовать из одного формата в другой и выполнить действия со строкой, как с массивом символов. 3. Явная избыточность UTF-32 на лицо. Фактически большинство часто используемых символов требует одного байта. Из этого следует, что UTF-8 - наилучший вариант. Но передавать его как нультерминальную строку нельзя, т.к. стандарт UTF не запрещает нулевой символ. Поэтому нужно с указателем на строку передавать еще и длину строки. Это удобно объединить в структуру. [code]type AString_Type = packed record Str: PChar; // UTF-8 string Len: Integer; end;[/code] Это хороший вариант. Более того, в GTK для передачи строк используется точно такая же структура (GString). Виктор, кстати поздравляю с вашим сообщением за номером 1001! Такое событие нужно отметить! :)[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 20:41 [quote="victorst"][quote="Prof1983"]Виктор, кстати поздравляю с вашим сообщением за номером 1001! Такое событие нужно отметить! :)[/quote]Спасибо за поздравление. Я случайно, я не специально, оно само так вышло. Действительно, в данной теме идет речь о передаче, а не об обработке строковых параметров. С этой точки зрения и нужно рассматривать строки. Поэтому я и предложил UTF-8. Получив строку, можете немедленно преобразовать к тому виду, в котором удобнее обрабаатывать на данной платформе и пользоваться и UTF-16 и UTF -32 или еще чем. Но с нулем внутри строки - да, я напарывался на такое не раз. Особенно когда нужно строкой передать массив численных данных. Поэтому параметр длины строки желателен. Но как быть с самим нулем в конце строки? Логично было бы его оттуда убрать при передаче.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 20:51 [quote="Prof1983"][quote="DCV"]По-моему Юникод может хранить даже китайские иероглифы.[/quote] [quote]В Microsoft Windows NT и основанных на ней системах Windows 2000 и Windows XP в основном используется форма UTF-16LE.[/quote]http://ru.wikipedia.org/wiki/Unicode Я еще раз подумал про UTF-8. Дело в том, что можно использовать UTF-16 без использования wchar_t. Поэтому мое предыдущее высказывание "1. Могут быть потенциальные проблемы с wchar_t, т.к. в Windows и в *nix разные стандарты на wchar_t. Кроме этого разные реализации в разных компиляторах. По этой причине от WideChar лучше отказаться совсем." не имеет значения. Стало быть UTF-16 ни чем не хуже, чем UTF-8. Лишней избыточности не много. На один символ будет приходится 2 байта, а не 4 как в UTF-32. Хотя при UTF-16 не получится гарантировать одинаковый размер для всех символов. На сколько я понял, редко используемые символы в UTF-16 могут записываться в 4 байта. Но тем не менее, UTF-8 вроде более распространен и поддерживается в многих библиотечках (в том числе преобразование UTF-8 входит в System.pas в Delphi).[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 21:40 [quote="victorst"]Дело в том, что в мире еще полно старых программ или библиотек функций, работающих с обычными нуль-терминальными строками и др. неюникодовыми строками. UTF-8 позволяет этим программам и ф-циям (если в нем нет 0) прозрачно работать. Только там где нужно учитывать юникодовость, например, при выводе на экран требуется учет этого. Если вы откроете Notepad++, то в нем есть два режима сохранения текста UTF-8 - с BOM и без BOM. Этот BOM - набор специальных байт в начале текста, который говорит, что текст в документе UTF-8. И программы, знающие такой префикс в начале текста автоматически будут воспринимать текст как UTF-8. Зачем нужен вариант без BOM? Для старых программ. Этот BOM приводит их к некорректной работе. UTF-8 при грамотном обращении позволяет значительно расширить потенциальный круг применения вашей системы. http://ru.wikipedia.org/wiki/UTF-8 "В отличие от UTF-16, UTF-8 является самосинхронизирующейся кодировкой[1]: при потере одного байта последующие байты будут раскодированы корректно." Весьма полезное свойство для любого канала передачи данных, не правда ли?[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 22:44 [quote="Prof1983"]Да. Все верно. Я вот еще смотрю на реализацию функций GTK. Вот например: http://www.opennet.ru/docs/RUS/glib_api/glib-Character-Set-Conversion.html Там практически везде используется *gchar. Это то же самое что *char. Спрашивается зачем тогда нужен тип GString (http://www.opennet.ru/docs/RUS/glib_api/glib-Strings.html#GString)? Не могу понять. Может быть тогда вообще прийти к старому классическому виду и передавать все строки между модулями AIKernel как PChar/*char, добавляя дополнительный параметры длины строки в байтах? То есть[code]function Example(S: PChar; Len: Integer; OutStr: PPChar; MaxLenOutStr: Integer): Integer;[/code] Что-то я запутался.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 29 май 2011, 23:11 [quote="victorst"]Разница между просто *char и *char UTF-8 в том, что источник и приемник сообщения заранее знают, что содержимое стрки либо ASCII либо UTF-8. Это априорное соглашение сторон. Оно позволяет соотетственно обрабатывать строки. Вот и все. Поэтому если вы отправите обычную *char строку, то в ней нельзя будет закодировать символы, код которых больше 127.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 30 май 2011, 01:41 [quote="daner"]Если вам по какой-то причине хочется изобретать свое колесо, да еще и с прицелом на всевозможные варианты, то лучше использовать, что-то типа такой структуры и соответствующих функций (а лучше конечно класс) class UString{// от слова универсальный. uint code, uint size, uint strSize, char* str }; ну str понятно, size -- кол-во символов, strSize -- длинна строки в байтах, ну и code -- это идентификатор кодировки. (естественно size , strSize связанны через code, но лучше иметь их оба, тратит не много места, но зато экономит ненужные подсчеты, особенно когда строки большие, а кодировка не предусматривает постоянного кол-во байт за одним символом). Ну опять таки, тут еще бы подумать о том, как такие строки будут в основном использоваться в вашей системе... если правок в них будет много, то... как обычно стоит взвешивать всевозможные структуры (типа списков, динамических массивов и т.д.), соответственно поля тоже могут меняться в зависимости от структуры данных. Но для чего вам весь этот геморрой? я так и не могу понять. используйте готовые библиотеки типа boost-а и т.д. Нравится GTK ну так и пользуйтесь его стандартами.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 01 июн 2011, 23:47 [quote="Prof1983"][quote="daner"]class UString{// от слова универсальный. uint code, uint size, uint strSize, char* str };[/quote]Идея хорошая. Вот только класс смысла использовать нету, лучше структуру. Я решил пока реализовать передачу строк между модулей с помощью указателя на структуру AString_Type. При этом внутреннее содержание пока не раскрываю, а вместо этого будут реализованы примерно такие функции (Pascal): [code]type AString = ^AString_Type; // Указатель. Можно записать и так: AString = Pointer; function A_String_New(S: AString): AString; stdcall; function A_String_NewC(S: PChar; Len: AInteger): AString; stdcall; // Ansi function A_String_NewU(S: PChar; Size: ASize): AString; stdcall; // UTF-8[/code] А работу со строками реализовать внутри одного из основных модулей в виде примерно таких функций: [code]function A_System_String_Length(S: AString): AInteger; stdcall; function A_System_String_Compare(Str1, Str2: AString): AInteger; stdcall; function A_System_String_CompareA(Str1, Str2: AString; IgnoreCase: ABoolean): AInteger; stdcall; function A_System_String_Concat(Str1, Str2: AString): AString; stdcall; function A_System_String_ConcatA(Str1, Str2, Str3: AString): AString; stdcall; function A_System_String_IndexOfCh(S: AString; Ch: AChar): AInteger; stdcall; function A_System_String_IndexOfStr(S, Str: AString): AInteger; stdcall; function A_System_String_LastIndexOfCh(S: AString; Ch: AChar): AInteger; stdcall; function A_System_String_LastIndexOfStr(S, Str: AString): AInteger; stdcall;[/code] Реализовать для начала основные. А за тем, по мере необходимости добавлять еще функций. А для использования строки преобразовывать примерно так:[code]function String_ToWideString(S: AString): WideString; stdcall;[/code][/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 03 июн 2011, 19:45 [quote="Prof1983"][quote="DCV"]Чем лицензия должна отличаться от лицензии на Visual Studio Express 2010, которая вроде бы бесплатная?[/quote]Лицензия на готовое ПО - это одно, а лицензия на исходный код этого ПО - это другое. Лицензия на бинарники в основном разрешают использовать (на платной или бесплатной основе) и получать некий результат работы. Я не в курсе какое разрешенное использование имеют исходные коды Visual Studio Express 2010 и есть ли эти исходные коды в общем доступе. Скорее всего их нет. Более того дезасемблировать или каким-либо другим способом смотреть внутренности бинарников от MS обычно запрещается. Если имеете в виду исходный код, который предстоит самому написать в редакторе MSVS, то этот исходный код будет распространяться под такими условиями, какие установит автор (или правообладатель). Или вы имели в виду что-то другое?[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 03 июн 2011, 22:42 [quote="Prof1983"][quote="DCV"]Значит, Вы устанавливаете требование к выбору языка программирования: возможность иметь исходный код языка программирования и редактировать исходный код языка программирования? Зачем это нужно?[/quote]Требования к языку программирования (вернее к компилятору) я уже описывал ранее. А именно: язык должен быть компилируемым, то есть для выполнения программы не должно требоваться каких-либо виртуальных машин и т.п. DotNET под эти требования не подходит. А что вы понимаете под исходным кодом языка? Может быть имеете в виду исходный код компилятора? Если так, то открыт компилятор или закрыт - это не важно. Важно, в какой вид этот компилятор скомпилирует программу или библиотечку и можно ли ее будет использовать потом в программах на других языках. DotNET и под эти требования не подходит. Если хотите развить дискуссию на эту тему, то давайте создадим соответствующую тему. Например "Меряемся языками" или что-то подобное. :) А эту тему я скоро закрою, т.к. ответ на вопрос по теме топика уже найден.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 03 июн 2011, 23:11 [quote="victorst"]Раз тему все равно закрывают, то под занавес оффтоп: 2Prof1983: Как вы относитесь к виртуальной машине языка Lua? Для Lua есть и интерпретатор и компилятор на самые распространенные программные платформы. Я проверил скорость работы интерпретатора. Delphi на простых циклах в 3-40 раз быстрее чем Lua. Довольно неплохой показатель при сравнении компилятора Delphi и интерпретатора Lua. Для контроля сравнил Delphi c CLIPS. На циклах, которые не характерны для CLIPS, но все же: CLIPS в 300-500 раз медленнее чем Delphi. Получается что Lua в 10-12 раз быстрее чем CLIPS. К тому же Lua довольно легко стыкуется с разными языками программирования - Delphi, C++, C и т.д. В одной программе на Delphi можно запустить много Lua виртуальных машин с разными скриптами. Чем не параллельная система? Но это так, мысли вслух.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 03 июн 2011, 23:39 [quote="Prof1983"][quote="victorst"]Как вы относитесь к виртуальной машине языка Lua?[/quote]Лично я к LUA хорошо отношусь. Но смотря для выполнения каких задач. Если использовать LUA для реализации высокоуровневой функциональности (например манипулирование онтологическими сущностями с принятием решения и т.п.), то LUA для этого хорошо подойдет. Если же использовать LUA для реализации низкоуровневого функционала (чтение из файла, передача данных, преобразование данных, требующая хорошего быстродействия и т.д.), то LUA для этого не очень хорошо подходит. На сколько я знаю существуют встраиваемые LUA движки (виртуальные машины, если так можно сказать). То есть не требуется поставлять с программой какую-то стороннюю систему или программу. Да в общем-то вся программа вместе с интерпретатором LUA и скриптами на LUA могут быть в составе одного исполняемого файла (.exe). Вот цитаты с википедии по теме: [quote]Lua ([лу́а], порт. «луна») — интерпретируемый язык программирования, разработанный подразделением Tecgraf Католического университета Рио-де-Жанейро (Computer Graphics Technology Group of Pontifical Catholic University of Rio de Janeiro in Brazil). Является свободно распространяемым, с открытыми исходными текстами на языке Си.[/quote][quote][b]Реализация[/b] Как и многие интерпретируемые языки программирования, реализация Lua имеет отдельно компилятор с исходного языка в исполняемый байт-код и виртуальную машину для исполнения сгенерированного байт-кода. Причём байт-код — это не команды стековой машины, а команды некоего виртуального процессора с несколькими регистрами, что повышает эффективность исполнения. В стандартной виртуальной машине Lua используется распределение памяти со сборкой мусора (аналогично Java или .NET). Lua использует единый строковой пул, что позволяет снизить расходы памяти на хранение строк. Для задач, критичных по времени, имеется JIT компилятор Lua LuaJIT. Также разработан компилятор llvm-lua, генерирующий код для виртуальной машины LLVM, позволяющей последующую компиляцию в очень эффективный машинный код для процессоров различной архитектуры. [b]Использование[/b] В настоящее время используется в различных проектах, где требуется встроить достаточно быстрый и нетрудный в освоении скриптовый язык программирования — например, в разработке игр, где Lua часто используется между игровым «движком» и данными для написания сценариев поведения/взаимодействия объектов.[/quote] [url=http://ru.wikipedia.org/wiki/Lua]http://ru.wikipedia.org/wiki/Lua[/url] Я бы хотел встроить открытый интерпретатор LUA в проект AIKernel в качестве одного из "модулей".[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 04 июн 2011, 00:05 [quote="victorst"]Я кстати встроил Lua в программу на Delphi. Но т.к. для Lua желательно чтобы он управлял каким-то укрупненным функционалом, то я встроил пока что в игровой движок HGE. Lua можно встроить в любую другую программу. С его помощью можно было решать какой-то типовой класс задач, управлять быстрым движком на основном языке. Можно не игровым, а модулями ИИ, например. Второй вариант - сделать на Lua множество микродвижков в рамках одной программы на том же Delphi. Например, для эмуляции параллельно работающих нейронов. Я забыл упомянуть о сравнении Lua и моей виртуальной машины, которую я писал несколько лет на ассемблере. Моя оказалась заметно медленнее чем Lua. Это меня премного удивило, тем белее, что в цикле AIGod обрабатывал целые 64 битные числа, а Lua - с плавающей точкой повышенной точности. Обмен между Lua и основной материнской программой осуществляется через стек. Эта реализация оказалась также очень похожа на мой AIGod.[/quote]
Заголовок сообщения: Re: Передача строковых параметров СообщениеДобавлено: 04 июн 2011, 00:25 [quote="Prof1983"]Раз уж пошло обсуждение посторонних тем, то и я продолжу. Я добрый модератор. :) [quote="DCV"]Язык C++ ... Подходит ли этот язык под Ваши требования?[/quote]Да. Подходит, но с одним но: в экспортируемых для внешнего использования функциях в качестве параметров не должны использоваться классы. Вместо классов можно использовать структуры. [quote="victorst"]HGE, Lua[/quote]Виктор, я тоже очень хочу заняться этими технологиями и направлениями. А так же Онтологиями, Sumo, роботами и прочим и прочим. Но, сильно ограничен в свободном времени. Так что, даже и не знаю, получится ли у меня когда-нибудь повторить то, что вы изучили и реализовали. Не говоря уже о том, чтобы сделать что-то лучше, чем это уже реализовано. Но, тем не менее, я постараюсь приложить все усилия на то, чтобы развить проект AIKernel до стадии продукта. Под продуктом я здесь понимаю фреймворк, набор библиотечек ("модулей"), которые будут объединены в одну систему. На этих выходных у меня не получится позаниматься проектом AIKernel и вообще ИИ, поэтому откладываю на следующие. Вообще надо как-то привлекать еще людей к участию. Пока для обсуждения, а потом, возможно и для небольшого кодинга. Тем более, что заинтересованные есть, но нужно их как-то организовывать. Вопрос только как? По всей видимости нужен какой-то стимул, какая-то четкая реальная цель. И чтобы для включения в проект не требовалось долгого изучения применяемых технологий, а все было максимально просто. На данный момент в Рунете попыток создания проектов ИИ много, но все они разрозненные и нет сильного лидера за которым пойдет народ. А каждый сам по себе, в одиночку, вряд-ли что-то существенное сможет создать. Не говоря уже о таком сложном проекте как создание ИР. Как же быть в такой ситуации? Что делать?[/quote]