Утилиты для обработки json

Использование JSON в HTTP интерфейсах приложений

Автоматически генерируемый REST интерфейс прикладных решений

При обращении к REST интерфейсу прикладного решения вы можете получать ответ в формате JSON. Для этого в адресной строке вам нужно указать параметр $format=json. Либо указать MIME тип «application/json» в заголовке Accept HTTP запроса. Например:

Запрос:

GET /TestInfobase/odata/standard.odata/СправочникДляТестов?$format=json HTTP/1.1
MaxDataServiceVersion: 3.0;NetFx
Accept: application/json
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services

Ответ:

HTTP/1.1 200 OK
Content-Length: 9429
Content-Type: application/json;charset=utf-8
Server: Microsoft-IIS/7.5
DataServiceVersion: 3.0
X-Powered-By: ASP.NET
Date: Mon, 12 Aug 2013 09:44:07 GMT
    
{
"odata.metadata":"http://host/svc/$metadata#СправочникДляТестов",
"value":[
{
	"Ref_Key":guid'cc6a7df3-8cfe-11dc-8ca0-000d8843cd1b',
	"DataVersion":"AAAAAQAAAAE",	
	"DeletionMark":false,
	"Parent_Key":guid'bbb079ae-8c51-11db-a9b0-00055d49b45e',
	"IsFolder":false,
	"Code":000000025,
	"Description":"Пинетки",
	"Поставщик_Key":guid'd1cb82a7-8e8b-11db-a9b0-00055d49b45e',
	"Поставщик@navigationLinkUrl":"СправочникДляТестов(guid'cc6a7df3-8cfe-11dc-8ca0-000d8843cd1b')/Поставщик",
	"РеквизитХранилище_Type": "image/jpeg",
	"РеквизитХранилище_Base64Data@mediaReadLink": "Catalog_ДемоСправочник(guid'cf2b1a24-1b96-11e3-8f11-5404a6a68c42')/РеквизитХранилище_Base64Data",
	"РеквизитХранилище_Base64Data": <строка с закодированными данными>
	…
},
{…},
{…}
]
}

Вы можете управлять объёмом передаваемой информации за счёт изменения детальности представления метаданных в выгрузке. Существуют три уровня: Nometadata, Minimalmetadata и Fullmetadata. По-умолчанию (на примере вверху) используется средний уровень — Minimalmetadata. На уровне Nometadata объём передаваемой информации минимальный, а на уровне Fullmetadata — максимальный. Однако при этом нужно понимать, что сокращение объёма передаваемой информации приводит к более интенсивным вычислениям на клиенте. И наоборот, когда вся информация включается в выгрузку, объём вычислений на клиенте будет минимальным.

Детальность представления метаданных вы можете указать, например, в адресной строке.

Сведения о метаданных не передаются:

GET /TestInfobase/odata/standard.odata/СправочникДляТестов/?$format=application/json;odata= minimalmetadata

Вся информация о метаданных включается в выгрузку:

GET /TestInfobase/odata/standard.odata/СправочникДляТестов/?$format=application/json;odata=fullmetadata

HTTP-сервисы прикладного решения

HTTP-сервисы, реализованные в прикладном решении, также могут возвращать ответ в формате JSON. Для этого вам проще всего сформировать тело ответа в JSON, получить его как строку, а затем установить из этой строки тело HTTP ответа сервиса. При этом желательно указать, что BOM (Byte Order Mark, метка порядка байтов) использоваться не должна.

Последний параметр (ИспользованиеByteOrderMark.НеИспользовать) вы можете и не указывать, если режим совместимости конфигурации не установлен, или он больше чем Версия8_3_5. Потому что в этом случае BOM автоматически будет использоваться только для кодировок UTF-16 и UTF-32, а для UTF-8, UTF-16LE/UTF-16BE, UTF-32LE/UTF-32BE и других она использоваться не будет.

Взаимодействие со сторонними HTTP сервисами

При взаимодействии со сторонними HTTP интерфейсами у вас также может возникнуть необходимость формирования запросов к ним в формате JSON. В этом случае алгоритм ваших действий будет аналогичным. Формируете тело запроса в JSON. Получаете тело в виде строки. Из этой строки устанавливаете тело HTTP запроса. BOM не используете.

Дальнейшее развитие

Мы думаем над тем, чтобы предоставить вам возможность сериализации в JSON прикладных типов 1С:Предприятия: ссылок, объектов, наборов записей и т.д. Поэтому есть вероятность появления ещё одного, третьего уровня средств работы с JSON. Этот уровень позволит вам преобразовывать в JSON любые типы 1С:Предприятия, для которых поддерживается XDTO-сериализация в XML.

Как создать файл

Формат JSON, как правило, используется для работы (хранения и использования) служебной информации. Обычно это штатное расписание, которое не должен видеть ни разработчик, ни аудитория веб-ресурса.

Существует несколько способов создать файл с соответствующим расширением. Прежде всего, это можно сделать посредством обычного текстового редактора, являющегося частью операционной системы Microsoft Windows. Для этого необходимо открыть Блокнот, вставить соответствующий код и сохранить документ в обычном и единственно доступном расширении. После этого необходимо поменять его на нужный вариант.

Второй способ подразумевает использование сторонних сервисов. Наиболее популярным является JSON Editor Online. Он намного удобнее, чем вариант с Блокнотом. Интерфейс сервиса представлен в виде двух рабочих зон.

В первой происходит непосредственно работа по формированию данных, во второй зоне размещаются инструменты для этого. После того как процесс создания будет окончен, необходимо нажать на кнопку «Save» и выбрать способ сохранения результата: на диск или онлайн.

Как уже отмечалось, использование онлайн-сервиса намного удобнее Блокнота. Связано это с тем, что сервис в процессе работы автоматически определяет синтаксические ошибки и выделяет их, чтобы пользователь мог заметить упущения и сразу же исправить.

Синтаксис и структура JSON

Прежде чем приступить к разбору JSON надо понять и разобраться в том, как собственно все это дело создаётся и записывается в файл. Синтаксис достаточно простой и не должен вызвать каких-то сложностей. Достаточно запомнить следующие моменты и посмотреть на примеры.

Общие принципы:

  1. Массив всегда заключается в  квадратные скобки 
  2. Объект нужно заключать в фигурные скобки { … }
  3. Свойства и значения в двойных кавычках разделённые ( : ) «Значение» : «Свойства»

Свойства может быть:

  1. Логическим (true или false).
  2. Числом, записывается без двойных кавычек.
  3. Строкой, записывается в двойные кавычки.
  4. Массивом или объектом.

Когда основные моменты структуры JSON известны, рассмотрим примеры JSON файлов и начнём с самого примитивного и простого примера.

{
«Машка» : «28 год»,
«Дашка» : «35 лет»,
«Анжелка» : «30 лет»
}

Если декодировать этот пример из приложения, например из PHP используя функцию json_decode() то вывод будет следующим.

stdClass Object
(
=> 28 год
=> 35 лет
=> 30 лет
)

Поскольку JSON пофиг на табуляцию и пробелы, вы можете делать записи как Вам больше нравится, например в одну строку.

{ «Машка» : «28 год», «Дашка» : «35 лет», «Анжелка» : «30 лет» }

Или использовать табуляцию, для полной красоты записи.

{
«Машка» : «28 год»,
«Дашка» : «35 лет»,
«Анжелка» : «30 лет»
}

Давай сделаем все не много интереснее и усложним пример. Разделим логически записи для каждой особы, что бы добавить для каждой девушки информацию о ней.

{
«Машка» : {
«Возрост» : «33»,
«1 час» : «150$»
},
«Дашка» : {
«Возрост» : «28»,
«1 час» : «200$»
},
«Анжелка» : {
«Возрост» : «28»,
«1 час» : «100$»
}
}

Обратите внимание, что за последним элементом не ставится запитая, как после свойства так и объекта. Посмотрим, какой теперь будет ответ

stdClass Object
(
=> stdClass Object
(
=> 33
=> 150$
)

=> stdClass Object
(
=> 28
=> 200$
)

=> stdClass Object
(
=> 28
=> 100$
)

)

Теперь все куда интереснее. Можно из программы получить нужный объект, например «» и посмотреть что там за час))) Но что если и этого мало. Нужно больше информации и по каждому объекту. Можно присобачить массив. Далее буду использовать примеры JSON в более коротком варианте, либо листинги длинные…

{
«Машка» : {
«Возрост» : «33»,
«1 час» : «150$»,

«Доп инфа» :

}
}

Ну и стразу можно посмотреть в каком виде прилетит ответ. Кстати, в этом примере [] можно убрать, они тут в принципе и нахер не нужны, но для примера сойдёт.

stdClass Object
(
=> stdClass Object
(
=> 33
=> 150$
=> Array
(
=> stdClass Object
(
=> 169
=> 1
)

)

Думаю понятно, что к чему, и как создаются JSON файлы. Вы сами можете продумывать структуру файлов под свои задачи, главное не нарушать синтаксис, и все будет хорошо.

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

JSON Синтаксис

Чтобы правильно создать файл .json, вы должны следовать правильному синтаксису.

Есть два основных элемента объекта JSON: ключи и значения.

  • Ключи должны быть строками. Они содержат последовательность символов, которые заключены в кавычки.
  • Значения являются допустимым типом данных JSON. Они могут быть в форме массива, объекта, строки, логического значения, числа или значения null.

Объект JSON начинается и заканчивается фигурными скобками {}. Внутри может быть две или больше пар ключей/значений с запятой для их разделения. Между тем за каждым ключом следует двоеточие, чтобы отличить его от значения.

Вот пример:

{"city":"New York", "country":"United States "}

У нас есть две пары ключей/значений: ключи — город и страна; Нью-Йорк и США — это значения.

Типы Значений

Значения содержат допустимый тип данных JSON, например:

Массив

Массив — это упорядоченная коллекция значений. Он заключен в квадратные скобки [], а каждое значение внутри разделено запятой.

Значение массива может содержать объекты JSON, что означает, что он использует ту же концепцию пар ключей/значений. Например:

"students":

Информация в квадратных скобках — это массив, в котором есть три объекта.

Объект

Объект содержит ключ и значение. После каждого ключа стоит двоеточие, а после каждого значения — запятая, которая также различает каждый объект. Оба они находятся внутри кавычек.

Объект как значение должен подчиняться тому же правилу, что и объект. Например:

“employees”: {"firstName":"Tom", "lastName":"Jackson”}

Здесь сотрудники — ключ, а всё, что находится внутри фигурных скобок — объект.

Строки

Строка — заданная последовательность из нуля и больше символов Юникода, заключенная в две двойные кавычки.

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

"firstName":"Tom"

Число

Число в JSON должно быть целым или с плавающей запятой, например:

{“age”:”30”}

Булевый тип

Вы можете использовать true или false в качестве значения, как показано ниже:

{“married”:”false”)

Значение null

Показывает отсутствие информации.

{“bloodType”:”null”}

JSON в практических примерах

Первое что в голову приходит, это взять соц.сеть, например API VK и поработать с ним, но нет. Не охота тратить время на создание приложения, подтверждать все по СМС и прочие, и вообще ВК дно…

Не много подумал, если же coinmarketcap.com/api/ с публичным API без всяких ключей и секретов. Круто, будем писать крипто приложение, можно какойнить виджет на сайт замутить))) Напишем прогу которая будет сообщать, какие монеты находятся в ТОП 3, какие цены, и всю херню…

Отправляем запрос на сервер 

Ломимся на coinmarketcap.com и смотрим что там есть. Что бы получить ТОП 3 манеты можно отправить GET запрос по адресу  где параметру limit передать нужно количество монет «Значение», нас интересует 3. Пишем код.

$ticker = file_get_contents(‘http://api.coinmarketcap.com/v2/ticker/?limit=3’);
$ticker = json_decode($ticker);

echo «\n»;
print_r($ticker);
echo «\n»;

И сразу смотрим ответ, что там пришло.

Видим уже нечто знакомое, это сервер вернул ответ в JSON формате, в котором содержится целая куча всякой разной информации по каждой монете. Теперь осталось разобрать все это дело и забрать только то, что нам нужно. Пишем код дальше.

$ticker = file_get_contents(‘http://api.coinmarketcap.com/v2/ticker/?limit=3’);
$ticker = json_decode($ticker);

echo «\n»;

foreach ($ticker->data as $key => $value) {
echo ‘ ============= TOP ‘. $value->rank .’ ==============’ . «\r\n»;
echo ‘ Монета :’ . $value->name . «\r\n»;
echo ‘ Цена :’ . $value->quotes->USD->price . «\r\n»;
echo ‘ Объём :’ . $value->quotes->USD->volume_24h . «\r\n»;
echo ‘ ==================================’ . «\r\n\r\n»;
}

Для примера я взяла только некоторую часть информации, а остальное брать не буду, сами разбирайтесь))) Результат работы этой крутой и полезной программы представлен на этом скнине.

Как вы понимаете я использую консоль, по скольку все это дело на PHP думаю понятно, как просто вывести все это дело на сайте.

На этом работа с JSON на сегодня окончена, мы посмотрели пару примеров, и написали программу, которая прекрасно демонстрирует всю прелесть и удобство JSON.

Сравнение JSON и XML

Во многих отношениях вы можете рассматривать JSON как альтернативу XML, по крайней мере, в сфере веб приложений. Концепция AJAX оригинально основывалась на использовании XML для передачи данных между сервером и браузером. Но в последние годы JSON становится все более популярным для переноса данных AJAX.

Хотя XML является проверенной технологией, которая используется в достаточном количестве приложений, преимуществами JSON являются более компактный  и простой для распознавания формат данных.

Вот как будет выглядеть выше приведенный пример объекта на XML:

<object>
  <property>
    <key>orderID</key>
    <number>12345</number>
  </property>
  <property>
    <key>shopperName</key>
    <string>Ваня Иванов</string>
  </property>
  <property>
    <key>shopperEmail</key>
    <string>ivanov@example.com</string>
  </property>
  <property>
    <key>contents</key>
    <array>
      <object>
        <property>
          <key>productID</key>
          <number>34</number>
        </property>
        <property>
          <key>productName</key>
          <string>Супер товар</string>
        </property>
        <property>
          <key>quantity</key>
          <number>1</number>
        </property>       
      </object>
      <object>
        <property>
          <key>productID</key>
          <number>56</number>
        </property>
        <property>
          <key>productName</key>
          <string>Чудо товар</string>
        </property>
        <property>
          <key>quantity</key>
          <number>3</number>
        </property>
      </object>
    </array>
  </property>
  <property>
    <key>orderCompleted</key>
    <boolean>true</boolean>
  </property> 
</object>

Версия XML имеет существенно больший размер. В действительности она имеет длину 1128 символов, а вариант JSON — только 323 символа. Версию XML также достаточно трудно воспринимать.

Конечно, это радикальный пример. И возможно создать более компактную запись XML. Но даже она будет существенно длиннее эквивалента на JSON.

5 последних уроков рубрики «Разное»

  • Выбрать хороший хостинг для своего сайта достаточно сложная задача. Особенно сейчас, когда на рынке услуг хостинга действует несколько сотен игроков с очень привлекательными предложениями. Хорошим вариантом является лидер рейтинга Хостинг Ниндзя — Макхост.

  • Как разместить свой сайт на хостинге? Правильно выбранный хороший хостинг — это будущее Ваших сайтов

    Проект готов, Все проверено на локальном сервере OpenServer и можно переносить сайт на хостинг. Вот только какую компанию выбрать? Предлагаю рассмотреть хостинг fornex.com. Отличное место для твоего проекта с перспективами бурного роста.

  • Создание вебсайта — процесс трудоёмкий, требующий слаженного взаимодействия между заказчиком и исполнителем, а также между всеми членами коллектива, вовлечёнными в проект. И в этом очень хорошее подспорье окажет онлайн платформа Wrike.

  • Подборка из нескольких десятков ресурсов для создания мокапов и прототипов.

Работаем со строкой JSON в PHP

PHP, как и JavaScript, имеет встроенные функции для работы с JSON строками.

Создаем строку JSON из переменной PHP

Функция принимает переменную PHP и возвращает строку JSON, представляющую содержание переменной. Вот наш пример с заказом, написанный на PHP:

<?php
$cart = array(
  "orderID" => 12345,
  "shopperName" => "Ваня Иванов",
  "shopperEmail" => "ivanov@example.com",
  "contents" => array(
    array(
      "productID" => 34,
      "productName" => "Супер товар",
      "quantity" => 1
    ),
    array(
      "productID" => 56,
      "productName" => "Чудо товар",
      "quantity" => 3
    )
  ),
  "orderCompleted" => true
);
 
echo json_encode( $cart );
?>

Данный код возвращает абсолютно такую же строку JSON, как и в примере с JavaScript:

{"orderID":12345,"shopperName":"Ваня Иванов","shopperEmail":"ivanov@example.com","contents":,"orderCompleted":true}

В реальном приложении ваш скрипт PHP пришлет данную строку JSON как часть AJAX ответа браузеру, где JavaScript код с помощью метода преобразует ее обратно в переменную для вывода на странице пользователя.

Вы может передавать различные флаги в качестве второго аргумента функции . С их помощью можно изменять принципы кодирования содержания переменных в строку JSON.

Создаем переменную из строки JSON

Для преобразования строки JSON в переменную PHP используется метод . Заменим наш пример для JavaScript с методом на код PHP:

<?php
$jsonString = '
{                                          
  "orderID": 12345,                        
  "shopperName": "Ваня Иванов",             
  "shopperEmail": "ivanov@example.com", 
  "contents": ,                                       
  "orderCompleted": true                   
}                                          
';
 
$cart = json_decode( $jsonString );
echo $cart->shopperEmail . "<br>";
echo $cart->contents->productName . "<br>";
?>

Как и для JavaScript данный код выдаст:

ivanov@example.com
Чудо товар

По умолчанию функция возвращает объекты JSON как объекты PHP. Существуют обобщенные объекты PHP класса . Поэтому мы используем для доступа к свойствам объекта в примере выше.

Если вам нужен объект JSON в виде ассоциированного массива PHP, нужно передать в качестве второго аргумента функции . Например:

$cart = json_decode( $jsonString, true );
echo $cart . "<br>";
echo $cart . "<br>";

Данный код выдаст такой же вывод:

ivanov@example.com
Чудо товар

Также функции можно передавать другие аргументы для указания глубины рекурсии и способов обработки больших целых чисел.

Для чего используется JSON?

Наиболее частое распространенное использование JSON — пересылка данных от сервера к браузеру. Обычно данные JSON доставляются с помощью AJAX, который позволяет обмениваться данными браузеру и серверу без необходимости перезагружать страницу.

Пример:

  1. Пользователь нажимает миниатюру продукта в онлайн магазине.
  2. JavaScript, выполняющийся на браузере, генерирует запрос AJAX к скрипту PHP, запущенному на сервере, передавая ID выбранного продукта.
  3. Скрипт PHP получает название продукта, описание, цену и другую информацию из базы данных. Затем составляет из данных строку JSON и отсылает ее браузеру.
  4. JavaScript, выполняющийся на браузере, получает строку JSON, декодирует ее и выводит информацию о продукте на странице для пользователя.

Также можно использовать JSON для отправки данных от браузера на сервер, передавая строку JSON в качестве параметра запросов GET или POST. Но данный метод имеет меньшее распространение, так как передача данных через запросы AJAX может быть упрощена. Например, ID продукта может быть включен в адрес URL как часть запроса GET.

Библиотека jQuery имеет несколько методов, например,  и , которые упрощают получение данных с помощью JSON через запросы AJAX.

Сериализация примитивных типов и коллекций в JSON

Вторая группа средств работы с JSON хороша тем, что избавляет вас от рутинной работы по чтению/записи каждого отдельного значения или свойства. При чтении документы JSON отображаются в фиксированный набор типов платформы: Строка, Число, Булево, Неопределено, Массив, ФиксированныйМассив, Структура, ФиксированнаяСтруктура, Соответствие, Дата. Соответственно, в обратную сторону, композиция объектов этих типов позволяет сформировать в памяти и быстро записать в файл структуру JSON. Таким образом, чтение и запись небольшого объема JSON заранее известной структуры можно производить немногими строчками кода.

Основное назначение этих средств мы видим в обмене информацией с внешними системами, чтении конфигурационных файлов в формате JSON.

Сериализацию вы можете выполнять с помощью методов глобального контекста ПрочитатьJSON() и ЗаписатьJSON(). Они работают в связке с объектами ЧтениеJSON и ЗаписьJSON.

В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:

Код 1С:Предприятия, выполняющий десериализацию, может выглядеть следующим образом:

А пример сериализации (записи) в JSON может выглядеть так:

Результат записи:

{
	"Фамилия": "Иванов",
	"Имя": "Иван",
	"Отчество": "Иванович",
	"Возраст": 40,
	"Женат": true,
	"Телефоны": 
}

Функции преобразования и восстановления при сериализации

Не всегда сериализация может быть выполнена полностью автоматически. В жизни встречаются самые разные ситуации. Поэтому мы добавили возможность использовать «самописную» функцию обработки значений при записи в JSON и при чтении из JSON.

В методе ЗаписатьJSON() она называется Функция преобразования и описывается с помощью трёх параметров:

  • ИмяФункцииПреобразования;
  • МодульФункцииПреобразования;
  • ДополнительныеПараметрыФункцииПреобразования.

В методе ПрочитатьJSON() она называется Функция восстановления и для неё есть аналогичные параметры:

  • ИмяФункцииВосстановления;
  • МодульФункцииВосстановления;
  • ДополнительныеПараметрыФункцииВосстановления.

При записи в JSON эта функция полезна потому, что позволяет самостоятельно преобразовать в JSON те типы, которые не подлежат автоматическому преобразованию. Или даже совсем отказаться от их сериализации.

Например, так оказалось, что в записываемой структуре одно из значений — это ссылка на элемент справочника ПодразделенияОрганизаций. Такое значение (ссылка на объект 1С:Предприятия) не может быть автоматически сериализовано средствами платформы. Тогда, используя функцию преобразования, мы можем получить для этого значения его строковое представление в удобном виде. Например, в виде строки «ИП Петров: Отдел рекламы».

Результат выполнения примера:

{
	"Фамилия": "Иванов",
	"Имя": "Иван",
	"Отчество": "Иванович",
	"Подразделение": "ИП Петров: Отдел рекламы",
	"Телефоны": 
}

При чтении из JSON функция восстановления может использоваться для того, чтобы преобразовать данные JSON в типы 1С, которые не могут являться результатом автоматического преобразования, или для того, чтобы самостоятельно (не автоматически) преобразовать даты JSON в даты 1С:Предприятия.

Что значит JSON

Несмотря на возможность использования практически во всех скриптовых языках, его название относится к JavaScript. Инструмент имеет следующие преимущества:

  1. Занимает сравнительно небольшой объем, компактен.
  2. Текстовое содержание может легко создаваться и поддаваться чтению вычислительной техникой и человеком.
  3. Можно без особого труда преобразовать в структуру практически для всех видов формальных языков, использующихся для создания компьютерных программ.
  4. Большинство языков программирования, будь то JavaScript, Ruby, Python или PHP, наделены функциями и специальными инструментами для чтения и редактирования файла.

В подавляющем большинстве случаев формат JSON используется для работы по передаче информации от сервера к браузеру. Этот процесс, как правило, происходит в «фоновом» режиме обмена браузера с web-сервером, а доставка осуществляется при помощи AJAX. Это обуславливается тем, что в процессе доставки данных отсутствует необходимость перезагружать страницу.

Работает это по следующему сценарию:

Все это происходит в считанные миллисекунды. Однако, если JavaScript отключен на компьютере по каким-либо причинам, веб-страница не загрузится либо будет отображаться с ошибками.

Основные преимущества JSON

Как уже понятно, JSON используется для обмена данными, которые являются структурированными и хранятся в файле или в строке кода. Числа, строки или любые другие объекты отображаются в виде текста, поэтому пользователь обеспечивает простое и надежное хранение информации. JSON обладает рядом преимуществ, которые и сделали его популярным:

  1. Не занимает много места, является компактным в написании и быстро компилируется.

  2. Создание текстового содержимого понятно человеку, просто в реализации, а чтение со стороны среды разработки не вызывает никаких проблем. Чтение может осуществляться и человеком, поскольку ничего сложного в представлении данных нет.

  3. Структура преобразуется для чтения на любых языках программирования.

  4. Практически все языки имеют соответствующие библиотеки или другие инструменты для чтения данных JSON.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Ваша ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: