мина ван дер марк
Она проснулась от тишины. Не от шума, не от света, не от голоса — а от того, что вокруг было слишком спокойно для её собственной спальни. В её квартире всегда гудел холодильник. Старый, урчащий, как рассерженный кот. Здесь же тишина стояла плотная, почти осязаемая, и только где-то за стеной мягко шуршала вода — кто-то мыл руки или наливал в чайник.
читать далее
СЕГОДНЯ В САКРАМЕНТО 15°C
джек

[telegram: cavalcanti_sun]
аарон

[лс]
джуди

[telegram: kellzyaba]
кристин

[telegram: potos_flavus]

сид

[лс]
даст

[telegram: auiuiui]
брэйди

[telegram: katrinelist]

юнас

[telegram: whyshouldidoit]
уилл

[telegram: pratoria]
[gem space: pratoria]
айзек

[telegram: sour_sour_cherry]
яго

[telegram: GreenFelis]
RPG TOP

dust ultimate two

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » dust ultimate two » Организация » для сбора табличке 2


для сбора табличке 2

Сообщений 1 страница 2 из 2

1

..

Подпись автора

https://i.imgur.com/5o0dxGP.png
♥️
поле чудес х rich bitch x капсула х  капсула'23
«good morning, reasons why I drink.»

0

2

Код:
<!--HTML-->
<style>
  .buildertd-body {
    font-family: -apple-system, Segoe UI, Roboto, sans-serif;
    margin: 0; padding: 20px;
    background: #f5f5f7;
    color: #222;
  }
  .buildertd-title { font-size: 20px; margin: 0 0 16px; }
  .buildertd-panel {
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 16px;
  }
  .buildertd-panel-title {
    font-size: 14px;
    margin: 0 0 8px;
    color: #555;
    font-weight: 600;
  }
  .buildertd-hint {
    font-size: 12px;
    color: #888;
    margin: 6px 0 0;
  }
  .buildertd-hint code {
    background: #eef1f5;
    padding: 1px 5px;
    border-radius: 4px;
    font-family: ui-monospace, Consolas, monospace;
  }
  .buildertd-textarea {
    width: 100%;
    resize: vertical;
    font-family: ui-monospace, Consolas, monospace;
    font-size: 13px;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 6px;
    outline: none;
  }
  .buildertd-textarea:focus { border-color: #4a90e2; }
  .buildertd-template { height: 160px; }
  .buildertd-list { height: 180px; }

  .buildertd-list-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
  }
  .buildertd-list-num {
    font-weight: 700;
    font-size: 14px;
    color: #333;
  }
  .buildertd-list-count {
    font-size: 12px;
    color: #888;
    margin-left: auto;
  }
  .buildertd-remove {
    background: #fdecea;
    color: #c0392b;
    border: 1px solid #f5c6c0;
    border-radius: 6px;
    padding: 4px 10px;
    font-size: 12px;
    cursor: pointer;
  }
  .buildertd-remove:hover { background: #fbdcd7; }

  .buildertd-group-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
    flex-wrap: wrap;
  }
  .buildertd-group-label {
    font-size: 14px;
    color: #333;
  }
  .buildertd-group-input {
    width: 100px;
    padding: 8px 10px;
    font-family: ui-monospace, Consolas, monospace;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 6px;
    outline: none;
  }
  .buildertd-group-input:focus { border-color: #4a90e2; }
  .buildertd-group-input:disabled {
    background: #f2f2f4;
    color: #999;
    cursor: not-allowed;
  }
  .buildertd-checkbox-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: #444;
  }
  .buildertd-checkbox-row input[type="checkbox"] {
    width: 16px; height: 16px;
    cursor: pointer;
  }
  .buildertd-checkbox-row.disabled { color: #aaa; }
  .buildertd-checkbox-row.disabled input[type="checkbox"] { cursor: not-allowed; }

  .buildertd-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    margin: 16px 0;
  }
  .buildertd-button {
    padding: 10px 20px;
    font-size: 14px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    background: #4a90e2;
    color: #fff;
    font-weight: 600;
  }
  .buildertd-button:hover { background: #3a7bc8; }
  .buildertd-button-secondary {
    background: #e5e5ea;
    color: #333;
  }
  .buildertd-button-secondary:hover { background: #d5d5da; }

  .buildertd-warning {
    color: #c0392b;
    font-weight: 600;
    padding: 8px 12px;
    background: #fdecea;
    border-radius: 6px;
    display: none;
    width: 100%;
    box-sizing: border-box;
  }
  .buildertd-warning-show { display: block; }

  .buildertd-output {
    width: 100%;
    height: 340px;
    font-family: ui-monospace, Consolas, monospace;
    font-size: 13px;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 6px;
    background: #fff;
    white-space: pre;
    overflow: auto;
  }
</style>
</head>
<body class="buildertd-body">

<h1 class="buildertd-title">Билдер табличек с призами</h1>

<!-- Шаблон -->
<div class="buildertd-panel">
  <h2 class="buildertd-panel-title">Шаблон</h2>
  <textarea id="buildertdTemplate" class="buildertd-textarea buildertd-template"
    placeholder="[td][align=center][img]$ССЫЛКА$[/img]
[size=10]$НАЗВАНИЕ$[/size][/align][/td]"></textarea>
  <p class="buildertd-hint">
    Переменные указываются как <code>$НАЗВАНИЕ_ПЕРЕМЕННОЙ$</code>.
    Значение подставляется из списка, у которого первой строкой указана эта же переменная.
  </p>
</div>

<!-- Списки -->
<div id="buildertdLists"></div>

<!-- Группировка -->
<div class="buildertd-panel">
  <h2 class="buildertd-panel-title">Разбить на группы по</h2>
  <div class="buildertd-group-row">
    <label for="buildertdGroupSize" class="buildertd-group-label">Количество в группе:</label>
    <input id="buildertdGroupSize" class="buildertd-group-input" type="number" min="1" step="1" placeholder="N">
  </div>
  <div id="buildertdPadRow" class="buildertd-checkbox-row disabled">
    <input id="buildertdPadLast" type="checkbox" disabled>
    <label for="buildertdPadLast">добавить пустые строки до полной группы</label>
  </div>
</div>

<div class="buildertd-actions">
  <button id="buildertdAddList" class="buildertd-button buildertd-button-secondary">+ Добавить список</button>
  <button id="buildertdGenerate" class="buildertd-button">Сгенерировать</button>
  <button id="buildertdCopy" class="buildertd-button buildertd-button-secondary">Копировать</button>
  <div id="buildertdWarning" class="buildertd-warning"></div>
</div>

<!-- Вывод -->
<div class="buildertd-panel">
  <h2 class="buildertd-panel-title">Результат</h2>
  <textarea id="buildertdOutput" class="buildertd-output" readonly></textarea>
</div>

<script>
(function () {
  const templateEl = document.getElementById('buildertdTemplate');
  const listsWrap  = document.getElementById('buildertdLists');
  const outEl      = document.getElementById('buildertdOutput');
  const warnEl     = document.getElementById('buildertdWarning');

  const groupSizeEl = document.getElementById('buildertdGroupSize');
  const padLastEl   = document.getElementById('buildertdPadLast');
  const padRowEl    = document.getElementById('buildertdPadRow');

  let nextListId = 1;

  // ---- Утилиты ----
  function parseLines(text) {
    return text.split(/\r?\n/).map(s => s.trim());
  }

  function parseListBlock(text) {
    const lines = parseLines(text);
    while (lines.length && lines[0] === '') lines.shift();
    if (lines.length === 0) {
      return { error: 'Пустой список — нет строки с названием переменной' };
    }
    const m = lines[0].match(/^\$([^$]+)\$$/);
    if (!m) {
      return { error: 'Первая строка должна содержать $НАЗВАНИЕ_ПЕРЕМЕННОЙ$' };
    }
    const varName = m[1].trim();
    if (!varName) {
      return { error: 'Пустое имя переменной' };
    }
    const values = lines.slice(1).map(s => s.trim()).filter(s => s.length > 0);
    return { varName, values };
  }

  function escapeRegex(s) {
    return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  }

  // ---- Управление списками ----
  function createListBlock() {
    const id = nextListId++;
    const panel = document.createElement('div');
    panel.className = 'buildertd-panel';
    panel.dataset.listId = String(id);

    panel.innerHTML = `
      <div class="buildertd-list-head">
        <span class="buildertd-list-num">Список ${id}</span>
        <span class="buildertd-list-count" data-role="count">строк: 0</span>
        <button class="buildertd-remove" data-role="remove">Удалить</button>
      </div>
      <textarea class="buildertd-textarea buildertd-list"
        placeholder="$НАЗВАНИЕ_ПЕРЕМЕННОЙ$
значение 1
значение 2"></textarea>
      <p class="buildertd-hint">
        Первой строкой укажите <code>$НАЗВАНИЕ_ПЕРЕМЕННОЙ$</code>. Последующие строки — значения.
      </p>
    `;

    const ta = panel.querySelector('textarea');
    const countEl = panel.querySelector('[data-role="count"]');

    function updateCount() {
      const parsed = parseListBlock(ta.value);
      countEl.textContent = parsed.error ? 'строк: —' : `строк: ${parsed.values.length}`;
    }

    ta.addEventListener('input', updateCount);
    panel.querySelector('[data-role="remove"]').addEventListener('click', () => {
      panel.remove();
      renumberLists();
    });

    listsWrap.appendChild(panel);
    updateCount();
    return panel;
  }

  function renumberLists() {
    const panels = listsWrap.querySelectorAll('[data-list-id]');
    panels.forEach((p, idx) => {
      const num = p.querySelector('.buildertd-list-num');
      if (num) num.textContent = `Список ${idx + 1}`;
    });
  }

  // ---- Логика чекбокса ----
  function updatePadState() {
    const val = groupSizeEl.value.trim();
    const n = Number(val);
    const enabled = val !== '' && Number.isFinite(n) && n >= 1 && Number.isInteger(n);
    if (enabled) {
      padRowEl.classList.remove('disabled');
      padLastEl.disabled = false;
    } else {
      padRowEl.classList.add('disabled');
      padLastEl.disabled = true;
      padLastEl.checked = false;
    }
  }
  groupSizeEl.addEventListener('input', updatePadState);

  // ---- Предупреждения ----
  function showWarning(msg) {
    warnEl.textContent = msg;
    warnEl.classList.add('buildertd-warning-show');
  }
  function hideWarning() {
    warnEl.textContent = '';
    warnEl.classList.remove('buildertd-warning-show');
  }

  // ---- Генерация ----
  function buildRow(templateText, blocks, rowIndex) {
    let result = templateText;
    for (const block of blocks) {
      const value = rowIndex < block.values.length ? block.values[rowIndex] : '';
      const re = new RegExp('\\$' + escapeRegex(block.varName) + '\\$', 'g');
      result = result.replace(re, value);
    }
    return result;
  }

  function generate() {
    hideWarning();
    outEl.value = '';

    // 1. Собираем списки
    const panels = Array.from(listsWrap.querySelectorAll('[data-list-id]'));
    if (panels.length === 0) {
      showWarning('Добавьте хотя бы один список');
      return;
    }

    const blocks = [];
    for (let i = 0; i < panels.length; i++) {
      const ta = panels[i].querySelector('textarea');
      const parsed = parseListBlock(ta.value);
      if (parsed.error) {
        showWarning(`Список ${i + 1}: ${parsed.error}`);
        return;
      }
      blocks.push(parsed);
    }

    // 2. Проверяем количество
    const counts = blocks.map(b => b.values.length);
    const first = counts[0];
    if (!counts.every(c => c === first)) {
      showWarning(`Неравное количество элементов: ${counts.map((c, i) => `Список ${i + 1} — ${c}`).join(', ')}`);
      return;
    }

    // 3. Шаблон
    const templateText = templateEl.value;
    if (!templateText.trim()) {
      showWarning('Шаблон пуст');
      return;
    }

    // 4. Размер группы (опционально)
    const rawSize = groupSizeEl.value.trim();
    let groupSize = null;
    if (rawSize !== '') {
      const n = Number(rawSize);
      if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {
        showWarning('Размер группы должен быть целым числом ≥ 1');
        return;
      }
      groupSize = n;
    }
    const padLast = padLastEl.checked && groupSize !== null;

    // 5. Нет данных — нечего генерировать (но если группировка с padLast — 
    //    пользователь просил "пустые строки до полной группы", но из пустого списка
    //    всё равно ничего не выйдет; требуем хотя бы одно значение)
    if (first === 0) {
      showWarning('Списки не содержат значений');
      return;
    }

    // 6. Генерируем строки (с паддингом, если нужно)
    let totalRows = first;
    if (groupSize !== null) {
      const remainder = first % groupSize;
      if (remainder !== 0 && padLast) {
        totalRows = first + (groupSize - remainder);
      }
    }

    const lines = [];
    for (let row = 0; row < totalRows; row++) {
      lines.push(buildRow(templateText, blocks, row));
    }

    // 7. Группируем
    if (groupSize === null) {
      outEl.value = lines.join('\n');
    } else {
      const groups = [];
      for (let i = 0; i < lines.length; i += groupSize) {
        groups.push(lines.slice(i, i + groupSize).join('\n'));
      }
      outEl.value = groups.join('\n\n');
    }
  }

  // ---- Копирование ----
  async function copyOutput() {
    if (!outEl.value) return;
    try {
      await navigator.clipboard.writeText(outEl.value);
      const btn = document.getElementById('buildertdCopy');
      const old = btn.textContent;
      btn.textContent = 'Скопировано!';
      setTimeout(() => btn.textContent = old, 1200);
    } catch (e) {
      outEl.select();
      document.execCommand('copy');
    }
  }

  // ---- События ----
  document.getElementById('buildertdAddList').addEventListener('click', () => {
    createListBlock();
    renumberLists();
  });
  document.getElementById('buildertdGenerate').addEventListener('click', generate);
  document.getElementById('buildertdCopy').addEventListener('click', copyOutput);

  // Начальные списки
  createListBlock();
  createListBlock();
  renumberLists();
  updatePadState();
})();
</script>

Подпись автора

https://i.imgur.com/5o0dxGP.png
♥️
поле чудес х rich bitch x капсула х  капсула'23
«good morning, reasons why I drink.»

0


Вы здесь » dust ultimate two » Организация » для сбора табличке 2


Рейтинг форумов | Создать форум бесплатно