/* ============================================================ ДЕЛО № 260826. ИСЧЕЗНОВЕНИЕ ПОДАРКА — версия 2 Конфигурация и содержимое. Правьте блок CONFIG — остальное трогать не обязательно. ============================================================ */ const CONFIG = { name: "Алиса", caseNumber: "260826", caseDateWords: "двадцать шестое августа две тысячи двадцать шестого года", pvzAddress: "Москва, Кочновский пр-д, 4 к. 1. ПВЗ Озон", /* Штрихкод не показывается в квесте: именинница присылает это кодовое слово в личные сообщения, а штрихкод отправляется в ответ. */ pickupCode: "АРБУЗ", pvzPageUrl: "", songSrc: "assets/song.mp3", }; /* Три факта, которые игрок добывает по ходу дела и вписывает в финальную форму ордера. Меняются только вместе с загадками. */ const FACTS = { exitTime: "09:08", // глава 2: журнал турникета foreignTag: "ДС-04", // глава 1: бирка сторонней службы codeWord: "ПАУЗА", // глава 4: акростих бриджа }; const COMMON = { hintIntro: [ "Следствие разрешает воспользоваться подсказкой. Это не считается поражением. Хотя статистика говорит об обратном.", "Подсказка выдана. Бюро делает вид, что это было предусмотрено.", "Следствие идёт навстречу. Один раз. И ещё один. И, кажется, ещё.", ], wrongGeneric: [ "Ответ не подтверждён. Следователь сделал вид, что так и задумано.", "Нет. Но уверенность впечатляет.", "Такая версия рассматривалась ещё в 1974 году. Не спрашивайте почему.", "Система вежливо не согласна. И просит передать это деликатно.", "Ошибка. Один из документов тихо извинился.", "Не подтверждается. Но в отчёте можно написать «смелая гипотеза».", ], }; const CONTENT = { /* ---------- ПРОЛОГ ---------- */ intro: { tag: "УВЕДОМЛЕНИЕ БКТО", title: "Объект задержан", body: [ "В отношении объекта, предназначавшегося вам в качестве подарка, открыто дело.", "Статус объекта: ВРЕМЕННО ОГРАНИЧЕН.", "Прямое раскрытие сюрприза запрещено регламентом. Всё, что вам могут дать, — документы.", ], button: "Принять дело к производству", footnote: "Отказ не предусмотрен. День рождения уже в процессе.", }, loadingScreen: { system: "ГИС «ПАПКА»", subtitle: "Подарочный Архив · Праздничный Контроль · Финальная Торжественность · Абсурд", lines: [ "Проверка праздничного статуса…", "Сверка папок…", "Папки найдены. Одна моргнула.", "Загрузка материалов дела…", ], button: "Войти в систему", }, /* ---------- ГЛАВА 0. НОМЕР ДЕЛА ---------- */ caseNumber: { chapter: "Допуск", title: "ПОДТВЕРЖДЕНИЕ ДОСТУПА", body: [ "Доступ к материалам открыт только получателю объекта.", "Номер дела не сообщается напрямую: он формируется автоматически.", ], ruleTitle: "ВЫПИСКА ИЗ РЕГЛАМЕНТА, П. 4.2", ruleText: "Номер дела образуется из даты регистрации в формате ДДММГГ, без разделителей.", registryTitle: "КАРТОЧКА РЕГИСТРАЦИИ", registryRows: [ ["Заявитель", "под грифом ДРУЖБА"], ["Дата регистрации", CONFIG.caseDateWords], ["Предмет", "объект торжественного назначения, 1 шт."], ], placeholder: "Номер дела", button: "Открыть дело", wrong: [ "Номер дела не совпадает. Бюрократия тихо плачет в папку.", "Дело с таким номером существует, но оно про кота. Не ваше.", "Не сходится. Регламент напоминает: сначала день, потом месяц, потом год. Все по две цифры.", ], hints: [ "Дата регистрации записана прописью. Переведите её в цифры.", "Формат ДДММГГ: день, месяц и год — каждый ровно двумя цифрами, подряд, без точек.", "Двадцать шестое августа две тысячи двадцать шестого — это " + CONFIG.caseNumber + ".", ], }, caseOpened: { title: "ДЕЛО ОТКРЫТО", body: [ "Вам присвоен статус: временный следователь по собственному делу.", "", "Права: ошибаться, сомневаться, запрашивать подсказки, быть именинницей.", "Ограничения: нельзя пропустить день рождения.", "", "Бюро обращает внимание: всё, что вы установите, попадёт в журнал дела. В финале журнал понадобится целиком.", ], button: "Осмотреть место происшествия", }, /* ---------- ГЛАВА 1. ОПИСЬ ---------- */ scene: { chapter: "Глава 1", title: "МЕСТО ПРОИСШЕСТВИЯ", body: [ "Снимок рабочего стола, сделанный после исчезновения объекта.", "Каждый предмет Бюро снабжает инвентарной биркой. Все предметы отдела имеют префикс БКТО.", "", "Задача: найти на столе предмет, которого нет в описи.", ], protocolTitle: "ОПИСЬ ИМУЩЕСТВА ОТДЕЛА", protocolNote: "Проверено вручную. Примерно.", inventory: [ ["БКТО-11", "лампа настольная, зелёная"], ["БКТО-12", "кружка с надписью «НЕ ТРОГАТЬ»"], ["БКТО-13", "календарь настенный"], ["БКТО-14", "папка дела"], ["БКТО-15", "карандаш"], ["БКТО-16", "кактус (эмоционально устойчив)"], ["БКТО-17", "лист с надписью «ПЕЧАТЬ НЕ ТРОГАТЬ»"], ], correctId: "box", successTitle: "Предмет вне описи обнаружен", successBody: "Картонная коробка с биркой " + FACTS.foreignTag + ". Префикс не принадлежит Бюро: это служба доставки «Доставка с чувством». Коробка приехала снаружи — и, судя по всему, уехала обратно.", reactions: { lamp: "Бирка БКТО-11. Лампа в описи. Лампа отрицает участие, но свет у неё подозрительно уверенный.", mug: "Бирка БКТО-12. Кружка в описи. Уликой не является, но морально поддерживает следствие.", calendar: "Бирка БКТО-13. Календарь в описи. Число 26 обведено дважды — это личное дело календаря.", folder: "Бирка БКТО-14. Папка уже в деле. Не заставляйте её волноваться повторно.", pencil: "Бирка БКТО-15. Карандаш в описи. Готов сотрудничать, но ему нечего сказать.", cactus: "Бирка БКТО-16. Кактус в описи и от показаний отказывается, ссылаясь на колючий характер.", paper: "Бирка БКТО-17. Лист в описи. Надпись «ПЕЧАТЬ НЕ ТРОГАТЬ» соблюдена. Формально.", }, hints: [ "Сверяйте бирки на предметах со списком в описи. Один предмет в списке отсутствует.", "Бюро использует только префикс БКТО. На одной бирке префикс другой.", "Картонная коробка справа внизу помечена «" + FACTS.foreignTag + "» — это чужая служба. Нажмите на неё.", ], evidence: { name: "КОРОБКА", fact: FACTS.foreignTag, factLabel: "Инвентарный признак сторонней службы", desc: "Картонная коробка службы «Доставка с чувством». В опись Бюро не входит.", }, button: "Приобщить к делу", }, /* ---------- ГЛАВА 2. ЖУРНАЛ И ПОКАЗАНИЯ ---------- */ witnesses: { chapter: "Глава 2", title: "СВЕРКА ПОКАЗАНИЙ", body: [ "Коробку кто-то вынес. Бюро подняло журнал турникета и опросило четверых.", "", "Задача: найти свидетеля, чьи показания физически невозможны — то есть противоречат журналу проходов.", ], logTitle: "ЖУРНАЛ ТУРНИКЕТА · 26 АВГУСТА", logRows: [ ["08:41", "Пылинкин А.", "вход"], ["09:02", "Шлюз К. И.", "выход"], ["09:06", "Быстрый Т.", "вход"], ["09:08", "Быстрый Т.", "выход"], ["09:12", "Шлюз К. И.", "вход"], ["09:15", "Каверза Л. П.", "вход"], ], cards: [ { id: "klavdia", name: "Клавдия Ивановна Шлюз", role: "вахтёрша", text: "«В 09:07 я была на посту. Мимо меня никто не проходил — ни туда, ни обратно. У меня глаз профессиональный».", }, { id: "pylinkin", name: "Архивариус Пылинкин", role: "младший хранитель бумажных сущностей", text: "«Около девяти мимо прошёл человек в шарфе. Папка при этом моргнула. Я доложил. Папке стало легче».", }, { id: "timur", name: "Тимур Быстрый", role: "курьер службы «Доставка с чувством»", text: "«Пришёл, забрал коробку, ушёл. Две минуты, не больше. Коробка была лёгкая. Подозрительно лёгкая».", }, { id: "kaverza", name: "Л. П. Каверза", role: "филолог-консультант", text: "«Когда я вошёл, на столе уже ничего не было. И сразу уточню: не “украдено”, а “изъято”. Это разные вещи».", }, ], correct: "klavdia", successTitle: "Противоречие установлено", successBody: "По журналу Шлюз К. И. вышла в 09:02 и вернулась в 09:12. В 09:07 её не было в здании — значит, видеть коридор она не могла. Свидетель ошибается, не становясь преступником.", wrongReactions: { pylinkin: "Пылинкин вошёл в 08:41 и не выходил. Около девяти он действительно был внутри — журналу это не противоречит. Странность показаний ещё не делает их невозможными.", timur: "Быстрый вошёл в 09:06 и вышел в 09:08. Ровно две минуты, как он и говорит. Журнал подтверждает его слово в точности.", kaverza: "Каверза вошёл в 09:15 — уже после того, как коробку вынесли. Он и правда мог застать пустой стол. Противоречия нет.", }, hints: [ "Возьмите время из каждого показания и проверьте по журналу, был ли этот человек в здании в тот момент.", "Один свидетель называет время, когда он, судя по журналу, находился снаружи.", "Шлюз вышла в 09:02 и вернулась в 09:12 — а утверждает, что была на посту в 09:07.", ], evidence: { name: "ЖУРНАЛ", fact: FACTS.exitTime, factLabel: "Время выхода объекта из здания", desc: "Коробку вынес курьер Быстрый Т. Турникет зафиксировал выход в " + FACTS.exitTime + ".", }, button: "Приобщить к делу", }, /* ---------- ГЛАВА 3. ФИЛОЛОГИЯ ---------- */ philology: { chapter: "Глава 3", title: "ФИЛОЛОГИЧЕСКАЯ ЭКСПЕРТИЗА", body: [ "Отдел нарративной безопасности сообщает: среди трёх документов дела один изготовлен не Бюро.", "", "Подделка может иметь подпись и даже печать. Но она не выдерживает проверки языком.", ], memoTitle: "ПАМЯТКА КОНСУЛЬТАНТА Л. П. КАВЕРЗЫ", memoText: "«Предлог “согласно” управляет дательным падежом: согласно чему? — согласно приказу, протоколу, распоряжению. Форма “согласно приказа” — родительный падеж — в служебном документе невозможна. Запятая — это дверь; падеж — это замок».", docs: [ { id: 1, head: "Распоряжение № 4/тор", text: "«Согласно приказу № " + CONFIG.caseNumber + ", объект подлежит проверке на торжественную пригодность».", sign: "К. К. Пропавший-Без-Вести", }, { id: 2, head: "Служебная записка № 7", text: "«В соответствии с протоколом № 7 свидетель обязан сохранять загадочность и не разглашать сюрприз в обеденный перерыв».", sign: "З. М. Штемпель", }, { id: 3, head: "Постановление б/н", text: "«Согласно приказа о похищении, подарок считается украденным, а филолог — подозрительным».", sign: "подпись неразборчива", }, ], correct: 3, successTitle: "Подделка обнаружена", successBody: "«Согласно приказа» — родительный падеж. Настоящее Бюро написало бы «согласно приказу». Отдел грамматики аплодирует, но по регламенту делает это беззвучно.", wrongReactions: { 1: "Документ № 1 оскорблён. Он всю жизнь использовал дательный падеж и не намерен это обсуждать: «согласно приказу» — безупречно.", 2: "Документ № 2 загадочен, но законен. «В соответствии с протоколом» — корректная конструкция. Свидетель сохраняет загадочность; дело пока нет.", }, hints: [ "Прочтите памятку Каверзы и проверьте по ней каждый документ.", "Ищите документ, где после «согласно» стоит не дательный падеж.", "Документ № 3: «согласно приказа» вместо «согласно приказу». Это подделка.", ], evidence: { name: "ЭКСПЕРТИЗА", fact: "согласно приказу", factLabel: "Признак подлинности документа", desc: "Настоящие документы Бюро используют дательный падеж. «Согласно приказа» — маркер подделки.", }, button: "Приобщить к делу", }, /* ---------- ГЛАВА 4. АУДИО ---------- */ audio: { chapter: "Глава 4", title: "АУДИОЭКСПЕРТИЗА", body: [ "Из архива поступила служебная песня. Бюро напоминает: музыка считается документом, если в ней есть хотя бы одна печать.", "", "В песне спрятано служебное слово. В самом тексте оно не звучит ни разу — иначе какая же это тайна.", "", "Припев намеренно подсовывает похожие слова. Не доверяйте припеву.", ], songTitle: "«Временное ограничение»", songAuthor: "ВИА «Канцелярия» при участии Отдела музыкальной отчётности", bridgeLabel: "служебная вставка", lyrics: [ { type: "verse", label: "Куплет 1", lines: [ "В архиве пахнет пылью и чаем,", "Объект на месте. Объект молчит.", "Мы ничего не подозреваем —", "Мы просто ждём, пока форма звучит.", ]}, { type: "chorus", label: "Припев", lines: [ "Не украден, не забыт,", "Он в законном состоянье.", "Не потерян, не сокрыт —", "Просто длится ожиданье.", ]}, { type: "verse", label: "Куплет 2", lines: [ "Свидетель смотрит в журнал слишком долго,", "Курьер уверяет, что вышел пустым.", "Филолог поправит падеж — и только", "Тогда документ перестанет быть злым.", ]}, { type: "chorus", label: "Припев", lines: [ "Не украден, не забыт,", "Он в законном состоянье.", "Не потерян, не сокрыт —", "Просто длится ожиданье.", ]}, { type: "bridge", label: "Бридж", lines: [ "Пусть протокол никуда не спешит,", "Архив тишину до конца сторожит.", "Условие радости: дать ей отстояться,", "Задержка объекта — не повод бояться,", "А выдача будет. По форме. Не сразу.", ]}, { type: "chorus", label: "Финальный припев", lines: [ "Не украден, не забыт,", "Он почти уже открыт.", "Не потерян, не сокрыт —", "Форма выдачи звучит.", ]}, ], placeholder: "Служебное слово", button: "Подтвердить", correct: FACTS.codeWord, successTitle: "Служебное слово принято", successBody: "Первые буквы бриджа складываются в «" + FACTS.codeWord + "». Именно этим словом Бюро обозначает состояние объекта: не украден, не потерян — поставлен на паузу до появления сюжета.", wrongHints: { ozhidanie: "Слово из припева. Припев вас именно на это и ловил. Служебное слово в тексте не звучит — его нужно собрать.", syuzhet: "Красивая версия, но этого слова в бридже не собрать. Смотрите на первые буквы пяти строк служебной вставки.", }, wrong: [ "Слово не принято. Музыкальная комиссия сделала вид, что это была репетиция.", "Неверно. Хор Бюро выражает сочувствие в допустимом диапазоне громкости.", "Не совпадает. Возможно, вы слушали слишком доверчиво.", ], hints: [ "Служебная вставка — это бридж, пять строк, выделенных отдельно. Смотрите на начала строк.", "Возьмите по одной первой букве каждой из пяти строк бриджа и прочтите сверху вниз.", "П, А, У, З, А — получается «" + FACTS.codeWord + "».", ], evidence: { name: "ЗАПИСЬ", fact: FACTS.codeWord, factLabel: "Служебное кодовое слово", desc: "Акростих бриджа. Обозначает состояние объекта: задержан до появления сюжета.", }, button: "Приобщить к делу", }, /* ---------- ГЛАВА 5. ЛОЖНЫЙ СЛЕД ---------- */ falseTrail: { chapter: "Глава 5", title: "СРОЧНОЕ ОБНОВЛЕНИЕ", alertBody: [ "В дело поступил рапорт о похищении объекта.", "Обвиняется филолог-консультант Л. П. Каверза.", ], reportTitle: "РАПОРТ О ПОХИЩЕНИИ", intro: "Рапорт выглядит официально: есть номер дела, время, подпись и печать. Бюро предлагает проверить его до того, как кого-нибудь задержат.", /* Текст рапорта разбит на фрагменты. is: тип реакции. tell: true — настоящий признак подделки (нужно найти оба). */ reportParts: [ { t: "Дело № " + CONFIG.caseNumber + ". ", id: "num" }, { t: "Установлено, что филолог-консультант Л. П. Каверза изъял объект ", id: "plain" }, { t: "в 09:05", id: "time", tell: true }, { t: " и вынес его через турникет ", id: "plain2" }, { t: "согласно приказа", id: "case", tell: true }, { t: " № " + CONFIG.caseNumber + ". Мотив: день рождения казался недостаточно сюжетным. ", id: "motive" }, { t: "Подпись: Л. П. Каверза.", id: "sign" }, { t: " Печать: имеется. Уверенность: повышенная.", id: "stamp" }, ], task: "Найдите в тексте признаки подделки. Их два. Нажимайте прямо на подозрительные места.", counter: "Признаков найдено", tellReactions: { time: { title: "Признак 1: невозможное время", text: "По журналу турникета Каверза вошёл в здание в 09:15. В 09:05 его здесь не было — изъять объект он не мог физически.", }, case: { title: "Признак 2: чужая грамматика", text: "«Согласно приказа» — родительный падеж. Настоящее Бюро пишет «согласно приказу». Тот же почерк, что и у поддельного постановления.", }, }, plainReactions: { num: "Номер дела указан верно. Подделка всегда начинается с правдоподобного.", plain: "Формулировка как формулировка. Обвинение — ещё не доказательство.", plain2: "Турникет действительно существует. Это, пожалуй, единственное, что здесь бесспорно.", motive: "Мотив звучит обидно правдоподобно. Но мотив не является уликой.", sign: "Подпись есть. Каверза утверждает, что подписывается всегда со сноской. Сноски нет — но это спорный аргумент.", stamp: "«Уверенность: повышенная» — не реквизит документа. Смешно, но подделку этим не доказать.", }, successTitle: "Рапорт признан подделкой", successBody: "Оба признака подтверждены: время противоречит журналу, падеж противоречит регламенту. Филолог освобождён от подозрений с формулировкой «слишком грамотен для этого преступления».", kaverzaQuote: "«Я подозревал, что меня подставят. Но не ожидал, что сделают это с такой слабой грамматикой. Это обиднее подозрений».", hints: [ "Один признак — фактический: сверьте время в рапорте с журналом турникета. Второй — языковой: вспомните памятку Каверзы.", "Каверза вошёл в 09:15, а рапорт называет другое время. И где-то в тексте снова хромает падеж.", "Нажмите на «в 09:05» и на «согласно приказа».", ], evidence: { name: "ОПРОВЕРЖЕНИЕ", fact: "версия о краже несостоятельна", factLabel: "Итог проверки", desc: "Рапорт изготовлен Отделом срочных ложных версий. Кражи не было.", }, button: "Приобщить к делу", }, /* ---------- ГЛАВА 6. ОРДЕР ---------- */ order: { chapter: "Глава 6", title: "ФОРМА ОРДЕРА НА ВЫДАЧУ", body: [ "Кражи не было. Объект не похищен — он задержан.", "", "Чтобы снять ограничение, заполните ордер. Все три графы уже установлены следствием: загляните в журнал дела, если что-то забылось.", ], fields: [ { id: "exitTime", label: "Графа 1. Время выхода объекта из здания", placeholder: "чч:мм", hintSource: "глава 2, журнал турникета", wrong: "Время не соответствует журналу турникета. Проверьте, когда именно объект покинул здание.", }, { id: "foreignTag", label: "Графа 2. Инвентарный признак сторонней службы", placeholder: "XX-00", hintSource: "глава 1, опись имущества", wrong: "Такой бирки в деле нет. Речь о предмете, которого не было в описи Бюро.", }, { id: "codeWord", label: "Графа 3. Служебное кодовое слово", placeholder: "слово", hintSource: "глава 4, аудиоэкспертиза", wrong: "Слово не совпадает со служебным. Оно было собрано из первых букв бриджа.", }, ], button: "Подать ордер", partial: "Форма принята частично. Бюро не любит частично.", hints: [ "Все три значения уже есть в журнале дела — откройте его кнопкой «Журнал» наверху.", "Графа 1 — время из журнала турникета. Графа 2 — бирка коробки. Графа 3 — акростих бриджа.", FACTS.exitTime + " · " + FACTS.foreignTag + " · " + FACTS.codeWord, ], }, /* ---------- ФИНАЛ ---------- */ twist: { lines: [ "Преступления не было.", "Дело № " + CONFIG.caseNumber + " переквалифицировано.", "Объект не похищали. Объект был поставлен на паузу — до появления сюжета.", "Сюжет создан. Вами. Только что.", ], stamp: "СЮЖЕТ ПРИЛОЖЕН", button: "Закрыть дело", }, congrats: { title: "Дело № " + CONFIG.caseNumber + " закрыто", body: [ "Преступления не было.", "", "Были бумаги, штампы, журнал турникета, один подделанный рапорт и один филолог, который переживал за падежи больше, чем за собственную репутацию.", "", "А ещё был день рождения, который заслуживал не просто подарок, а историю.", "", CONFIG.name + ", ты прошла это дело с внимательностью, иронией и терпением, которым позавидовала бы любая бюрократическая система.", "", "С днём рождения.", "", "Пусть запятые стоят там, где им удобно.", "Пусть правила нарушаются с умом.", "Пусть подарки ждут тебя не в камерах хранения, а в руках.", "", "И если жизнь когда-нибудь снова покажется слишком серьёзной — вспомни: где-то в этом деле тебя официально признали человеком, способным расследовать собственную радость.", ], button: "Получить ордер на выдачу", }, orderScreen: { title: "ОРДЕР НА ВЫДАЧУ ОБЪЕКТА № " + CONFIG.caseNumber, rows: [ ["Объект", "Подарок, 1 шт."], ["Статус", "готов к выдаче"], ["Основание", "сюжет приложен"], ], qrNote: "Наведите камеру на контрольную печать.", /* Штрихкод намеренно не выдаётся системой: последний шаг — написать организатору. */ claimTitle: "ПОЛУЧЕНИЕ ШТРИХКОДА", claimLead: "Бюро не хранит штрихкоды в открытом виде: они выдаются ответственному лицу под расписку.", claimSteps: [ "Отправьте мне в личные сообщения кодовое слово: " + CONFIG.pickupCode + ".", "В ответ придёт штрихкод заказа.", "Покажите штрихкод на пункте выдачи по адресу выше.", ], claimNote: "Да, это ещё одна бюрократическая процедура. Последняя. Обещаю.", joke: "Если сотрудник ПВЗ спросит, зачем вам подарок, отвечайте: «По делу № " + CONFIG.caseNumber + "». Это не поможет. Но звучит весомо.", reserveNote: "Если что-то не открывается — это не подарок, это техническая подделка. Напишите мне.", copyButton: "Скопировать адрес и кодовое слово", }, easter: { speedButton: "Ускорить следствие", speedFirst: "Кнопка работает только в следующем квесте.", speedSecond: "Следствие ускорено эмоционально. Фактических изменений нет.", complaintButton: "Пожаловаться на Бюро", complaintResult: "Ваша жалоба принята. Ей присвоен номер № 0. Номер № 0 благодарит вас за внимание.", confusedButton: "Я ничего не понимаю", confusedFirst: "Это нормальная реакция. Следствие признаёт её официальной.", confusedSecond: "Уровень понимания не изменился. Уровень атмосферы вырос.", resetButton: "Начать сначала", resetArm: "Нажмите ещё раз, чтобы начать дело заново. Прогресс будет стёрт.", footer: "если вы читаете это, вы внимательны. подарок всё ещё реален.", }, }; /* Порядок глав для индикатора прогресса */ const CHAPTERS = [ { stage: "caseNumber", label: "Допуск" }, { stage: "scene", label: "Опись" }, { stage: "witnesses", label: "Показания" }, { stage: "philology", label: "Экспертиза" }, { stage: "audio", label: "Запись" }, { stage: "falseTrail", label: "Ложный след" }, { stage: "orderForm", label: "Ордер" }, ];