diff --git a/README.md b/README.md
index ffadc1b..3a1022e 100644
--- a/README.md
+++ b/README.md
@@ -2050,3 +2050,146 @@ const Gantt = ({ title }) => {
```
Полные актуальные исходные коды примеров можно увидеть в "db/PKG_P8PANELS_SAMPLES.pck" и "app/panels/samples/gantt.js" данного репозитория соответственно.
+
+##### Интерактивное изображение "P8PSVG"
+
+Компонент предназначен для отображения изображений в формате SVG. Поддерживается:
+
+- Режим галереи с зацикленным переключением между несколькими переданными компоненту изображениями
+- Обработка событий `onClick` для изображения в целом и `onItemClick` для отдельных замкнутых контуров и групп, имеющих атрибут `id`
+- Управление цветом и прозрачностью заливки отдельных замкнутых контуров и их групп
+
+
+
+**Подключение**
+
+Клиентская часть реализована в компоненте `P8PSVG`, объявленном в "app/components/p8p_svg". Для использования компонента на панели его необходимо импортировать:
+
+```
+import { P8PSVG } from "../../components/p8p_svg";
+
+const MyPanel = () => {
+ return (
+
+ );
+}
+```
+
+**Свойства**
+
+`data` - обязательный, строка, данные в формате SVG (`...ДАННЫЕ_ИЗОБРАЖЕНИЯ... `), при необходимости передать несколько изображений они должны просто идти подряд, разделённые закрывающим тегом ``: `...ДАННЫЕ_ИЗОБРАЖЕНИЯ_1... ...ДАННЫЕ_ИЗОБРАЖЕНИЯ_N... `, вложенные теги `` не допускаются (` ` - нельзя)\
+`items` - необязательный, массив, интерактивные элементы изображения, должен состоять из объектов вида `{id: <УНИКАЛЬНЫЙ_ИДЕНТИФИКАТОР>, title: <ТЕКСТ_ВСПЛЫВАЮЩЕЙ_ПОДСКАЗКИ>, backgroundColor: <ЦВЕТ_ЗАЛИВКИ>}`\
+`onClick` - необязательный, функция, будет вызвана при нажатии пользователем на изображение, сигнатура функции `f(event)`, результат функции не интерпретируется. В функцию будет передан типовой JS-объект `MouseEvent` с описанием события. Функция не будет вызвана, если произошло нажатие на интерактивный элемент и была вызвана функция `onItemClick` (см. ниже).\
+`onItemClick` - необязательный, функция, будет вызвана при нажатии пользователем на интерактивный элемент изображения, сигнатура функции `f({item})`, результат функции не интерпретируется. В функцию будет передан объект в поле `item`, которого, будет содержаться элемент массива `items`, описывающий интерактивный элемент изображения, на котором произошло событие. Если функция была вызвана, то вызов функции `onClick` (см. выше) не происходит.\
+`canvasStyle` - необязательный, объект, будет применён в качестве значения атрибута `style` контейнера `div` изображения\
+`fillOpacity` - необязательный, строка, прозрачность заливки интерактивных элементов, где "0" - 100% прозрачность, "0.5" - 50% прозрачность, "1" - 100% непрозрачность и т.п.\
+
+**API на сервере БД**
+
+Компонент компонент не имеет специального серверного API.\
+
+**Пример**
+
+Код панели на стороне клиента (WEB-приложения):
+
+```
+import React, { useState, useEffect } from "react"; //Классы React
+import { Typography, Grid, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio } from "@mui/material"; //Интерфейсные элементы
+import { P8PSVG } from "../../components/p8p_svg"; //Интерактивные изображения
+
+//Адрес тестового изображения
+const SAMPLE_URL = "img/sample.svg";
+
+//Стили
+const STYLES = {
+ CONTAINER: { textAlign: "center", paddingTop: "20px" },
+ TITLE: { paddingBottom: "15px" },
+ FORM: { justifyContent: "center", alignItems: "center" },
+ SVG: { height: "30vw", display: "flex", justifyContent: "center" }
+};
+
+//Пример: Интерактивные изображения "P8PSVG"
+const Svg = ({ title }) => {
+ //Собственное состояние - SVG-изображение
+ const [svg, setSVG] = useState({
+ loaded: false,
+ data: null,
+ mode: "items1",
+ items1: [
+ { id: "1", backgroundColor: "red", desc: "Цифра на флюзеляже", title: "Цифра на флюзеляже" },
+ { id: "2", backgroundColor: "magenta", desc: "Ребро флюзеляжа", title: "Ребро флюзеляжа" },
+ { id: "3", backgroundColor: "yellow", desc: "Люк", title: "Люк" }
+ ],
+ items2: [
+ { id: "4", backgroundColor: "green", desc: "Хвост", title: "Хвост" },
+ { id: "5", backgroundColor: "blue", desc: "Хвостовой руль", title: "Хвостовой руль" },
+ { id: "6", backgroundColor: "aquamarine", desc: "Ребро жесткости хвоста", title: "Ребро жесткости хвоста" }
+ ],
+ items3: [
+ { id: "7", backgroundColor: "blueviolet", desc: "Крыло левое", title: "Крыло левое" },
+ { id: "8", backgroundColor: "orange", desc: "Двигатель левый", title: "Двигатель левый" },
+ { id: "9", backgroundColor: "springgreen", desc: "Крыло правое", title: "Крыло правое" }
+ ],
+ selectedItemDesc: ""
+ });
+
+ //Загрузка изображения
+ const loadSVG = async () => {
+ const resp = await fetch(SAMPLE_URL);
+ const data = await resp.text();
+ setSVG(pv => ({ ...pv, loaded: true, data }));
+ };
+
+ //Отработка нажатия на изображение
+ const handleSVGClick = () => {
+ setSVG(pv => ({ ...pv, selectedItemDesc: "Выбрано изображение целиком" }));
+ };
+
+ //Отработка нажатия на элемент изображения
+ const handleSVGItemClick = ({ item }) => {
+ setSVG(pv => ({ ...pv, selectedItemDesc: item?.desc ? `Выбран элемент: ${item.desc}` : "Для выбранного элемента не задано описание" }));
+ };
+
+ //При подключении к странице
+ useEffect(() => {
+ loadSVG();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ //Генерация содержимого
+ return (
+
+
+ {title}
+
+
+ Группа элементов
+ setSVG(pv => ({ ...pv, mode: e.target.value, selectedItemDesc: "" }))}>
+ } label="Первая" />
+ } label="Вторая" />
+ } label="Третья" />
+
+ {svg.selectedItemDesc ? svg.selectedItemDesc : "Нажмите на элемент изображения для получения его описания"}
+
+
+
+ {svg.loaded ? (
+
+ ) : null}
+
+
+
+ );
+};
+```
+
+Полные актуальные исходные коды примера можно увидеть в "app/panels/samples/svg.js" данного репозитория соответственно.
diff --git a/docs/Image Sources.pptx b/docs/Image Sources.pptx
index b00c3e8..cd2d093 100644
Binary files a/docs/Image Sources.pptx and b/docs/Image Sources.pptx differ
diff --git a/docs/img/71.png b/docs/img/71.png
new file mode 100644
index 0000000..6a95b1b
Binary files /dev/null and b/docs/img/71.png differ