Строительные материалы от производителя с доставкой! Кирпич, ЖБИ, Газоблок
Краснодар
Главная
Контакты
Компания
  • О компании
  • Отзывы
Информация
  • Реквизиты
  • Магазины
  • Акции
  • Поставщикам
  • Оптовый клуб
Производители
Услуги
Помощь
  • Условия оплаты
  • Условия доставки
  • Возврат товаров
  • Калькулятор кирпича
  • Калькулятор газоблока
  • Калькулятор фундамента
  • Калькулятор тротуарной плитки
Блог
    +7 988 365-15-41
    +7 988 365-15-41Татьяна
    +7 861 290-70-50Светлана
    Заказать звонок
    E-mail
    ugstroys@yandex.ru
    Адрес

    г. Краснодар, ул. Ставропольская, 328/1

    Режим работы
    Пн. – Пт.: с 9:00 до 17:30 Сб.: с 9:00 до 15:00 Вс.: Выходной
    Заказать звонок
    Строй-С — официальный магазин стройматериалов
    • Кирпич
    • Тротуарная плитка
    • ЖБИ
    • Блок строительный
    • Строительные смеси
    • Колпаки и парапеты
    • Композитная арматура
    • Композитная сетка
    • Стеклопластиковая арматура
    • Декоративный камень
    • Кровельные материалы
    • Абразивно-шлифовальный инструмент
    • Буры, сверла, коронки, фрезы
    • Измерительный инструмент
    • Инструмент автомобильный
    • Крепеж и крепежный инструмент
    • Отделочный инструмент
    • Распродажа - 20%
    • Садовый инструмент
    • Сантехнический инструмент
    • Слесарный инструмент
    • Столярный инструмент
    • Торговое оборудование
    • Хозтовары и скобяные изделия
    • Электро-Пневмо-Бензоинструмент
    • Инженерное, отопительное и сантехническое оборудование
    Каталог
    По всему сайту
    По каталогу
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Кирпич ЖБИ Строительные смеси Тротуарная плитка Газоблок Автомобильный инструмент Аккумуляторный инструмент Инструмент измерительный
    Строй-С — официальный магазин стройматериалов
    Каталог
    По всему сайту
    По каталогу
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Строй-С — официальный магазин стройматериалов
    Телефоны
    +7 988 365-15-41 Татьяна
    +7 861 290-70-50 Светлана
    Заказать звонок
    0
    0
    0
    Строй-С — официальный магазин стройматериалов
    • Краснодар
      • Назад
      • Города
      • Адыгея
      • Анапа
      • Армавир
      • Белореченск
      • Геленджик
      • Горячий Ключ
      • Краснодар
      • Москва
      • Новороссийск
      • Сочи
      • Темрюк
      • Тихорецк
      • Херсон
    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    • +7 988 365-15-41 Татьяна
      • Назад
      • Телефоны
      • +7 988 365-15-41 Татьяна
      • +7 861 290-70-50 Светлана
      • Заказать звонок
    • ugstroys@yandex.ru
    • г. Краснодар, ул. Ставропольская, 328/1

    • Пн. – Пт.: с 9:00 до 17:30 Сб.: с 9:00 до 15:00 Вс.: Выходной
     
    Тротуарная плитка от производителя
    Широкий ассортимент. Высокое качество. Доставка по Краснодару и краю.
    Открыть каталог
    Инженерное, отопительное и сантехническое оборудование
    Лучшее качество
    Заказать продукт
    Кирпич с доставкой по всему Южному округу!
    Строй-С ваш официальный поставщик кирпича!
    Открыть каталог
    Кирпич, газоблок, жби изделия
    «Строй-С» стремится сделать условия покупки максимально выгодными для каждого покупателя, поэтому на сайте регулярно появляются новые товары и предложения
    Выбрать
    Подробнее

    Популярные категории

    Кирпич Кирпич
    Тротуарная плитка Тротуарная плитка
    ЖБИ ЖБИ
    Блок строительный Блок строительный
    Строительные смеси Строительные смеси
    Колпаки и парапеты Колпаки и парапеты
    Композитная арматура Композитная арматура
    Композитная сетка Композитная сетка
    Стеклопластиковая арматура Стеклопластиковая арматура
    Кровельные материалы Кровельные материалы
    Инструмент автомобильный Инструмент автомобильный
    Слесарный инструмент Слесарный инструмент
    Электро-Пневмо-Бензоинструмент Электро-Пневмо-Бензоинструмент
    Весь каталог
    🔥 ОПТОВЫЙ КЛУБ

    Инструмент оптом

    от 100 000 ₽ / доставка по всей России

    🏭 Прямые поставки
    ⚡ ХИТ

    Аккумуляторный

    Fit, Cutop, Maxpro

    от 20 шт 🚛 доставка
    🔧 ПРОФИ

    Измерительный

    Fit, Курск

    от 15 шт 🚛 доставка
    🔄 ОСНАСТКА

    Расходники

    Буры, свёрла, диски

    от 100 шт 🚛 доставка
    🏗️ ОТДЕЛКА

    Электроинструмент

    Дрели, перфораторы, УШМ

    от 50 шт 🚛 доставка
    💰
    от 100 000 ₽
    минимальный оптовый заказ
    🏪
    Самовывоз — СКИДКА 15%
    при самовывозе из офиса / склада
    📄 Получить оптовый прайс


    Рассчитайте материалы за 1 минуту

    Кирпич, газоблок, фундамент, брусчатка — точный расчет бесплатно

    ⚡ 4 рабочих инструмента

    🧮 Рассчитайте кирпич

    Количество кирпича, раствора и поддонов для вашего проекта

    ✓ Быстро ✓ Точно ✓ Бесплатно
    Открыть калькулятор →
    🧱

    🏗️ Рассчитайте газоблок

    Газоблоки, клей и вес конструкции для вашего проекта

    ✓ Быстро ✓ Точно ✓ Бесплатно
    Открыть калькулятор →
    🏗️

    🏠 Рассчитайте фундамент

    Бетон, арматура и опалубка для монолитной плиты

    ✓ Быстро ✓ Точно ✓ Бесплатно
    Открыть калькулятор →
    🏠

    🧱 Рассчитайте брусчатку

    Количество плитки, площадь покрытия и цена материала

    ✓ Шт/м² ✓ С запасом 5% ✓ Бесплатно
    Рассчитать плитку →
    🧱

    Лучшие предложения

    Новинка
    Советуем
    Акция
    Хит
    Новинка
    Быстрый просмотр
    кирпич облицовочный, фасадный кирпич, купить облицовочный кирпич, облицовочный кирпич цена, кирпич облицовочный краснодар, фасадный кирпич цена, купить фасадный кирпич
кирпич облицовочный, фасадный кирпич, купить облицовочный кирпич, облицовочный кирпич цена, кирпич облицовочный краснодар, фасадный кирпич цена, купить фасадный кирпич
кирпич облицовочный, фасадный кирпич, купить облицовочный кирпич, облицовочный кирпич цена, кирпич облицовочный краснодар, фасадный кирпич цена, купить фасадный кирпич
кирпич облицовочный, фасадный кирпич, купить облицовочный кирпич, облицовочный кирпич цена, кирпич облицовочный краснодар, фасадный кирпич цена, купить фасадный кирпич
кирпич облицовочный, фасадный кирпич, купить облицовочный кирпич, облицовочный кирпич цена, кирпич облицовочный краснодар, фасадный кирпич цена, купить фасадный кирпич
    73.90 ₽/шт
    Кирпич керамический Бархат Премиум
    0
    Есть в наличии
    В корзину В корзине
    Подробнее
    Формат кирпича : 1.4 НФ
    Новинка
    Быстрый просмотр
    Кирпич керамический Светлый янтарь Премиум Кирпич керамический Светлый янтарь Премиум Кирпич керамический Светлый янтарь Премиум Кирпич керамический Светлый янтарь Премиум Кирпич керамический Светлый янтарь Премиум
    80.90 ₽/шт
    Кирпич керамический Светлый янтарь Премиум
    0
    Есть в наличии
    В корзину В корзине
    Подробнее
    Формат кирпича : 1.4 НФ
    Новинка
    Быстрый просмотр
    Кирпич керамический Белоснежный сатин Премиум Кирпич керамический Белоснежный сатин Премиум Кирпич керамический Белоснежный сатин Премиум
    113.90 ₽/шт
    Кирпич керамический Белоснежный сатин Премиум
    0
    Есть в наличии
    В корзину В корзине
    Подробнее
    Формат кирпича : 1.4 НФ
    Новинка
    Быстрый просмотр
    Кирпич керамический Ниагара Премиум Кирпич керамический Ниагара Премиум
    102.90 ₽/шт
    Кирпич керамический Ниагара Премиум
    0
    Есть в наличии
    В корзину В корзине
    Подробнее
    Формат кирпича : 1.4 НФ
    Новинка
    Быстрый просмотр
    Кирпич керамический Белоснежный матовый Premium Кирпич керамический Белоснежный матовый Premium Кирпич керамический Белоснежный матовый Premium Кирпич керамический Белоснежный матовый Premium Кирпич керамический Белоснежный матовый Premium
    108.90 ₽/шт
    Кирпич керамический Белоснежный матовый Премиум
    0
    Есть в наличии
    В корзину В корзине
    Подробнее
    Формат кирпича : 1.4 НФ
    Напрямую от производителя
    Забутовочный кирпич
    На любой вкус
    Облицовочный кирпич
    По выгодным ценам
    Огромный выбор тротуарной плитки
    от 100 ₽
    Кладочные смеси
    Свое производство
    Жби изделия
    Широкий выбор
    Кровельные материалы
    ППК
    Колпаки и парапеты
    Любого формата
    Газоблок
    Радиаторы отопления оптом!
    Радиаторы
    Доставка от 5000 т.р
    Сантехника
    Широкой выбор для любых задач
    Насосное оборудование
    Гарантия производителя
    Запорная и регулирующая арматура

    Чаще всего покупают

    Новинка
    Советуем
    Акция
    Хит
    Новинка
    Быстрый просмотр
    MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс купить MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс купить MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс купить MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс купить MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс
    30 450 ₽/шт
    MAX-PRO Молоток отбойный электрический 1700 Вт; 200-2100 уд/мин; 45 Дж; SDS-MAX; 11,5 кг; резиновый кабель; дополнительные щетки; кейс
    0
    Есть в наличии
    В корзину В корзине
    Новинка
    Быстрый просмотр
    Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка купить Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка купить Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка купить Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка купить Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка
    3 335 ₽/шт
    Воздуходувка-пылесос 400 Вт; 14000 об/мин; 3000 л/мин; 1,25 кг; БС щеток; коробка
    0
    Есть в наличии
    В корзину В корзине
    Новинка
    Быстрый просмотр
    Временная опора Временная опора Временная опора Временная опора Временная опора
    12 800 ₽/шт
    Временная опора в Краснодаре
    0
    Есть в наличии
    В корзину В корзине
    Новинка
    Быстрый просмотр
    Газобетон
    5 400 ₽/м³
    Газобетонный блок - 625х100х250: цены, размеры, характеристики
    0
    Есть в наличии
    В корзину В корзине
    Новинка
    Быстрый просмотр
    Газобетон
    5 400 ₽/м³
    Газобетонный блок - 625х125х250: цены, размеры, характеристики
    0
    Есть в наличии
    В корзину В корзине

    Акции

    Ограниченная партия кирпича!
    10%
    Не упустите акцию от Строй-С: качественный кирпич с доставкой на дом!
    -10%
    -10% на первый заказ
    до 50%
    Скидки постоянным клиентам

    Статьи и новости

    Гипсовая штукатурка: полное руководство по выбору, нанесению и расчёту
    Блог
    /
    11 августа 2026
    Декоративная штукатурка для стен: полное руководство по выбору и нанесению
    Блог
    /
    11 августа 2026
    Штукатурка стен: полное руководство для новичков и профессионалов
    Блог
    /
    11 августа 2026
    Облицовочный кирпич: полное руководство по видам
    Блог
    /
    28 июля 2026
    Тротуарная плитка: характеристики, виды и сфера применения
    Блог
    /
    13 июня 2026
    Кирпич ручной формовки: особенности, применение и характеристики
    Блог
    /
    1 июля 2025
    Как выбрать надежного производителя кирпича: ключевые критерии
    Блог
    /
    30 июня 2025
    Как рассчитать количество кирпича для строительства дома: формулы + примеры
    Блог
    /
    20 июня 2025
    Виды кирпича: от ручной формовки до современных решений
    Блог
    /
    1 апреля 2025
    Кирпич в строительстве и его преимущества
    Блог
    /
    6 марта 2025

    Бренды

    Кирпичный завод Красная Гвардия
    BRIDGE купить в Краснодаре
    IONICH
    Black&Decker
    WP
    FDW
    Фабрика замков
    SORMAT
    MAX-PRO
    FIT

    Интернет магазин Кирпича

    Кирпич

    в Краснодаре от компании Строй-С

    Приобретите качественный кирпич в Краснодаре от компании Строй-С. Широкий ассортимент, доступные цены и быстрая доставка для вашего строительства.

    О компании
    Интернет-магазин
    Каталог
    Услуги
    Производители
    Компания
    О компании
    Отзывы
    Информация
    Реквизиты
    Магазины
    Акции
    Поставщикам
    Оптовый клуб
    Контакты
    +7 988 365-15-41
    +7 988 365-15-41Татьяна
    +7 861 290-70-50Светлана
    Заказать звонок
    E-mail
    ugstroys@yandex.ru
    Адрес

    г. Краснодар, ул. Ставропольская, 328/1

    Режим работы
    Пн. – Пт.: с 9:00 до 17:30 Сб.: с 9:00 до 15:00 Вс.: Выходной
    ugstroys@yandex.ru

    г. Краснодар, ул. Ставропольская, 328/1

    Мы в соцсетях
    © 2026 Строй-С Указанные на сайте цены не являются публичной офертой (ст.435 ГК РФ).Стоимость и наличие товара просьба уточнять в офисах продаж....
    Конфиденциальность
    Согласие
    Главная Каталог 0 Корзина 0 Избранные Контакты
    CjwhLS0g0JrQvdC+0L/QutCwINGH0LDRgtCwIC0tPgo8ZGl2IGlkPSJtYXgtY2hhdC1idXR0b24iIHN0eWxlPSIKICAgIHBvc2l0aW9uOiBmaXhlZDsKICAgIGJvdHRvbTogNjBweDsKICAgIHJpZ2h0OiAxNXB4OwogICAgd2lkdGg6IDUwcHg7CiAgICBoZWlnaHQ6IDUwcHg7CiAgICBiYWNrZ3JvdW5kOiAjMTQyNTM2OwogICAgYm9yZGVyLXJhZGl1czogNTAlOwogICAgY3Vyc29yOiBwb2ludGVyOwogICAgYm94LXNoYWRvdzogMCA0cHggMTBweCByZ2JhKDIwLDM3LDU0LDAuMyk7CiAgICB6LWluZGV4OiA5OTk5OTk7CiAgICBkaXNwbGF5OiBmbGV4OwogICAgYWxpZ24taXRlbXM6IGNlbnRlcjsKICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOwogICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTsKIj4KICAgIDxkaXYgaWQ9Im1heC1vbmxpbmUtc3RhdHVzIiBzdHlsZT0iCiAgICAgICAgcG9zaXRpb246IGFic29sdXRlOwogICAgICAgIGJvdHRvbTogMnB4OwogICAgICAgIHJpZ2h0OiAycHg7CiAgICAgICAgd2lkdGg6IDEycHg7CiAgICAgICAgaGVpZ2h0OiAxMnB4OwogICAgICAgIGJhY2tncm91bmQ6ICM0YWRlODA7CiAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlOwogICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHdoaXRlOwogICAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4zczsKICAgICI+PC9kaXY+CiAgICA8c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgPHBhdGggZD0iTTIwIDJINGMtMS4xIDAtMiAuOS0yIDJ2MTJjMCAxLjEuOSAyIDIgMmgxNGw0IDRWNGMwLTEuMS0uOS0yLTItMnoiLz4KICAgIDwvc3ZnPgo8L2Rpdj4KCjwhLS0g0JDQutGC0LjQstC90L7QtSDQv9GA0LjQs9C70LDRiNC10L3QuNC1INC6INC00LjQsNC70L7Qs9GDIC0tPgo8ZGl2IGlkPSJtYXgtY2hhdC1pbnZpdGUiIHN0eWxlPSIKICAgIHBvc2l0aW9uOiBmaXhlZDsKICAgIGJvdHRvbTogMTIwcHg7CiAgICByaWdodDogMjBweDsKICAgIGJhY2tncm91bmQ6IHdoaXRlOwogICAgcGFkZGluZzogMTBweCAxNnB4OwogICAgYm9yZGVyLXJhZGl1czogMzBweDsKICAgIGJveC1zaGFkb3c6IDAgNHB4IDIwcHggcmdiYSgwLDAsMCwwLjE1KTsKICAgIGZvbnQtc2l6ZTogMTNweDsKICAgIGNvbG9yOiAjMTQyNTM2OwogICAgZm9udC13ZWlnaHQ6IDUwMDsKICAgIHotaW5kZXg6IDk5OTk5ODsKICAgIGRpc3BsYXk6IG5vbmU7CiAgICBhbGlnbi1pdGVtczogY2VudGVyOwogICAgZ2FwOiA4cHg7CiAgICBib3JkZXI6IDFweCBzb2xpZCAjZTJlOGYwOwogICAgY3Vyc29yOiBwb2ludGVyOwogICAgdHJhbnNpdGlvbjogYWxsIDAuM3M7CiAgICBhbmltYXRpb246IHNsaWRlSW52aXRlIDAuNXMgZWFzZTsKIj4KICAgIDxzcGFuIGlkPSJpbnZpdGUtZW1vamkiPvCfkqw8L3NwYW4+CiAgICA8c3BhbiBpZD0iaW52aXRlLXRleHQiPjxzdHJvbmc+0J3QsNC/0LjRiNC40YLQtSE8L3N0cm9uZz4g0J/QvtC70YPRh9C40YLQtSDQutC+0L3RgdGD0LvRjNGC0LDRhtC40Y4g0LfQsCAxINC80LjQvdGD0YLRgzwvc3Bhbj4KICAgIDxzcGFuIHN0eWxlPSJmb250LXNpemU6IDE2cHg7Ij7ihpI8L3NwYW4+CiAgICA8c3BhbiBpZD0iY2xvc2UtbWF4LWludml0ZSIgc3R5bGU9IgogICAgICAgIG1hcmdpbi1sZWZ0OiA1cHg7CiAgICAgICAgZm9udC1zaXplOiAxOHB4OwogICAgICAgIGNvbG9yOiAjOTRhM2I4OwogICAgICAgIGN1cnNvcjogcG9pbnRlcjsKICAgICAgICBwYWRkaW5nOiAwIDVweDsKICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7CiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuMnM7CiAgICAiIG9uY2xpY2s9ImV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LWNoYXQtaW52aXRlJykucmVtb3ZlKCk7Ij7inJU8L3NwYW4+CjwvZGl2PgoKPCEtLSDQntC60L3QviDRh9Cw0YLQsCBNQVggLS0+CjxkaXYgaWQ9Im1heC1jaGF0LXdpbmRvdyIgc3R5bGU9IgogICAgcG9zaXRpb246IGZpeGVkOwogICAgYm90dG9tOiA3MHB4OwogICAgcmlnaHQ6IDE1cHg7CiAgICB3aWR0aDogMzgwcHg7CiAgICBoZWlnaHQ6IDUyMHB4OwogICAgYmFja2dyb3VuZDogd2hpdGU7CiAgICBib3JkZXItcmFkaXVzOiAxMnB4OwogICAgYm94LXNoYWRvdzogMCA1cHggMzBweCByZ2JhKDAsMCwwLDAuMTUpOwogICAgei1pbmRleDogOTk5OTk5OwogICAgZGlzcGxheTogbm9uZTsKICAgIGJvcmRlcjogbm9uZTsKICAgIG92ZXJmbG93OiBoaWRkZW47CiAgICBmb250LWZhbWlseTogLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCBSb2JvdG8sIHNhbnMtc2VyaWY7CiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBlYXNlOwogICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKIj4KCiAgICA8IS0tINCX0LDQs9C+0LvQvtCy0L7QuiAtLT4KICAgIDxkaXYgc3R5bGU9IgogICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMxNDI1MzYgMCUsICMxYTJmNDQgMTAwJSk7CiAgICAgICAgY29sb3I6IHdoaXRlOwogICAgICAgIHBhZGRpbmc6IDEycHggMTVweDsKICAgICAgICBkaXNwbGF5OiBmbGV4OwogICAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsKICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyOwogICAgICAgIGZsZXgtc2hyaW5rOiAwOwogICAgICAgIGJvcmRlci1yYWRpdXM6IDEycHggMTJweCAwIDA7CiAgICAiPgogICAgICAgIDxkaXYgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyI+CiAgICAgICAgICAgIDxkaXYgaWQ9ImhlYWRlci1zdGF0dXMtZG90IiBzdHlsZT0iCiAgICAgICAgICAgICAgICB3aWR0aDogMTBweDsKICAgICAgICAgICAgICAgIGhlaWdodDogMTBweDsKICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICM0YWRlODA7CiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7CiAgICAgICAgICAgICAgICBhbmltYXRpb246IHB1bHNlIDEuNXMgaW5maW5pdGU7CiAgICAgICAgICAgICAgICBib3gtc2hhZG93OiAwIDAgMTBweCByZ2JhKDc0LDIyMiwxMjgsMC41KTsKICAgICAgICAgICAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4zczsKICAgICAgICAgICAgIj48L2Rpdj4KICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMTZweDsiPtCh0LLQtdGC0LvQsNC90LA8L3NwYW4+CiAgICAgICAgICAgIDxzcGFuIGlkPSJoZWFkZXItc3RhdHVzLXRleHQiIHN0eWxlPSJmb250LXNpemU6IDEycHg7IG9wYWNpdHk6IDAuODsiPm9ubGluZTwvc3Bhbj4KICAgICAgICA8L2Rpdj4KICAgICAgICA8YnV0dG9uIGlkPSJjbG9zZS1tYXgtY2hhdCIgc3R5bGU9IgogICAgICAgICAgICBiYWNrZ3JvdW5kOiBub25lOwogICAgICAgICAgICBib3JkZXI6IG5vbmU7CiAgICAgICAgICAgIGNvbG9yOiB3aGl0ZTsKICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyOwogICAgICAgICAgICBmb250LXNpemU6IDIwcHg7CiAgICAgICAgICAgIHBhZGRpbmc6IDAgNXB4OwogICAgICAgICAgICBvcGFjaXR5OiAwLjg7CiAgICAgICAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMC4yczsKICAgICAgICAiIG9ubW91c2VvdmVyPSJ0aGlzLnN0eWxlLm9wYWNpdHk9JzEnIiBvbm1vdXNlb3V0PSJ0aGlzLnN0eWxlLm9wYWNpdHk9JzAuOCciPuKclTwvYnV0dG9uPgogICAgPC9kaXY+CgogICAgPCEtLSDQntCx0LvQsNGB0YLRjCDRgdC+0L7QsdGJ0LXQvdC40LkgLS0+CiAgICA8ZGl2IGlkPSJtYXgtY2hhdC1tZXNzYWdlcyIgc3R5bGU9IgogICAgICAgIGZsZXg6IDE7CiAgICAgICAgb3ZlcmZsb3cteTogYXV0bzsKICAgICAgICBwYWRkaW5nOiAxMnB4IDE1cHg7CiAgICAgICAgYmFja2dyb3VuZDogI2Y3ZjhmYTsKICAgICAgICBkaXNwbGF5OiBmbGV4OwogICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgICAgICAgZ2FwOiA2cHg7CiAgICAgICAgbWluLWhlaWdodDogMDsKICAgICI+PC9kaXY+CgogICAgPCEtLSDQmNC90LTQuNC60LDRgtC+0YAg0L/QtdGH0LDRgtCw0LXRgiAtLT4KICAgIDxkaXYgaWQ9Im1heC10eXBpbmciIHN0eWxlPSIKICAgICAgICBkaXNwbGF5OiBub25lOwogICAgICAgIHBhZGRpbmc6IDZweCAxNXB4OwogICAgICAgIGJhY2tncm91bmQ6ICNlZGYyZjc7CiAgICAgICAgZm9udC1zaXplOiAxM3B4OwogICAgICAgIGNvbG9yOiAjNGE1NTY4OwogICAgICAgIGZsZXgtc2hyaW5rOiAwOwogICAgICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCAjZTJlOGYwOwogICAgIj7QodCy0LXRgtC70LDQvdCwINC/0LXRh9Cw0YLQsNC10YIuLi48L2Rpdj4KCiAgICA8IS0tINCk0L7RgNC80LAg0LLQstC+0LTQsCAtLT4KICAgIDxkaXYgc3R5bGU9IgogICAgICAgIHBhZGRpbmc6IDEycHggMTVweDsKICAgICAgICBiYWNrZ3JvdW5kOiB3aGl0ZTsKICAgICAgICBib3JkZXItdG9wOiAxcHggc29saWQgI2VkZjJmNzsKICAgICAgICBmbGV4LXNocmluazogMDsKICAgICI+CiAgICAgICAgPGRpdiBpZD0ibWF4LXN0YXR1cyIgc3R5bGU9IgogICAgICAgICAgICBkaXNwbGF5OiBub25lOwogICAgICAgICAgICBtYXJnaW4tYm90dG9tOiA4cHg7CiAgICAgICAgICAgIHBhZGRpbmc6IDZweCAxMHB4OwogICAgICAgICAgICBib3JkZXItcmFkaXVzOiA2cHg7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTNweDsKICAgICAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyOwogICAgICAgICI+PC9kaXY+CgogICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0ibWF4LW5hbWUiIHBsYWNlaG9sZGVyPSLQktCw0YjQtSDQuNC80Y8iIHN0eWxlPSIKICAgICAgICAgICAgd2lkdGg6IDEwMCU7CiAgICAgICAgICAgIHBhZGRpbmc6IDhweCAxMnB4OwogICAgICAgICAgICBtYXJnaW4tYm90dG9tOiA2cHg7CiAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNlMmU4ZjA7CiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDhweDsKICAgICAgICAgICAgZm9udC1zaXplOiAxNHB4OwogICAgICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogICAgICAgICAgICBvdXRsaW5lOiBub25lOwogICAgICAgICAgICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgMC4yczsKICAgICAgICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYzsKICAgICAgICAiPgoKICAgICAgICA8aW5wdXQgdHlwZT0idGVsIiBpZD0ibWF4LXBob25lIiBwbGFjZWhvbGRlcj0i0KLQtdC70LXRhNC+0L0iIHN0eWxlPSIKICAgICAgICAgICAgd2lkdGg6IDEwMCU7CiAgICAgICAgICAgIHBhZGRpbmc6IDhweCAxMnB4OwogICAgICAgICAgICBtYXJnaW4tYm90dG9tOiA2cHg7CiAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNlMmU4ZjA7CiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDhweDsKICAgICAgICAgICAgZm9udC1zaXplOiAxNHB4OwogICAgICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogICAgICAgICAgICBvdXRsaW5lOiBub25lOwogICAgICAgICAgICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgMC4yczsKICAgICAgICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYzsKICAgICAgICAiPgoKICAgICAgICA8ZGl2IHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDsiPgogICAgICAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgaWQ9Im1heC1tZXNzYWdlIiBwbGFjZWhvbGRlcj0i0J3QsNC/0LjRiNC40YLQtSDQstC+0L/RgNC+0YEuLi4iIHN0eWxlPSIKICAgICAgICAgICAgICAgIGZsZXg6IDE7CiAgICAgICAgICAgICAgICBwYWRkaW5nOiA4cHggMTJweDsKICAgICAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNlMmU4ZjA7CiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7CiAgICAgICAgICAgICAgICBmb250LXNpemU6IDE0cHg7CiAgICAgICAgICAgICAgICBvdXRsaW5lOiBub25lOwogICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIDAuMnM7CiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAjZjhmYWZjOwogICAgICAgICAgICAiPgogICAgICAgICAgICA8YnV0dG9uIGlkPSJtYXgtc2VuZCIgc3R5bGU9IgogICAgICAgICAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzE0MjUzNiAwJSwgIzFhMmY0NCAxMDAlKTsKICAgICAgICAgICAgICAgIGNvbG9yOiB3aGl0ZTsKICAgICAgICAgICAgICAgIGJvcmRlcjogbm9uZTsKICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDhweDsKICAgICAgICAgICAgICAgIHBhZGRpbmc6IDhweCAxNnB4OwogICAgICAgICAgICAgICAgZm9udC1zaXplOiAxNnB4OwogICAgICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyOwogICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuMnM7CiAgICAgICAgICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwOwogICAgICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDsKICAgICAgICAgICAgIiBvbm1vdXNlb3Zlcj0idGhpcy5zdHlsZS50cmFuc2Zvcm09J3NjYWxlKDEuMDUpJyIgb25tb3VzZW91dD0idGhpcy5zdHlsZS50cmFuc2Zvcm09J3NjYWxlKDEpJyI+4oaSPC9idXR0b24+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgc3R5bGU9IgogICAgICAgICAgICBtYXJnaW4tdG9wOiA2cHg7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogOXB4OwogICAgICAgICAgICBjb2xvcjogIzk0YTNiODsKICAgICAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyOwogICAgICAgICI+CiAgICAgICAgICAgINCh0L7Qs9C70LDRgdC40LUg0YEgPGEgaHJlZj0iL2luY2x1ZGUvb2ZmZXJfZGV0YWlsLnBocCIgdGFyZ2V0PSJfYmxhbmsiIHN0eWxlPSJjb2xvcjogIzE0MjUzNjsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBmb250LXdlaWdodDogNTAwOyI+0L/QvtC70LjRgtC40LrQvtC5INC60L7QvdGE0LjQtNC10L3RhtC40LDQu9GM0L3QvtGB0YLQuDwvYT4KICAgICAgICA8L2Rpdj4KICAgIDwvZGl2Pgo8L2Rpdj4KCjxzdHlsZT4KICAgIEBrZXlmcmFtZXMgc2xpZGVJbnZpdGUgewogICAgICAgIGZyb20geyBvcGFjaXR5OiAwOyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMjBweCk7IH0KICAgICAgICB0byB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKTsgfQogICAgfQogICAgQGtleWZyYW1lcyBnZW50bGVQdWxzZSB7CiAgICAgICAgMCUgeyB0cmFuc2Zvcm06IHNjYWxlKDEpOyBib3gtc2hhZG93OiAwIDRweCAxMHB4IHJnYmEoMjAsMzcsNTQsMC4zKTsgfQogICAgICAgIDUwJSB7IHRyYW5zZm9ybTogc2NhbGUoMS4wOCk7IGJveC1zaGFkb3c6IDAgOHB4IDIwcHggcmdiYSgyMCwzNyw1NCwwLjUpOyB9CiAgICAgICAgMTAwJSB7IHRyYW5zZm9ybTogc2NhbGUoMSk7IGJveC1zaGFkb3c6IDAgNHB4IDEwcHggcmdiYSgyMCwzNyw1NCwwLjMpOyB9CiAgICB9CiAgICBAa2V5ZnJhbWVzIHB1bHNlIHsKICAgICAgICAwJSwgMTAwJSB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogc2NhbGUoMSk7IH0KICAgICAgICA1MCUgeyBvcGFjaXR5OiAwLjY7IHRyYW5zZm9ybTogc2NhbGUoMC44KTsgfQogICAgfQogICAgCiAgICAvKiDQodGC0LjQu9C4INC00LvRjyDRgdC+0L7QsdGJ0LXQvdC40LkgKi8KICAgIC5tYXgtdXNlci1tZXNzYWdlIHsKICAgICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMTQyNTM2IDAlLCAjMWEyZjQ0IDEwMCUpOwogICAgICAgIGNvbG9yOiB3aGl0ZTsKICAgICAgICBwYWRkaW5nOiA4cHggMTJweDsKICAgICAgICBib3JkZXItcmFkaXVzOiAxNHB4IDE0cHggNHB4IDE0cHg7CiAgICAgICAgbWF4LXdpZHRoOiA4MCU7CiAgICAgICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7CiAgICAgICAgZm9udC1zaXplOiAxNHB4OwogICAgICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDsKICAgICAgICBib3gtc2hhZG93OiAwIDFweCAzcHggcmdiYSgwLDAsMCwwLjEpOwogICAgfQogICAgCiAgICAubWF4LWJvdC1tZXNzYWdlIHsKICAgICAgICBiYWNrZ3JvdW5kOiB3aGl0ZTsKICAgICAgICBwYWRkaW5nOiA4cHggMTJweDsKICAgICAgICBib3JkZXItcmFkaXVzOiAxNHB4IDE0cHggMTRweCA0cHg7CiAgICAgICAgbWF4LXdpZHRoOiA4MCU7CiAgICAgICAgYWxpZ24tc2VsZjogZmxleC1zdGFydDsKICAgICAgICBmb250LXNpemU6IDE0cHg7CiAgICAgICAgd29yZC13cmFwOiBicmVhay13b3JkOwogICAgICAgIGJveC1zaGFkb3c6IDAgMXB4IDNweCByZ2JhKDAsMCwwLDAuMDgpOwogICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNmMGYwZjA7CiAgICB9CiAgICAKICAgIC8qINCk0L7QutGD0YEg0L3QsCDQv9C+0LvRj9GFICovCiAgICBpbnB1dDpmb2N1cyB7CiAgICAgICAgYm9yZGVyLWNvbG9yOiAjMTQyNTM2ICFpbXBvcnRhbnQ7CiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgM3B4IHJnYmEoMjAsMzcsNTQsMC4wOCkgIWltcG9ydGFudDsKICAgICAgICBiYWNrZ3JvdW5kOiB3aGl0ZSAhaW1wb3J0YW50OwogICAgfQogICAgCiAgICAvKiDQpdC+0LLQtdGA0YsgKi8KICAgICNtYXgtY2hhdC1pbnZpdGU6aG92ZXIgewogICAgICAgIGJhY2tncm91bmQ6ICNmOGZhZmM7CiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0ycHgpOwogICAgICAgIGJveC1zaGFkb3c6IDAgNnB4IDI1cHggcmdiYSgwLDAsMCwwLjIpOwogICAgfQogICAgCiAgICAjY2xvc2UtbWF4LWludml0ZTpob3ZlciB7CiAgICAgICAgYmFja2dyb3VuZDogI2UyZThmMDsKICAgICAgICBjb2xvcjogIzQ3NTU2OTsKICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7CiAgICB9CiAgICAKICAgIC8qINCh0LrRgNC+0LvQu9Cx0LDRgCAqLwogICAgI21heC1jaGF0LW1lc3NhZ2VzOjotd2Via2l0LXNjcm9sbGJhciB7CiAgICAgICAgd2lkdGg6IDRweDsKICAgIH0KICAgICNtYXgtY2hhdC1tZXNzYWdlczo6LXdlYmtpdC1zY3JvbGxiYXItdHJhY2sgewogICAgICAgIGJhY2tncm91bmQ6ICNmMWYxZjE7CiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDsKICAgIH0KICAgICNtYXgtY2hhdC1tZXNzYWdlczo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIgewogICAgICAgIGJhY2tncm91bmQ6ICMxNDI1MzY7CiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDsKICAgIH0KICAgICNtYXgtY2hhdC1tZXNzYWdlczo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXIgewogICAgICAgIGJhY2tncm91bmQ6ICMxYTJmNDQ7CiAgICB9CgogICAgLyogPT09PT0g0JzQntCR0JjQm9Cs0J3QkNCvINCS0JXQoNCh0JjQryAtINCf0J7Qm9Cd0KvQmSDQrdCa0KDQkNCdID09PT09ICovCiAgICBAbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHsKICAgICAgICAjbWF4LWNoYXQtd2luZG93IHsKICAgICAgICAgICAgcG9zaXRpb246IGZpeGVkICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIGJvdHRvbTogMCAhaW1wb3J0YW50OwogICAgICAgICAgICByaWdodDogMCAhaW1wb3J0YW50OwogICAgICAgICAgICBsZWZ0OiAwICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIHRvcDogMCAhaW1wb3J0YW50OwogICAgICAgICAgICB3aWR0aDogMTAwJSAhaW1wb3J0YW50OwogICAgICAgICAgICBoZWlnaHQ6IDEwMCUgIWltcG9ydGFudDsKICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMCAhaW1wb3J0YW50OwogICAgICAgICAgICBib3gtc2hhZG93OiBub25lICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIHotaW5kZXg6IDk5OTk5OSAhaW1wb3J0YW50OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAjbWF4LWNoYXQtd2luZG93ID4gZGl2OmZpcnN0LWNoaWxkIHsKICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMCAhaW1wb3J0YW50OwogICAgICAgICAgICBwYWRkaW5nOiAxNHB4IDE2cHggIWltcG9ydGFudDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgI21heC1jaGF0LW1lc3NhZ2VzIHsKICAgICAgICAgICAgcGFkZGluZzogMTRweCAxNnB4ICFpbXBvcnRhbnQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICNtYXgtY2hhdC13aW5kb3cgPiBkaXY6bGFzdC1jaGlsZCB7CiAgICAgICAgICAgIHBhZGRpbmc6IDE0cHggMTZweCAhaW1wb3J0YW50OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAjbWF4LWNoYXQtd2luZG93IGlucHV0IHsKICAgICAgICAgICAgcGFkZGluZzogMTBweCAxMnB4ICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTZweCAhaW1wb3J0YW50OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAjbWF4LWNoYXQtYnV0dG9uIHsKICAgICAgICAgICAgYm90dG9tOiAxMTVweCAhaW1wb3J0YW50OwogICAgICAgICAgICByaWdodDogMTVweCAhaW1wb3J0YW50OwogICAgICAgICAgICB3aWR0aDogNTVweCAhaW1wb3J0YW50OwogICAgICAgICAgICBoZWlnaHQ6IDU1cHggIWltcG9ydGFudDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgI21heC1jaGF0LWludml0ZSB7CiAgICAgICAgICAgIGJvdHRvbTogMTMwcHggIWltcG9ydGFudDsKICAgICAgICAgICAgcmlnaHQ6IDE1cHggIWltcG9ydGFudDsKICAgICAgICAgICAgcGFkZGluZzogMTBweCAxNnB4ICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTRweCAhaW1wb3J0YW50OwogICAgICAgICAgICBtYXgtd2lkdGg6IGNhbGMoMTAwJSAtIDMwcHgpICFpbXBvcnRhbnQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICNtYXgtY2hhdC1tZXNzYWdlcyAubWF4LWJvdC1tZXNzYWdlLAogICAgICAgICNtYXgtY2hhdC1tZXNzYWdlcyAubWF4LXVzZXItbWVzc2FnZSB7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTVweCAhaW1wb3J0YW50OwogICAgICAgICAgICBwYWRkaW5nOiAxMHB4IDE0cHggIWltcG9ydGFudDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgI21heC1zZW5kIHsKICAgICAgICAgICAgcGFkZGluZzogMTBweCAxOHB4ICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMThweCAhaW1wb3J0YW50OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBAa2V5ZnJhbWVzIHNsaWRlVXAgewogICAgICAgICAgICBmcm9tIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDEwMCUpOyB9CiAgICAgICAgICAgIHRvIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApOyB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgICNtYXgtY2hhdC13aW5kb3cub3Blbi1tb2JpbGUgewogICAgICAgICAgICBhbmltYXRpb246IHNsaWRlVXAgMC4zcyBlYXNlIGZvcndhcmRzOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyog0J/Qu9Cw0L3RiNC10YLRiyAqLwogICAgQG1lZGlhIChtaW4td2lkdGg6IDc2OXB4KSBhbmQgKG1heC13aWR0aDogMTAyNHB4KSB7CiAgICAgICAgI21heC1jaGF0LXdpbmRvdyB7CiAgICAgICAgICAgIHdpZHRoOiA0MDBweCAhaW1wb3J0YW50OwogICAgICAgICAgICBoZWlnaHQ6IDU1MHB4ICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIGJvdHRvbTogODBweCAhaW1wb3J0YW50OwogICAgICAgICAgICByaWdodDogMjBweCAhaW1wb3J0YW50OwogICAgICAgIH0KICAgIH0KPC9zdHlsZT4KCjxzY3JpcHQ+CmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbigpIHsKICAgIC8vID09PT09INCj0J3QmNCa0JDQm9Cs0J3Qq9CZIElEINCh0JXQodCh0JjQmCDQlNCb0K8g0JrQkNCW0JTQntCT0J4g0JrQm9CY0JXQndCi0JAgPT09PT0KICAgIGxldCBzZXNzaW9uSWQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbWF4X3Nlc3Npb25faWQnKTsKICAgIGlmICghc2Vzc2lvbklkKSB7CiAgICAgICAgc2Vzc2lvbklkID0gJ2NsaWVudF8nICsgRGF0ZS5ub3coKSArICdfJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KTsKICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbWF4X3Nlc3Npb25faWQnLCBzZXNzaW9uSWQpOwogICAgfQogICAgCiAgICAvLyA9PT09PSDQntCf0KDQldCU0JXQm9CV0J3QmNCVINCS0KDQldCc0JXQndCYID09PT09CiAgICBmdW5jdGlvbiBnZXRUaW1lU3RhdHVzKCkgewogICAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7CiAgICAgICAgY29uc3QgaG91cnMgPSBub3cuZ2V0SG91cnMoKTsKICAgICAgICBjb25zdCBtaW51dGVzID0gbm93LmdldE1pbnV0ZXMoKTsKICAgICAgICBjb25zdCB0aW1lID0gaG91cnMgKyBtaW51dGVzIC8gNjA7CiAgICAgICAgCiAgICAgICAgLy8g0KDQsNCx0L7Rh9C10LUg0LLRgNC10LzRjzog0YEgOTowMCDQtNC+IDE4OjAwCiAgICAgICAgY29uc3QgaXNXb3JraW5nSG91cnMgPSB0aW1lID49IDkgJiYgdGltZSA8IDE4OwogICAgICAgIAogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGlzV29ya2luZzogaXNXb3JraW5nSG91cnMsCiAgICAgICAgICAgIGhvdXJzOiBob3VycywKICAgICAgICAgICAgbWludXRlczogbWludXRlcwogICAgICAgIH07CiAgICB9CiAgICAKICAgIC8vID09PT09INCf0KDQmNCc0JXQndCV0J3QmNCVINCh0KLQkNCi0KPQodCQID09PT09CiAgICBmdW5jdGlvbiBhcHBseVRpbWVTdGF0dXMoKSB7CiAgICAgICAgY29uc3Qgc3RhdHVzID0gZ2V0VGltZVN0YXR1cygpOwogICAgICAgIGNvbnN0IHN0YXR1c0RvdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXgtb25saW5lLXN0YXR1cycpOwogICAgICAgIGNvbnN0IGhlYWRlckRvdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXItc3RhdHVzLWRvdCcpOwogICAgICAgIGNvbnN0IGhlYWRlclRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhZGVyLXN0YXR1cy10ZXh0Jyk7CiAgICAgICAgY29uc3QgaW52aXRlRW1vamkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW52aXRlLWVtb2ppJyk7CiAgICAgICAgY29uc3QgaW52aXRlVGV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbnZpdGUtdGV4dCcpOwogICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXgtY2hhdC1idXR0b24nKTsKICAgICAgICBjb25zdCB0eXBpbmdJbmRpY2F0b3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LXR5cGluZycpOwogICAgICAgIAogICAgICAgIGlmIChzdGF0dXMuaXNXb3JraW5nKSB7CiAgICAgICAgICAgIC8vINCU0L3QtdCy0L3QvtC5INGA0LXQttC40LwgLSDQvtC90LvQsNC50L0KICAgICAgICAgICAgc3RhdHVzRG90LnN0eWxlLmJhY2tncm91bmQgPSAnIzRhZGU4MCc7CiAgICAgICAgICAgIGhlYWRlckRvdC5zdHlsZS5iYWNrZ3JvdW5kID0gJyM0YWRlODAnOwogICAgICAgICAgICBoZWFkZXJEb3Quc3R5bGUuYm94U2hhZG93ID0gJzAgMCAxMHB4IHJnYmEoNzQsMjIyLDEyOCwwLjUpJzsKICAgICAgICAgICAgaGVhZGVyRG90LnN0eWxlLmFuaW1hdGlvbiA9ICdwdWxzZSAxLjVzIGluZmluaXRlJzsKICAgICAgICAgICAgaGVhZGVyVGV4dC50ZXh0Q29udGVudCA9ICdvbmxpbmUnOwogICAgICAgICAgICBoZWFkZXJUZXh0LnN0eWxlLm9wYWNpdHkgPSAnMC44JzsKICAgICAgICAgICAgCiAgICAgICAgICAgIGludml0ZUVtb2ppLnRleHRDb250ZW50ID0gJ/CfkqwnOwogICAgICAgICAgICBpbnZpdGVUZXh0LmlubmVySFRNTCA9ICc8c3Ryb25nPtCd0LDQv9C40YjQuNGC0LUhPC9zdHJvbmc+INCf0L7Qu9GD0YfQuNGC0LUg0LrQvtC90YHRg9C70YzRgtCw0YbQuNGOINC30LAgMSDQvNC40L3Rg9GC0YMnOwogICAgICAgICAgICAKICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmJveFNoYWRvdyA9ICcwIDRweCAxMHB4IHJnYmEoMjAsMzcsNTQsMC4zKSc7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyDQnNC10L3Rj9C10Lwg0YLQtdC60YHRgiDQv9GA0LjQstC10YLRgdGC0LLQuNGPCiAgICAgICAgICAgIHdpbmRvdy5jaGF0V2VsY29tZU1lc3NhZ2UgPSBgCiAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iY29sb3I6IzE0MjUzNjsgZm9udC13ZWlnaHQ6NjAwOyI+0KHQstC10YLQu9Cw0L3QsDwvc3Bhbj48YnI+CiAgICAgICAgICAgICAgICDwn5GLINCX0LTRgNCw0LLRgdGC0LLRg9C50YLQtSE8YnI+CiAgICAgICAgICAgICAgICA8c3Ryb25nPtCd0LDQv9C40YjQuNGC0LUg0YHQstC+0Lkg0LLQvtC/0YDQvtGBPC9zdHJvbmc+IOKAlCDRjyDQvtGC0LLQtdGH0YMg0YfQtdGA0LXQtyDQvNC40L3Rg9GC0YMhPGJyPgogICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTogMTNweDsgY29sb3I6ICM2NDc0OGI7Ij7Qn9C+0LzQvtCz0YMg0L/QvtC00L7QsdGA0LDRgtGMINC80LDRgtC10YDQuNCw0LssINGA0LDRgdGB0YfQuNGC0LDRgtGMINGB0YLQvtC40LzQvtGB0YLRjCDQuNC70Lgg0L7RgtCy0LXRh9GDINC90LAg0LvRjtCx0L7QuSDQstC+0L/RgNC+0YE8L3NwYW4+CiAgICAgICAgICAgIGA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8g0JLQtdGH0LXRgNC90LjQuSDRgNC10LbQuNC8IC0g0L7RhNC70LDQudC9CiAgICAgICAgICAgIHN0YXR1c0RvdC5zdHlsZS5iYWNrZ3JvdW5kID0gJyM5NGEzYjgnOwogICAgICAgICAgICBoZWFkZXJEb3Quc3R5bGUuYmFja2dyb3VuZCA9ICcjOTRhM2I4JzsKICAgICAgICAgICAgaGVhZGVyRG90LnN0eWxlLmJveFNoYWRvdyA9ICdub25lJzsKICAgICAgICAgICAgaGVhZGVyRG90LnN0eWxlLmFuaW1hdGlvbiA9ICdub25lJzsKICAgICAgICAgICAgaGVhZGVyVGV4dC50ZXh0Q29udGVudCA9ICfQvtGE0LvQsNC50L0nOwogICAgICAgICAgICBoZWFkZXJUZXh0LnN0eWxlLm9wYWNpdHkgPSAnMC42JzsKICAgICAgICAgICAgCiAgICAgICAgICAgIGludml0ZUVtb2ppLnRleHRDb250ZW50ID0gJ/CfjJknOwogICAgICAgICAgICBpbnZpdGVUZXh0LmlubmVySFRNTCA9ICc8c3Ryb25nPtCc0Ysg0L7RgtC+0YjQu9C4ITwvc3Ryb25nPiDQntGB0YLQsNCy0YzRgtC1INC90L7QvNC10YAg4oCUINC+0YLQstC10YLQuNC8INGD0YLRgNC+0LwnOwogICAgICAgICAgICAKICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmJveFNoYWRvdyA9ICcwIDRweCAxMHB4IHJnYmEoMTQ4LDE2MywxODQsMC4zKSc7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyDQnNC10L3Rj9C10Lwg0YLQtdC60YHRgiDQv9GA0LjQstC10YLRgdGC0LLQuNGPCiAgICAgICAgICAgIHdpbmRvdy5jaGF0V2VsY29tZU1lc3NhZ2UgPSBgCiAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iY29sb3I6IzE0MjUzNjsgZm9udC13ZWlnaHQ6NjAwOyI+0KHQstC10YLQu9Cw0L3QsDwvc3Bhbj48YnI+CiAgICAgICAgICAgICAgICDwn4yZINCU0L7QsdGA0YvQuSDQstC10YfQtdGAITxicj4KICAgICAgICAgICAgICAgIDxzdHJvbmc+0JzRiyDRgdC10LnRh9Cw0YEg0L3QtSDQvtC90LvQsNC50L08L3N0cm9uZz4sINC90L4g0LXRgdC70Lgg0LLRiyDQvtGB0YLQsNCy0LjRgtC1INC90L7QvNC10YAg0Lgg0LLQsNGIINCy0L7Qv9GA0L7RgSDigJQ8YnI+CiAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iZm9udC1zaXplOiAxM3B4OyBjb2xvcjogIzY0NzQ4YjsiPtC80Ysg0L7RgtCy0LXRgtC40Lwg0LLQsNC8INGD0YLRgNC+0Lwg0YEgOTowMCEg8J+Sqzwvc3Bhbj4KICAgICAgICAgICAgYDsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vINCc0LXQvdGP0LXQvCDRgtC10LrRgdGCINCyINC/0L7Qu9C1INGB0L7QvtCx0YnQtdC90LjRjwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LW1lc3NhZ2UnKS5wbGFjZWhvbGRlciA9ICfQntGB0YLQsNCy0YzRgtC1INCy0L7Qv9GA0L7RgS4uLic7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyDQn9GA0LjQvNC10L3Rj9C10Lwg0YHRgtCw0YLRg9GBINC/0YDQuCDQt9Cw0LPRgNGD0LfQutC1CiAgICBhcHBseVRpbWVTdGF0dXMoKTsKICAgIAogICAgLy8g0J7QsdC90L7QstC70Y/QtdC8INGB0YLQsNGC0YPRgSDQutCw0LbQtNGD0Y4g0LzQuNC90YPRgtGDCiAgICBzZXRJbnRlcnZhbChhcHBseVRpbWVTdGF0dXMsIDYwMDAwKTsKICAgIAogICAgbGV0IGNoYXRJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtYXhfY2hhdF9pZCcpOwogICAgCiAgICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LWNoYXQtYnV0dG9uJyk7CiAgICBjb25zdCBjaGF0V2luZG93ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21heC1jaGF0LXdpbmRvdycpOwogICAgY29uc3QgY2xvc2VCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvc2UtbWF4LWNoYXQnKTsKICAgIGNvbnN0IHNlbmRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LXNlbmQnKTsKICAgIGNvbnN0IHN0YXR1c0RpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXgtc3RhdHVzJyk7CiAgICBjb25zdCBtZXNzYWdlc0FyZWEgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LWNoYXQtbWVzc2FnZXMnKTsKICAgIGNvbnN0IHR5cGluZ0luZGljYXRvciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXgtdHlwaW5nJyk7CiAgICBjb25zdCBuYW1lSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LW5hbWUnKTsKICAgIGNvbnN0IHBob25lSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LXBob25lJyk7CiAgICBjb25zdCBtZXNzYWdlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF4LW1lc3NhZ2UnKTsKICAgIGNvbnN0IGludml0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXgtY2hhdC1pbnZpdGUnKTsKICAgIAogICAgY29uc3QgQVBJX1VSTCA9ICcvaW5jbHVkZS9tYXgtYm90L2FwaS5waHAnOwogICAgCiAgICBjb25zdCBpc01vYmlsZSA9IHdpbmRvdy5pbm5lcldpZHRoIDw9IDc2ODsKCiAgICAvLyA9PT09PSDQpNCj0J3QmtCm0JjQryDQntCi0JrQoNCr0KLQmNCvINCn0JDQotCQID09PT09CiAgICBmdW5jdGlvbiBvcGVuQ2hhdCgpIHsKICAgICAgICBjaGF0V2luZG93LnN0eWxlLmRpc3BsYXkgPSAnZmxleCc7CiAgICAgICAgYnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgYnV0dG9uLnN0eWxlLmFuaW1hdGlvbiA9ICcnOwogICAgICAgIAogICAgICAgIGlmIChpc01vYmlsZSkgewogICAgICAgICAgICBjaGF0V2luZG93LmNsYXNzTGlzdC5hZGQoJ29wZW4tbW9iaWxlJyk7CiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJzsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8g0JTQvtCx0LDQstC70Y/QtdC8INC/0YDQuNCy0LXRgtGB0YLQstC10L3QvdC+0LUg0YHQvtC+0LHRidC10L3QuNC1INGC0L7Qu9GM0LrQviDQtdGB0LvQuCDRh9Cw0YIg0L7RgtC60YDRi9GCINCy0L/QtdGA0LLRi9C1CiAgICAgICAgaWYgKCFzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdtYXhfY2hhdF9vcGVuZWQnKSkgewogICAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdtYXhfY2hhdF9vcGVuZWQnLCAndHJ1ZScpOwogICAgICAgICAgICBzZXRUaW1lb3V0KGFkZFdlbGNvbWVNZXNzYWdlLCAzMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaW52aXRlICYmIGludml0ZS5wYXJlbnROb2RlKSBpbnZpdGUucmVtb3ZlKCk7CiAgICAgICAgc3RhcnRQb2xsaW5nKCk7CiAgICB9CgogICAgLy8gPT09PT0g0KTQo9Cd0JrQptCY0K8g0JTQntCR0JDQktCb0JXQndCY0K8g0J/QoNCY0JLQldCi0KHQotCS0JjQryA9PT09PQogICAgZnVuY3Rpb24gYWRkV2VsY29tZU1lc3NhZ2UoKSB7CiAgICAgICAgY29uc3Qgd2VsY29tZURpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIHdlbGNvbWVEaXYuY2xhc3NOYW1lID0gJ21heC1ib3QtbWVzc2FnZSc7CiAgICAgICAgd2VsY29tZURpdi5pbm5lckhUTUwgPSB3aW5kb3cuY2hhdFdlbGNvbWVNZXNzYWdlIHx8IGAKICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImNvbG9yOiMxNDI1MzY7IGZvbnQtd2VpZ2h0OjYwMDsiPtCh0LLQtdGC0LvQsNC90LA8L3NwYW4+PGJyPgogICAgICAgICAgICDwn5GLINCX0LTRgNCw0LLRgdGC0LLRg9C50YLQtSE8YnI+CiAgICAgICAgICAgIDxzdHJvbmc+0J3QsNC/0LjRiNC40YLQtSDRgdCy0L7QuSDQstC+0L/RgNC+0YE8L3N0cm9uZz4g4oCUINGPINC+0YLQstC10YfRgyDRh9C10YDQtdC3INC80LjQvdGD0YLRgyE8YnI+CiAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJmb250LXNpemU6IDEzcHg7IGNvbG9yOiAjNjQ3NDhiOyI+0J/QvtC80L7Qs9GDINC/0L7QtNC+0LHRgNCw0YLRjCDQvNCw0YLQtdGA0LjQsNC7LCDRgNCw0YHRgdGH0LjRgtCw0YLRjCDRgdGC0L7QuNC80L7RgdGC0Ywg0LjQu9C4INC+0YLQstC10YfRgyDQvdCwINC70Y7QsdC+0Lkg0LLQvtC/0YDQvtGBPC9zcGFuPgogICAgICAgIGA7CiAgICAgICAgbWVzc2FnZXNBcmVhLmFwcGVuZENoaWxkKHdlbGNvbWVEaXYpOwogICAgICAgIG1lc3NhZ2VzQXJlYS5zY3JvbGxUb3AgPSBtZXNzYWdlc0FyZWEuc2Nyb2xsSGVpZ2h0OwogICAgICAgIAogICAgICAgIHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICBtZXNzYWdlSW5wdXQuZm9jdXMoKTsKICAgICAgICB9LCA1MDApOwogICAgfQoKICAgIC8vID09PT09INCa0J3QntCf0JrQkCDQntCi0JrQoNCr0KLQmNCvID09PT09CiAgICBidXR0b24ub25jbGljayA9IGZ1bmN0aW9uKCkgeyBvcGVuQ2hhdCgpOyB9OwoKICAgIGZ1bmN0aW9uIGFkZE1lc3NhZ2UodGV4dCwgaXNVc2VyID0gdHJ1ZSkgewogICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIGRpdi5jbGFzc05hbWUgPSBpc1VzZXIgPyAnbWF4LXVzZXItbWVzc2FnZScgOiAnbWF4LWJvdC1tZXNzYWdlJzsKICAgICAgICBpZiAoIWlzVXNlcikgewogICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gJzxzcGFuIHN0eWxlPSJjb2xvcjojMTQyNTM2OyBmb250LXdlaWdodDo2MDA7Ij7QodCy0LXRgtC70LDQvdCwPC9zcGFuPjxicj4nICsgdGV4dDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0OwogICAgICAgIH0KICAgICAgICBtZXNzYWdlc0FyZWEuYXBwZW5kQ2hpbGQoZGl2KTsKICAgICAgICBtZXNzYWdlc0FyZWEuc2Nyb2xsVG9wID0gbWVzc2FnZXNBcmVhLnNjcm9sbEhlaWdodDsKICAgICAgICBzYXZlTWVzc2FnZVRvSGlzdG9yeSh0ZXh0LCBpc1VzZXIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzYXZlTWVzc2FnZVRvSGlzdG9yeSh0ZXh0LCBpc1VzZXIpIHsKICAgICAgICBjb25zdCBoaXN0b3J5ID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbWF4X2NoYXRfaGlzdG9yeV8nICsgc2Vzc2lvbklkKSB8fCAnW10nKTsKICAgICAgICBoaXN0b3J5LnB1c2goeyB0ZXh0OiB0ZXh0LCBpc1VzZXI6IGlzVXNlciwgdGltZTogRGF0ZS5ub3coKSB9KTsKICAgICAgICBpZiAoaGlzdG9yeS5sZW5ndGggPiA1MCkgaGlzdG9yeS5zaGlmdCgpOwogICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtYXhfY2hhdF9oaXN0b3J5XycgKyBzZXNzaW9uSWQsIEpTT04uc3RyaW5naWZ5KGhpc3RvcnkpKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gbG9hZEhpc3RvcnkoKSB7CiAgICAgICAgY29uc3QgaGlzdG9yeSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ21heF9jaGF0X2hpc3RvcnlfJyArIHNlc3Npb25JZCkgfHwgJ1tdJyk7CiAgICAgICAgbWVzc2FnZXNBcmVhLmlubmVySFRNTCA9ICcnOwogICAgICAgIGhpc3RvcnkuZm9yRWFjaChtc2cgPT4gewogICAgICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICAgICAgZGl2LmNsYXNzTmFtZSA9IG1zZy5pc1VzZXIgPyAnbWF4LXVzZXItbWVzc2FnZScgOiAnbWF4LWJvdC1tZXNzYWdlJzsKICAgICAgICAgICAgaWYgKCFtc2cuaXNVc2VyKSB7CiAgICAgICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gJzxzcGFuIHN0eWxlPSJjb2xvcjojMTQyNTM2OyBmb250LXdlaWdodDo2MDA7Ij7QodCy0LXRgtC70LDQvdCwPC9zcGFuPjxicj4nICsgbXNnLnRleHQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkaXYudGV4dENvbnRlbnQgPSBtc2cudGV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBtZXNzYWdlc0FyZWEuYXBwZW5kQ2hpbGQoZGl2KTsKICAgICAgICB9KTsKICAgICAgICBtZXNzYWdlc0FyZWEuc2Nyb2xsVG9wID0gbWVzc2FnZXNBcmVhLnNjcm9sbEhlaWdodDsKICAgIH0KCiAgICBmdW5jdGlvbiBzaG93U3RhdHVzKHRleHQsIGlzRXJyb3IpIHsKICAgICAgICBzdGF0dXNEaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7CiAgICAgICAgc3RhdHVzRGl2LnRleHRDb250ZW50ID0gdGV4dDsKICAgICAgICBzdGF0dXNEaXYuc3R5bGUuYmFja2dyb3VuZCA9IGlzRXJyb3IgPyAnI2ZlZTJlMicgOiAnI2RjZmNlNyc7CiAgICAgICAgc3RhdHVzRGl2LnN0eWxlLmNvbG9yID0gaXNFcnJvciA/ICcjZGMyNjI2JyA6ICcjMTZhMzRhJzsKICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN0YXR1c0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnLCAzMDAwKTsKICAgIH0KCiAgICAvLyA9PT09PSDQntCi0J/QoNCQ0JLQmtCQID09PT09CiAgICBhc3luYyBmdW5jdGlvbiBzZW5kVG9NYXgoKSB7CiAgICAgICAgY29uc3QgbmFtZSA9IG5hbWVJbnB1dC52YWx1ZS50cmltKCk7CiAgICAgICAgY29uc3QgcGhvbmUgPSBwaG9uZUlucHV0LnZhbHVlLnRyaW0oKTsKICAgICAgICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZUlucHV0LnZhbHVlLnRyaW0oKTsKCiAgICAgICAgaWYgKCFuYW1lIHx8ICFwaG9uZSB8fCAhbWVzc2FnZSkgewogICAgICAgICAgICBzaG93U3RhdHVzKCfQl9Cw0L/QvtC70L3QuNGC0LUg0LLRgdC1INC/0L7Qu9GPJywgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgY29uc3QgcGhvbmVEaWdpdHMgPSBwaG9uZS5yZXBsYWNlKC9cRC9nLCAnJyk7CiAgICAgICAgaWYgKHBob25lRGlnaXRzLmxlbmd0aCA8IDEwKSB7CiAgICAgICAgICAgIHNob3dTdGF0dXMoJ9CS0LLQtdC00LjRgtC1INC60L7RgNGA0LXQutGC0L3Ri9C5INC90L7QvNC10YAgKNC80LjQvS4gMTAg0YbQuNGE0YApJywgdHJ1ZSk7CiAgICAgICAgICAgIHBob25lSW5wdXQuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZGMyNjI2JzsKICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBwaG9uZUlucHV0LnN0eWxlLmJvcmRlciA9ICcnLCAyMDAwKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoL14oXGQpXDF7MTB9JC8udGVzdChwaG9uZURpZ2l0cykpIHsKICAgICAgICAgICAgc2hvd1N0YXR1cygn0JLQstC10LTQuNGC0LUg0YDQtdCw0LvRjNC90YvQuSDQvdC+0LzQtdGAINGC0LXQu9C10YTQvtC90LAnLCB0cnVlKTsKICAgICAgICAgICAgcGhvbmVJbnB1dC5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkICNkYzI2MjYnOwogICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHBob25lSW5wdXQuc3R5bGUuYm9yZGVyID0gJycsIDIwMDApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBhZGRNZXNzYWdlKG1lc3NhZ2UsIHRydWUpOwogICAgICAgIG1lc3NhZ2VJbnB1dC52YWx1ZSA9ICcnOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOwogICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2FjdGlvbicsICdzZW5kJyk7CiAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnbmFtZScsIG5hbWUpOwogICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ3Bob25lJywgcGhvbmUpOwogICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ21lc3NhZ2UnLCBtZXNzYWdlKTsKICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdwYWdlX3VybCcsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTsKICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdwYWdlX3RpdGxlJywgZG9jdW1lbnQudGl0bGUpOwogICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ3Nlc3Npb25faWQnLCBzZXNzaW9uSWQpOwogICAgICAgICAgICAKICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChBUElfVVJMLCB7IG1ldGhvZDogJ1BPU1QnLCBib2R5OiBmb3JtRGF0YSB9KTsKICAgICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IGdldFRpbWVTdGF0dXMoKTsKICAgICAgICAgICAgICAgIGlmIChzdGF0dXMuaXNXb3JraW5nKSB7CiAgICAgICAgICAgICAgICAgICAgc2hvd1N0YXR1cygn4pyTINCe0YLQv9GA0LDQstC70LXQvdC+ISDQodCy0LXRgtC70LDQvdCwINC+0YLQstC10YLQuNGCINCyINGH0LDRgtC1JywgZmFsc2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzaG93U3RhdHVzKCfinJMg0J7RgtC/0YDQsNCy0LvQtdC90L4hINCe0YLQstC10YLQuNC8INCy0LDQvCDRg9GC0YDQvtC8INGBIDk6MDAnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWNoYXRJZCAmJiBkYXRhLmNoYXRfaWQpIHsKICAgICAgICAgICAgICAgICAgICBjaGF0SWQgPSBkYXRhLmNoYXRfaWQ7CiAgICAgICAgICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21heF9jaGF0X2lkJywgY2hhdElkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNob3dTdGF0dXMoZGF0YS5lcnJvciB8fCAn0J7RiNC40LHQutCwINC+0YLQv9GA0LDQstC60LgnLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGVycm9yKTsKICAgICAgICAgICAgc2hvd1N0YXR1cygn0J7RiNC40LHQutCwINGB0L7QtdC00LjQvdC10L3QuNGPJywgdHJ1ZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vID09PT09INCf0J7Qm9Cb0JjQndCTID09PT09CiAgICBsZXQgcG9sbGluZ0ludGVydmFsID0gbnVsbDsKICAgIAogICAgZnVuY3Rpb24gc3RhcnRQb2xsaW5nKCkgewogICAgICAgIGlmIChwb2xsaW5nSW50ZXJ2YWwpIGNsZWFySW50ZXJ2YWwocG9sbGluZ0ludGVydmFsKTsKICAgICAgICBwb2xsaW5nSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7CiAgICAgICAgICAgIGlmIChjaGF0V2luZG93LnN0eWxlLmRpc3BsYXkgIT09ICdmbGV4JykgcmV0dXJuOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtBUElfVVJMfT9hY3Rpb249Z2V0LXJlcGx5JnNlc3Npb25faWQ9JHtzZXNzaW9uSWR9YCk7CiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpOwogICAgICAgICAgICAgICAgaWYgKGRhdGEuaGFzX3JlcGx5KSB7CiAgICAgICAgICAgICAgICAgICAgdHlwaW5nSW5kaWNhdG9yLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgICAgICAgICAgICAgYWRkTWVzc2FnZShkYXRhLm1lc3NhZ2UsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsgY29uc29sZS5lcnJvcignUG9sbGluZyBlcnJvcjonLCBlcnJvcik7IH0KICAgICAgICB9LCAzMDAwKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3RvcFBvbGxpbmcoKSB7CiAgICAgICAgaWYgKHBvbGxpbmdJbnRlcnZhbCkgeyBjbGVhckludGVydmFsKHBvbGxpbmdJbnRlcnZhbCk7IHBvbGxpbmdJbnRlcnZhbCA9IG51bGw7IH0KICAgIH0KCiAgICAvLyA9PT09PSDQntCR0KDQkNCR0J7QotCn0JjQmtCYID09PT09CiAgICBjbG9zZUJ0bi5vbmNsaWNrID0gKCkgPT4gewogICAgICAgIGNoYXRXaW5kb3cuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICAgICAgICBjaGF0V2luZG93LmNsYXNzTGlzdC5yZW1vdmUoJ29wZW4tbW9iaWxlJyk7CiAgICAgICAgYnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnZmxleCc7CiAgICAgICAgdHlwaW5nSW5kaWNhdG9yLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgc3RvcFBvbGxpbmcoKTsKICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7CiAgICB9OwoKICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4gewogICAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgJiYgY2hhdFdpbmRvdy5zdHlsZS5kaXNwbGF5ID09PSAnZmxleCcpIGNsb3NlQnRuLm9uY2xpY2soKTsKICAgIH0pOwoKICAgIHNlbmRCdG4ub25jbGljayA9IHNlbmRUb01heDsKICAgIG1lc3NhZ2VJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlwcmVzcycsIChlKSA9PiB7CiAgICAgICAgaWYgKGUua2V5ID09PSAnRW50ZXInICYmICFlLnNoaWZ0S2V5KSB7IGUucHJldmVudERlZmF1bHQoKTsgc2VuZFRvTWF4KCk7IH0KICAgIH0pOwoKICAgIC8vID09PT09INCc0JDQodCa0JAg0JTQm9CvINCi0JXQm9CV0KTQntCd0JAgKNCe0KDQmNCT0JjQndCQ0JvQrNCd0JDQrykgPT09PT0KICAgIHBob25lSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbihlKSB7CiAgICAgICAgbGV0IHZhbHVlID0gZS50YXJnZXQudmFsdWUucmVwbGFjZSgvXEQvZywgJycpOwogICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPiAxMSkgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLCAxMSk7CiAgICAgICAgCiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA8PSAxKSB2YWx1ZSA9ICcrNyc7CiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA8PSA0KSB2YWx1ZSA9ICcrNyAoJyArIHZhbHVlLnN1YnN0cmluZygxLCA0KTsKICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUubGVuZ3RoIDw9IDcpIHZhbHVlID0gJys3ICgnICsgdmFsdWUuc3Vic3RyaW5nKDEsIDQpICsgJykgJyArIHZhbHVlLnN1YnN0cmluZyg0LCA3KTsKICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUubGVuZ3RoIDw9IDkpIHZhbHVlID0gJys3ICgnICsgdmFsdWUuc3Vic3RyaW5nKDEsIDQpICsgJykgJyArIHZhbHVlLnN1YnN0cmluZyg0LCA3KSArICctJyArIHZhbHVlLnN1YnN0cmluZyg3LCA5KTsKICAgICAgICAgICAgZWxzZSB2YWx1ZSA9ICcrNyAoJyArIHZhbHVlLnN1YnN0cmluZygxLCA0KSArICcpICcgKyB2YWx1ZS5zdWJzdHJpbmcoNCwgNykgKyAnLScgKyB2YWx1ZS5zdWJzdHJpbmcoNywgOSkgKyAnLScgKyB2YWx1ZS5zdWJzdHJpbmcoOSwgMTEpOwogICAgICAgICAgICBlLnRhcmdldC52YWx1ZSA9IHZhbHVlOwogICAgICAgICAgICBlLnRhcmdldC5zdHlsZS5ib3JkZXIgPSAnJzsKICAgICAgICB9CiAgICB9KTsKICAgIAogICAgcGhvbmVJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgZnVuY3Rpb24oZSkgewogICAgICAgIGNvbnN0IGRpZ2l0cyA9IGUudGFyZ2V0LnZhbHVlLnJlcGxhY2UoL1xEL2csICcnKTsKICAgICAgICBpZiAoZGlnaXRzLmxlbmd0aCA+IDAgJiYgZGlnaXRzLmxlbmd0aCA8IDEwKSB7CiAgICAgICAgICAgIHNob3dTdGF0dXMoJ9Cd0L7QvNC10YAg0YLQtdC70LXRhNC+0L3QsCDRgdC70LjRiNC60L7QvCDQutC+0YDQvtGC0LrQuNC5JywgdHJ1ZSk7CiAgICAgICAgICAgIGUudGFyZ2V0LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgI2RjMjYyNic7CiAgICAgICAgfSBlbHNlIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiAvXihcZClcMXsxMH0kLy50ZXN0KGRpZ2l0cykpIHsKICAgICAgICAgICAgc2hvd1N0YXR1cygn0JLQstC10LTQuNGC0LUg0YDQtdCw0LvRjNC90YvQuSDQvdC+0LzQtdGAINGC0LXQu9C10YTQvtC90LAnLCB0cnVlKTsKICAgICAgICAgICAgZS50YXJnZXQuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZGMyNjI2JzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlLnRhcmdldC5zdHlsZS5ib3JkZXIgPSAnJzsKICAgICAgICB9CiAgICB9KTsKCiAgICAvLyA9PT09PSDQl9CQ0JPQoNCj0JfQmtCQINCY0KHQotCe0KDQmNCYID09PT09CiAgICBjb25zdCBvcmlnaW5hbE9wZW5DaGF0ID0gYnV0dG9uLm9uY2xpY2s7CiAgICBidXR0b24ub25jbGljayA9IGZ1bmN0aW9uKCkgewogICAgICAgIGlmICh0eXBlb2Ygb3JpZ2luYWxPcGVuQ2hhdCA9PT0gJ2Z1bmN0aW9uJykgb3JpZ2luYWxPcGVuQ2hhdCgpOwogICAgICAgIHNldFRpbWVvdXQobG9hZEhpc3RvcnksIDEwMCk7CiAgICB9Owp9KTsKPC9zY3JpcHQ+