diff --git a/cleaner.js b/cleaner.js
new file mode 100644
index 0000000..78dc0ce
--- /dev/null
+++ b/cleaner.js
@@ -0,0 +1,86 @@
+// cleaner.js — Node.js модуль для безопасной очистки комментариев
+const strip = require('strip-comments');
+const fs = require('fs');
+const path = require('path');
+
+const SUPPORTED = ['.js', '.css', '.ejs'];
+
+// Очистка контента по расширению
+function cleanContent(content, ext) {
+ if (!SUPPORTED.includes(ext)) return content;
+ // EJS: удаляем только <%# комментарии %>, остальное — strip-comments
+ if (ext === '.ejs') content = content.replace(/<%#.*?%>/gs, '');
+ return strip(content, { preserveNewlines: true });
+}
+
+// Обработать один файл
+function processFile(inputPath, outputPath = null) {
+ const ext = path.extname(inputPath).toLowerCase();
+ if (!SUPPORTED.includes(ext)) return { skipped: inputPath };
+
+ const content = fs.readFileSync(inputPath, 'utf8');
+ const cleaned = cleanContent(content, ext);
+ const target = outputPath || inputPath;
+
+ fs.mkdirSync(path.dirname(target), { recursive: true });
+ fs.writeFileSync(target, cleaned, 'utf8');
+ return { ok: inputPath };
+}
+
+// Обработать папку рекурсивно
+function processDirectory(inputDir, outputDir = null) {
+ const results = { processed: [], skipped: [], errors: [] };
+
+ function walk(dir, outBase) {
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
+ const inPath = path.join(dir, entry.name);
+ const outPath = outBase ? path.join(outBase, path.relative(inputDir, inPath)) : null;
+
+ if (entry.isDirectory()) {
+ walk(inPath, outBase ? path.dirname(outPath) : null);
+ } else {
+ const ext = path.extname(entry.name).toLowerCase();
+ if (SUPPORTED.includes(ext)) {
+ try {
+ processFile(inPath, outPath);
+ results.processed.push(entry.name);
+ } catch (e) {
+ results.errors.push(`${entry.name}: ${e.message}`);
+ }
+ } else {
+ results.skipped.push(entry.name);
+ }
+ }
+ }
+ }
+
+ walk(inputDir, outputDir);
+ return results;
+}
+
+// CLI режим
+if (require.main === module) {
+ const [,, cmd, input, output] = process.argv;
+
+ if (cmd === 'file' && input) {
+ const res = processFile(input, output || null);
+ if (res.ok) console.log(`[OK] ${path.basename(input)}`);
+ else if (res.skipped) console.log(`[SKIP] ${path.basename(input)}`);
+ process.exit(0);
+ }
+
+ if (cmd === 'dir' && input) {
+ const res = processDirectory(input, output || null);
+ console.log(`✅ Обработано: ${res.processed.length}`);
+ if (res.skipped.length) console.log(`⊘ Пропущено: ${res.skipped.length}`);
+ if (res.errors.length) console.error(`❌ Ошибки: ${res.errors.join(', ')}`);
+ process.exit(res.errors.length ? 1 : 0);
+ }
+
+ console.log('Использование:');
+ console.log(' node cleaner.js file [output]');
+ console.log(' node cleaner.js dir [outputDir]');
+ process.exit(1);
+}
+
+module.exports = { cleanContent, processFile, processDirectory, SUPPORTED };
\ No newline at end of file
diff --git a/launcher.ps1 b/launcher.ps1
new file mode 100644
index 0000000..d6108c4
--- /dev/null
+++ b/launcher.ps1
@@ -0,0 +1,205 @@
+# ==============================================================================
+# LAUNCHER.PS1 - Обработка файлов для Node.js (Windows)
+# Использует: Node.js + strip-comments для безопасной очистки
+# Поддерживает: .js, .css, .ejs
+# ВАЖНО: Сохраняйте в UTF-8 with BOM
+# ==============================================================================
+
+# --- Настройка путей ---
+$ScriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
+$DevDirectory = Join-Path $ScriptDirectory "!DEV"
+$InputDirectory = Join-Path $ScriptDirectory "!DEV\input"
+$OutputDirectory = Join-Path $ScriptDirectory "!DEV\output"
+$CombinedFile = Join-Path $OutputDirectory "Combined_All_Files.txt"
+$CleanerScript = Join-Path $ScriptDirectory "cleaner.js"
+
+# --- Настройки ---
+$Global:RemoveComments = $true
+$SupportedExts = @('.js', '.css', '.ejs')
+
+# --- Цвета ---
+$C_CYAN = [ConsoleColor]::Cyan; $C_YELLOW = [ConsoleColor]::Yellow
+$C_GREEN = [ConsoleColor]::Green; $C_RED = [ConsoleColor]::Red
+$C_WHITE = [ConsoleColor]::White; $C_GRAY = [ConsoleColor]::DarkGray
+$C_MAGENTA = [ConsoleColor]::Magenta
+
+function Write-Color { param([string]$Text, $Color = $C_WHITE)
+ Write-Host $Text -ForegroundColor $Color
+}
+
+# --- Проверка зависимостей ---
+function Check-Deps {
+ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
+ Write-Color "[ERR] Node.js не установлен!" $C_RED
+ return $false
+ }
+ if (-not (Test-Path $CleanerScript)) {
+ Write-Color "[ERR] Не найден: cleaner.js" $C_RED
+ return $false
+ }
+ return $true
+}
+
+# --- Создание папок ---
+function Setup-Folders {
+ if (-not (Test-Path $DevDirectory)) {
+ New-Item -ItemType Directory -Force -Path $InputDirectory,$OutputDirectory | Out-Null
+ Write-Color "[OK] Папка !DEV создана" $C_GREEN
+ } else {
+ if (-not (Test-Path $InputDirectory)) { New-Item -ItemType Directory -Force -Path $InputDirectory | Out-Null }
+ if (-not (Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Force -Path $OutputDirectory | Out-Null }
+ }
+}
+
+# --- Очистка комментариев через Node.js ---
+function Clean-AllComments {
+ Write-Color "=== ОЧИСТКА КОММЕНТАРИЕВ (.js/.css/.ejs) ===" $C_CYAN
+ Write-Color "Режим: $(if ($Global:RemoveComments) { 'ВКЛ' } else { 'ВЫКЛ' })" $C_GRAY
+ Write-Host ""
+
+ if (-not $Global:RemoveComments) { Write-Color "Очистка отключена" $C_YELLOW; Write-Host ""; return }
+ if (-not (Check-Deps)) { return }
+ if (-not (Test-Path $InputDirectory)) { Write-Color "[ERR] Папка не найдена" $C_RED; return }
+
+ $result = & node $CleanerScript dir $InputDirectory 2>&1 | Out-String
+ Write-Host $result
+ Write-Color "✅ Очистка завершена" $C_GREEN
+ Write-Host ""
+}
+
+# --- Конвертация в .txt (только поддерживаемые расширения) ---
+function Convert-ToTxt {
+ Write-Color "=== КОНВЕРТАЦИЯ В .TXT ===" $C_CYAN; Write-Host ""
+ if (-not (Test-Path $InputDirectory)) { Write-Color "[ERR] Папка не найдена" $C_RED; return }
+
+ $Count = 0
+ Get-ChildItem -Path $InputDirectory -File -Recurse -ErrorAction SilentlyContinue |
+ Where-Object { $SupportedExts -contains $_.Extension -and $_.Extension -ne '.txt' } |
+ ForEach-Object {
+ $NewName = "$($_.BaseName).txt"
+ try {
+ Rename-Item -Path $_.FullName -NewName $NewName -Force
+ Write-Color "[OK] $($_.Name)" $C_GREEN
+ $Count++
+ } catch { Write-Color "[ERR] $($_.Name)" $C_RED }
+ }
+
+ Write-Color "Конвертировано: $Count" $C_WHITE; Write-Host ""
+}
+
+# --- Объединение файлов ---
+function Combine-Files {
+ Write-Color "=== ОБЪЕДИНЕНИЕ ФАЙЛОВ ===" $C_CYAN; Write-Host ""
+ if (-not (Test-Path $InputDirectory)) { Write-Color "[ERR] Папка не найдена" $C_RED; return }
+
+ $TxtFiles = Get-ChildItem -Path $InputDirectory -Filter "*.txt" -File -Recurse -ErrorAction SilentlyContinue
+ if (-not $TxtFiles) { Write-Color "[ERR] Нет .txt файлов" $C_RED; return }
+
+ Write-Color "Найдено: $($TxtFiles.Count)" $C_WHITE; Write-Host ""
+ if (-not (Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Force -Path $OutputDirectory | Out-Null }
+
+ $Header = @("ОБЪЕДИНЁННЫЙ ФАЙЛ (Node.js)", "Создан: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')",
+ "Источник: $InputDirectory", "Файлов: $($TxtFiles.Count)",
+ "Комментарии: $(if ($Global:RemoveComments) { 'УДАЛЕНЫ' } else { 'ОСТАВЛЕНЫ' })", "")
+ $Header | Set-Content -Path $CombinedFile -Encoding UTF8
+
+ foreach ($File in $TxtFiles | Sort-Object FullName) {
+ try {
+ "=" * 80 | Add-Content -Path $CombinedFile -Encoding UTF8
+ "ФАЙЛ: $($File.FullName)" | Add-Content -Path $CombinedFile -Encoding UTF8
+ "=" * 80 | Add-Content -Path $CombinedFile -Encoding UTF8
+ $Content = Get-Content -Path $File.FullName -Encoding UTF8 | Where-Object { $_ -match '\S' }
+ if ($Content) { $Content | Add-Content -Path $CombinedFile -Encoding UTF8 }
+ "" | Add-Content -Path $CombinedFile -Encoding UTF8
+ Write-Color "[OK] $($File.Name)" $C_GREEN
+ } catch { Write-Color "[ERR] $($File.Name)" $C_RED }
+ }
+
+ if (Test-Path $CombinedFile) {
+ $SizeKB = [math]::Round((Get-Item $CombinedFile).Length / 1KB, 2)
+ Write-Host ""; Write-Color "[OK] Создан: $CombinedFile ($SizeKB KB)" $C_GREEN
+ }
+ Write-Host ""
+}
+
+# --- Остальные функции (меню, настройки) ---
+function Toggle-Comments {
+ Write-Color "=== НАСТРОЙКА ===" $C_CYAN; Write-Host ""
+ $Global:RemoveComments = -not $Global:RemoveComments
+ Write-Color "Очистка: $(if ($Global:RemoveComments) { 'ВКЛ' } else { 'ВЫКЛ' })" $(if ($Global:RemoveComments) { $C_GREEN } else { $C_YELLOW })
+ Write-Host ""
+}
+
+function Clean-All {
+ Write-Color "=== СБРОС ПРОЕКТА ===" $C_RED; Write-Host ""
+ if (Test-Path $DevDirectory) { Remove-Item -Path $DevDirectory -Recurse -Force; Write-Color "[OK] !DEV удалена" $C_GREEN }
+ Setup-Folders; Write-Color "[OK] Структура восстановлена" $C_GREEN; Write-Host ""
+}
+
+function Open-Folder {
+ if (Test-Path $DevDirectory) { Start-Process "explorer.exe" $DevDirectory; Write-Color "[OK] Открыта !DEV" $C_GREEN }
+ else { Write-Color "[ERR] !DEV не найдена" $C_RED }
+ Write-Host ""
+}
+
+function Show-Structure {
+ Write-Color "=== СТРУКТУРА ===" $C_CYAN; Write-Host ""
+ Write-Color "Корень: $ScriptDirectory" $C_WHITE
+ if (Test-Path $DevDirectory) {
+ Write-Color "!DEV/" $C_YELLOW
+ $In = (Get-ChildItem $InputDirectory -File -Recurse -ErrorAction SilentlyContinue).Count
+ $Out = (Get-ChildItem $OutputDirectory -File -Recurse -ErrorAction SilentlyContinue).Count
+ Write-Color " input/ ($In файлов)" $C_GREEN
+ Write-Color " output/ ($Out файлов)" $C_GREEN
+ }
+ Write-Color "Поддержка: $($SupportedExts -join ', ')" $C_CYAN
+ Write-Color "Очистка: $(if ($Global:RemoveComments) { 'ВКЛ' } else { 'ВЫКЛ' })" $(if ($Global:RemoveComments) { $C_GREEN } else { $C_RED })
+ Write-Host ""
+}
+
+function Show-Header { Clear-Host
+ Write-Color "==================================================" $C_CYAN
+ Write-Color " ОБРАБОТКА ФАЙЛОВ (Node.js + PowerShell)" $C_CYAN
+ Write-Color "==================================================" $C_CYAN
+ Write-Color "Скрипт: $ScriptDirectory\launcher.ps1" $C_GRAY; Write-Host ""
+}
+
+function Show-Menu {
+ Write-Color "Действия:" $C_YELLOW
+ Write-Color "1. [ОЧИСТКА] Удалить комментарии (.js/.css/.ejs)" $C_MAGENTA
+ Write-Color "2. [КОНВЕРТ] Конвертировать в .txt" $C_CYAN
+ Write-Color "3. [ОБЪЕДИН] Объединить .txt в один файл" $C_CYAN
+ Write-Color "4. [ВСЁ] Очистка → Конвертация → Объединение" $C_GREEN
+ Write-Color "5. [НАСТР] Переключить очистку $(if ($Global:RemoveComments) { '[ВКЛ]' } else { '[ВЫКЛ]' })" $C_WHITE
+ Write-Color "6. [ПАПКА] Открыть !DEV" $C_MAGENTA
+ Write-Color "7. [ИНФО] Показать структуру" $C_WHITE
+ Write-Color "8. [СБРОС] Полная очистка" $C_RED
+ Write-Color "0. [ВЫХОД] Завершить" $C_RED; Write-Host ""
+}
+
+function Wait-ForUser { Write-Host ""; Write-Color "Нажмите любую клавишу..." $C_GRAY
+ $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
+}
+
+# ==============================================================================
+# === ЗАПУСК ===
+# ==============================================================================
+Setup-Folders
+
+do {
+ Show-Header; Show-Menu
+ $Choice = Read-Host "Выберите (0-8)"
+ Write-Host ""
+ switch ($Choice) {
+ "1" { Clean-AllComments; Wait-ForUser }
+ "2" { Convert-ToTxt; Wait-ForUser }
+ "3" { Combine-Files; Wait-ForUser }
+ "4" { Clean-AllComments; Convert-ToTxt; Combine-Files; Wait-ForUser }
+ "5" { Toggle-Comments; Wait-ForUser }
+ "6" { Open-Folder; Wait-ForUser }
+ "7" { Show-Structure; Wait-ForUser }
+ "8" { Clean-All; Wait-ForUser }
+ "0" { Write-Color "Выход..." $C_YELLOW; exit }
+ default { Write-Color "Неверный выбор!" $C_RED; Start-Sleep -Seconds 2 }
+ }
+} while ($true)
\ No newline at end of file
diff --git a/launcher.sh b/launcher.sh
new file mode 100644
index 0000000..fcc42be
--- /dev/null
+++ b/launcher.sh
@@ -0,0 +1,193 @@
+#!/bin/bash
+# ==============================================================================
+# LAUNCHER.SH - Обработка файлов для Node.js (Linux)
+# Использует: Node.js + strip-comments для безопасной очистки
+# Поддерживает: .js, .css, .ejs
+# ==============================================================================
+
+# --- Пути ---
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+DEV_DIR="$SCRIPT_DIR/!DEV"
+INPUT_DIR="$DEV_DIR/input"
+OUTPUT_DIR="$DEV_DIR/output"
+COMBINED_FILE="$OUTPUT_DIR/Combined_All_Files.txt"
+CLEANER_SCRIPT="$SCRIPT_DIR/cleaner.js"
+
+# --- Настройки ---
+REMOVE_COMMENTS=true
+SUPPORTED_EXTS=("js" "css" "ejs")
+
+# --- Цвета ---
+C_CYAN='\033[0;36m'; C_YELLOW='\033[0;33m'; C_GREEN='\033[0;32m'
+C_RED='\033[0;31m'; C_WHITE='\033[0;37m'; C_GRAY='\033[0;90m'
+C_MAGENTA='\033[0;35m'; C_RESET='\033[0m'
+
+# --- Проверка зависимостей ---
+check_deps() {
+ if ! command -v node &>/dev/null; then
+ echo -e "${C_RED}[ERR] Node.js не установлен!${C_RESET}"; return 1
+ fi
+ if [[ ! -f "$CLEANER_SCRIPT" ]]; then
+ echo -e "${C_RED}[ERR] Не найден: cleaner.js${C_RESET}"; return 1
+ fi
+ return 0
+}
+
+# --- Создание папок ---
+setup_folders() {
+ if [[ ! -d "$DEV_DIR" ]]; then
+ mkdir -p "$INPUT_DIR" "$OUTPUT_DIR"
+ echo -e "${C_GREEN}[OK] Папка !DEV создана${C_RESET}"
+ else
+ [[ ! -d "$INPUT_DIR" ]] && mkdir -p "$INPUT_DIR"
+ [[ ! -d "$OUTPUT_DIR" ]] && mkdir -p "$OUTPUT_DIR"
+ fi
+}
+
+# --- Очистка комментариев ---
+clean_all_comments() {
+ echo -e "${C_CYAN}=== ОЧИСТКА КОММЕНТАРИЕВ (.js/.css/.ejs) ===${C_RESET}"
+ echo -e "${C_GRAY}Режим: $([ "$REMOVE_COMMENTS" = true ] && echo "ВКЛ" || echo "ВЫКЛ")${C_RESET}"
+
+ [[ "$REMOVE_COMMENTS" = false ]] && { echo -e "${C_YELLOW}Очистка отключена${C_RESET}\n"; return 0; }
+ check_deps || return 1
+ [[ ! -d "$INPUT_DIR" ]] && { echo -e "${C_RED}[ERR] Папка не найдена${C_RESET}"; return 1; }
+
+ node "$CLEANER_SCRIPT" dir "$INPUT_DIR"
+ echo -e "${C_GREEN}✅ Очистка завершена${C_RESET}\n"
+}
+
+# --- Конвертация в .txt ---
+convert_to_txt() {
+ echo -e "${C_CYAN}=== КОНВЕРТАЦИЯ В .TXT ===${C_RESET}\n"
+ [[ ! -d "$INPUT_DIR" ]] && { echo -e "${C_RED}[ERR] Папка не найдена${C_RESET}"; return 1; }
+
+ local count=0
+ while IFS= read -r -d '' file; do
+ ext="${file##*.}"
+ if [[ " ${SUPPORTED_EXTS[*]} " =~ " $ext " ]] && [[ "$ext" != "txt" ]]; then
+ newname="${file%.*}.txt"
+ mv "$file" "$newname" && { echo -e "${C_GREEN}[OK] $(basename "$file")${C_RESET}"; ((count++)); }
+ fi
+ done < <(find "$INPUT_DIR" -type f -print0 2>/dev/null)
+
+ echo -e "${C_WHITE}Конвертировано: $count${C_RESET}\n"
+}
+
+# --- Объединение файлов ---
+combine_files() {
+ echo -e "${C_CYAN}=== ОБЪЕДИНЕНИЕ ФАЙЛОВ ===${C_RESET}\n"
+ [[ ! -d "$INPUT_DIR" ]] && { echo -e "${C_RED}[ERR] Папка не найдена${C_RESET}"; return 1; }
+
+ mapfile -t txt_files < <(find "$INPUT_DIR" -type f -name "*.txt" 2>/dev/null | sort)
+ local file_count=${#txt_files[@]}
+
+ [[ $file_count -eq 0 ]] && { echo -e "${C_RED}[ERR] Нет .txt файлов${C_RESET}"; return 1; }
+ echo -e "${C_WHITE}Найдено: $file_count${C_RESET}\n"
+
+ mkdir -p "$OUTPUT_DIR"
+ {
+ echo "ОБЪЕДИНЁННЫЙ ФАЙЛ (Node.js)"
+ echo "Создан: $(date '+%Y-%m-%d %H:%M:%S')"
+ echo "Источник: $INPUT_DIR"
+ echo "Файлов: $file_count"
+ echo "Комментарии: $([ "$REMOVE_COMMENTS" = true ] && echo "УДАЛЕНЫ" || echo "ОСТАВЛЕНЫ")"
+ echo ""
+ } > "$COMBINED_FILE"
+
+ for file in "${txt_files[@]}"; do
+ echo "================================================================================" >> "$COMBINED_FILE"
+ echo "ФАЙЛ: $file" >> "$COMBINED_FILE"
+ echo "================================================================================" >> "$COMBINED_FILE"
+ grep -v '^[[:space:]]*$' "$file" >> "$COMBINED_FILE" 2>/dev/null
+ echo -e "\n" >> "$COMBINED_FILE"
+ echo -e "${C_GREEN}[OK] $(basename "$file")${C_RESET}"
+ done
+
+ if [[ -f "$COMBINED_FILE" ]]; then
+ local size=$(du -h "$COMBINED_FILE" | cut -f1)
+ echo -e "\n${C_GREEN}[OK] Создан: $COMBINED_FILE ($size)${C_RESET}"
+ fi
+ echo ""
+}
+
+# --- Меню и утилиты ---
+toggle_comments() {
+ echo -e "${C_CYAN}=== НАСТРОЙКА ===${C_RESET}\n"
+ REMOVE_COMMENTS=$([ "$REMOVE_COMMENTS" = true ] && echo false || echo true)
+ echo -e "${C_YELLOW}Очистка: $([ "$REMOVE_COMMENTS" = true ] && echo "ВКЛ" || echo "ВЫКЛ")${C_RESET}\n"
+}
+
+clean_all() {
+ echo -e "${C_RED}=== СБРОС ПРОЕКТА ===${C_RESET}\n"
+ [[ -d "$DEV_DIR" ]] && { rm -rf "$DEV_DIR"; echo -e "${C_GREEN}[OK] !DEV удалена${C_RESET}"; }
+ setup_folders; echo -e "${C_GREEN}[OK] Структура восстановлена${C_RESET}\n"
+}
+
+open_folder() {
+ if [[ -d "$DEV_DIR" ]]; then
+ (xdg-open "$DEV_DIR" 2>/dev/null || open "$DEV_DIR" 2>/dev/null || echo "Откройте: $DEV_DIR") &
+ echo -e "${C_GREEN}[OK] Открыта !DEV${C_RESET}"
+ else
+ echo -e "${C_RED}[ERR] !DEV не найдена${C_RESET}"
+ fi
+ echo ""
+}
+
+show_structure() {
+ echo -e "${C_CYAN}=== СТРУКТУРА ===${C_RESET}\n"
+ echo -e "${C_WHITE}Корень: $SCRIPT_DIR${C_RESET}"
+ if [[ -d "$DEV_DIR" ]]; then
+ echo -e "${C_YELLOW}!DEV/${C_RESET}"
+ echo -e " ${C_GREEN}input/ ($(find "$INPUT_DIR" -type f 2>/dev/null | wc -l) файлов)${C_RESET}"
+ echo -e " ${C_GREEN}output/ ($(find "$OUTPUT_DIR" -type f 2>/dev/null | wc -l) файлов)${C_RESET}"
+ fi
+ echo -e "${C_CYAN}Поддержка: ${SUPPORTED_EXTS[*]}${C_RESET}"
+ echo -e "${C_WHITE}Очистка: $([ "$REMOVE_COMMENTS" = true ] && echo -e "${C_GREEN}ВКЛ" || echo -e "${C_RED}ВЫКЛ")${C_RESET}\n"
+}
+
+show_header() {
+ clear
+ echo -e "${C_CYAN}==================================================${C_RESET}"
+ echo -e "${C_CYAN} ОБРАБОТКА ФАЙЛОВ (Node.js + Bash)${C_RESET}"
+ echo -e "${C_CYAN}==================================================${C_RESET}"
+ echo -e "${C_GRAY}Скрипт: $SCRIPT_DIR/launcher.sh${C_RESET}\n"
+}
+
+show_menu() {
+ echo -e "${C_YELLOW}Действия:${C_RESET}"
+ echo -e "1. ${C_MAGENTA}[ОЧИСТКА] Удалить комментарии (.js/.css/.ejs)${C_RESET}"
+ echo -e "2. ${C_CYAN}[КОНВЕРТ] Конвертировать в .txt${C_RESET}"
+ echo -e "3. ${C_CYAN}[ОБЪЕДИН] Объединить .txt в один файл${C_RESET}"
+ echo -e "4. ${C_GREEN}[ВСЁ] Очистка → Конвертация → Объединение${C_RESET}"
+ echo -e "5. ${C_WHITE}[НАСТР] Переключить очистку$([ "$REMOVE_COMMENTS" = true ] && echo " [ВКЛ]" || echo " [ВЫКЛ]")${C_RESET}"
+ echo -e "6. ${C_MAGENTA}[ПАПКА] Открыть !DEV${C_RESET}"
+ echo -e "7. ${C_WHITE}[ИНФО] Показать структуру${C_RESET}"
+ echo -e "8. ${C_RED}[СБРОС] Полная очистка${C_RESET}"
+ echo -e "0. ${C_RED}[ВЫХОД] Завершить${C_RESET}\n"
+}
+
+wait_for_user() { echo ""; read -p "Нажмите Enter для возврата..." < /dev/tty; }
+
+# ==============================================================================
+# === ЗАПУСК ===
+# ==============================================================================
+setup_folders
+
+while true; do
+ show_header; show_menu
+ read -p "Выберите (0-8): " choice
+ echo ""
+ case $choice in
+ 1) clean_all_comments; wait_for_user ;;
+ 2) convert_to_txt; wait_for_user ;;
+ 3) combine_files; wait_for_user ;;
+ 4) clean_all_comments; convert_to_txt; combine_files; wait_for_user ;;
+ 5) toggle_comments; wait_for_user ;;
+ 6) open_folder; wait_for_user ;;
+ 7) show_structure; wait_for_user ;;
+ 8) clean_all; wait_for_user ;;
+ 0) echo -e "${C_YELLOW}Выход...${C_RESET}"; exit 0 ;;
+ *) echo -e "${C_RED}Неверный выбор!${C_RESET}"; sleep 2 ;;
+ esac
+done
\ No newline at end of file
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
new file mode 100644
index 0000000..d98ca57
--- /dev/null
+++ b/node_modules/.package-lock.json
@@ -0,0 +1,17 @@
+{
+ "name": "devops",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "node_modules/strip-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
+ "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ }
+ }
+}
diff --git a/node_modules/strip-comments/CHANGELOG.md b/node_modules/strip-comments/CHANGELOG.md
new file mode 100644
index 0000000..7d21565
--- /dev/null
+++ b/node_modules/strip-comments/CHANGELOG.md
@@ -0,0 +1,136 @@
+# Release history
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+
+ Guiding Principles
+
+- Changelogs are for humans, not machines.
+- There should be an entry for every single version.
+- The same types of changes should be grouped.
+- Versions and sections should be linkable.
+- The latest version comes first.
+- The release date of each versions is displayed.
+- Mention whether you follow Semantic Versioning.
+
+
+
+
+ Types of changes
+
+Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_):
+
+- `Added` for new features.
+- `Changed` for changes in existing functionality.
+- `Deprecated` for soon-to-be removed features.
+- `Removed` for now removed features.
+- `Fixed` for any bug fixes.
+- `Security` in case of vulnerabilities.
+
+
+
+
+## [2.0.0] - 2019-09-14
+
+**Changed**
+
+- Refactored again to use a custom parser that is much faster and supports a number of different languages.
+
+## [1.0.2] - 2018-05-03
+
+- refactored
+- Remove default objectRestSpread plugin #40 allows for user configured plugins
+- Merge pull request #42 from tallarium/remove-default-transform
+- Merge remote-tracking branch 'origin/master' into refactor
+- Merge remote-tracking branch 'origin/master' into refactor
+- Merge pull request #44 from jonschlinkert/refactor
+
+## [1.0.1] - 2018-03-24
+
+- feat: Allow users to specify their own babylon plugins
+- Merge pull request #40 from briandipalma/patch-1
+- adds `allowReturnOutsideFunction` to defaults
+
+## [1.0.0] - 2018-03-24
+
+- adds object-rest-spread plugin
+
+## [0.4.4] - 2016-02-14
+
+- refactor to use babylon
+
+## [0.4.3] - 2015-12-25
+
+- minor tweak
+
+## [0.4.2] - 2015-12-11
+
+- bump extract-comments per issue https://github.com/jonschlinkert/strip-comments/issues/29
+- Merge branch 'master' of https://github.com/lebbe/strip-comments into lebbe-master
+- Merge branch 'lebbe-master'
+
+## [0.4.0] - 2015-11-04
+
+- adds more test cases
+- closes https://github.com/jonschlinkert/strip-comments/issues/18
+- Handles comments that are substrings of a later comment
+- Merge pull request #28 from epicoxymoron/bugfix/27-discard-is-too-greedy
+- adds example
+- adds json test
+
+## [0.3.4] - 2015-10-22
+
+- refactored
+- expose `first` method. code comments, minor formatting
+- allow line/block to be specified as options
+- Merge pull request #23 from jonschlinkert/dev
+- fixes examples
+- adds editorconfig
+
+## [0.3.0] - 2014-09-02
+
+- merge fix from origin
+- Merge pull request #13 from mk-pmb/tests_literals_nocomment
+- Merge pull request #15 from mk-pmb/tests_literals_snake
+- Merge pull request #22 from kgryte/patch-1
+- Merge pull request #9 from tunnckoCore/master
+- Merge remote-tracking branch 'origin/line-comments'
+- Merge remote-tracking branch 'origin/master'
+- tests: not a comment: snake-y ASCII art
+- tests: string and regexp literals
+- adds tests for URLs
+- fix globstars
+- lint
+
+## [0.2.0] - 2014-08-10
+
+- fixes `use strict` statement
+
+## [0.1.6] - 2014-02-13
+
+- Merge branch 'master' of https://github.com/tunnckoCore/strip-comments into tunnckoCore-master
+- Merge branch 'tunnckoCore-master'
+- minor formatting
+
+## [0.1.0] - 2014-02-10
+
+- first commit
+
+[1.0.2]: https://github.com/jonschlinkert/strip-comments/compare/1.0.1...1.0.2
+[1.0.1]: https://github.com/jonschlinkert/strip-comments/compare/1.0.0...1.0.1
+[1.0.0]: https://github.com/jonschlinkert/strip-comments/compare/0.4.4...1.0.0
+[0.4.4]: https://github.com/jonschlinkert/strip-comments/compare/0.4.3...0.4.4
+[0.4.3]: https://github.com/jonschlinkert/strip-comments/compare/0.4.2...0.4.3
+[0.4.2]: https://github.com/jonschlinkert/strip-comments/compare/0.4.0...0.4.2
+[0.4.0]: https://github.com/jonschlinkert/strip-comments/compare/0.3.4...0.4.0
+[0.3.4]: https://github.com/jonschlinkert/strip-comments/compare/0.3.0...0.3.4
+[0.3.0]: https://github.com/jonschlinkert/strip-comments/compare/0.2.0...0.3.0
+[0.2.0]: https://github.com/jonschlinkert/strip-comments/compare/0.1.6...0.2.0
+[0.1.6]: https://github.com/jonschlinkert/strip-comments/compare/0.1.0...0.1.6
+
+[Unreleased]: https://github.com/jonschlinkert/strip-comments/compare/0.1.0...HEAD
+[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog
+
diff --git a/node_modules/strip-comments/LICENSE b/node_modules/strip-comments/LICENSE
new file mode 100644
index 0000000..9af4a67
--- /dev/null
+++ b/node_modules/strip-comments/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-present, Jon Schlinkert.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/node_modules/strip-comments/README.md b/node_modules/strip-comments/README.md
new file mode 100644
index 0000000..62ec4fe
--- /dev/null
+++ b/node_modules/strip-comments/README.md
@@ -0,0 +1,237 @@
+# strip-comments [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/strip-comments) [](https://npmjs.org/package/strip-comments) [](https://npmjs.org/package/strip-comments) [](https://travis-ci.org/jonschlinkert/strip-comments)
+
+> Strip line and/or block comments from a string. Blazing fast, and works with JavaScript, Sass, CSS, Less.js, and a number of other languages.
+
+Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
+
+- [Install](#install)
+- [What does this do?](#what-does-this-do)
+- [Usage](#usage)
+- [API](#api)
+- [About](#about)
+
+_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
+
+## Install
+
+Install with [npm](https://www.npmjs.com/) (requires [Node.js](https://nodejs.org/en/) >=10):
+
+```sh
+$ npm install --save strip-comments
+```
+
+## What does this do?
+
+Takes a string and returns a new string with comments removed. Works with line comments and/or block comments. Optionally removes the first comment only or ignores protected comments.
+
+Works with:
+
+* ada
+* apl
+* applescript
+* c
+* csharp
+* css
+* hashbang
+* haskell
+* html
+* java
+* javascript
+* less
+* lua
+* matlab
+* ocaml
+* pascal
+* perl
+* php
+* python
+* ruby
+* sass
+* shebang
+* sql
+* swift
+* typscript
+* xml
+
+## Usage
+
+By default all comments are stripped.
+
+```js
+const strip = require('strip-comments');
+const str = strip('const foo = "bar";// this is a comment\n /* me too *\/');
+console.log(str);
+// => 'const foo = "bar";\n'
+```
+
+For more use-cases see the [tests](./test/test.js)
+
+## API
+
+### [strip](index.js#L33)
+
+Strip all code comments from the given `input`, including protected comments that start with `!`, unless disabled by setting `options.keepProtected` to true.
+
+**Params**
+
+* `input` **{String}**: string from which to strip comments
+* `options` **{Object}**: optional options, passed to [extract-comments](https://github.com/jonschlinkert/extract-comments)
+
+- `line` **{Boolean}**: if `false` strip only block comments, default `true`
+- `block` **{Boolean}**: if `false` strip only line comments, default `true`
+- `keepProtected` **{Boolean}**: Keep ignored comments (e.g. `/*!` and `//!`)
+- `preserveNewlines` **{Boolean}**: Preserve newlines after comments are stripped
+* `returns` **{String}**: modified input
+
+**Example**
+
+```js
+const str = strip('const foo = "bar";// this is a comment\n /* me too */');
+console.log(str);
+// => 'const foo = "bar";'
+```
+
+### [.block](index.js#L54)
+
+Strip only block comments.
+
+**Params**
+
+* `input` **{String}**: string from which to strip comments
+* `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`)
+* `returns` **{String}**: modified string
+
+**Example**
+
+```js
+const strip = require('..');
+const str = strip.block('const foo = "bar";// this is a comment\n /* me too */');
+console.log(str);
+// => 'const foo = "bar";// this is a comment'
+```
+
+### [.line](index.js#L74)
+
+Strip only line comments.
+
+**Params**
+
+* `input` **{String}**: string from which to strip comments
+* `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `//!`)
+* `returns` **{String}**: modified string
+
+**Example**
+
+```js
+const str = strip.line('const foo = "bar";// this is a comment\n /* me too */');
+console.log(str);
+// => 'const foo = "bar";\n/* me too */'
+```
+
+### [.first](index.js#L95)
+
+Strip the first comment from the given `input`. Or, if `opts.keepProtected` is true, the first non-protected comment will be stripped.
+
+**Params**
+
+* `input` **{String}**
+* `options` **{Object}**: pass `opts.keepProtected: true` to keep comments with `!`
+* `returns` **{String}**
+
+**Example**
+
+```js
+const output = strip.first(input, { keepProtected: true });
+console.log(output);
+// => '//! first comment\nfoo; '
+```
+
+### [.block](index.js#L116)
+
+Parses a string and returns a basic CST (Concrete Syntax Tree).
+
+**Params**
+
+* `input` **{String}**: string from which to strip comments
+* `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`)
+* `returns` **{String}**: modified string
+
+**Example**
+
+```js
+const strip = require('..');
+const str = strip.block('const foo = "bar";// this is a comment\n /* me too */');
+console.log(str);
+// => 'const foo = "bar";// this is a comment'
+```
+
+## About
+
+
+Contributing
+
+Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
+
+
+
+
+Running Tests
+
+Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
+
+```sh
+$ npm install && npm test
+```
+
+
+
+
+Building docs
+
+_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
+
+To generate the readme, run the following command:
+
+```sh
+$ npm install -g verbose/verb#dev verb-generate-readme && verb
+```
+
+
+
+### Related projects
+
+You might also be interested in these projects:
+
+* [code-context](https://www.npmjs.com/package/code-context): Parse a string of javascript to determine the context for functions, variables and comments based… [more](https://github.com/jonschlinkert/code-context) | [homepage](https://github.com/jonschlinkert/code-context "Parse a string of javascript to determine the context for functions, variables and comments based on the code that follows.")
+* [extract-comments](https://www.npmjs.com/package/extract-comments): Uses esprima to extract line and block comments from a string of JavaScript. Also optionally… [more](https://github.com/jonschlinkert/extract-comments) | [homepage](https://github.com/jonschlinkert/extract-comments "Uses esprima to extract line and block comments from a string of JavaScript. Also optionally parses code context (the next line of code after a comment).")
+* [parse-code-context](https://www.npmjs.com/package/parse-code-context): Fast and simple way to parse code context for use with documentation from code comments… [more](https://github.com/jonschlinkert/parse-code-context) | [homepage](https://github.com/jonschlinkert/parse-code-context "Fast and simple way to parse code context for use with documentation from code comments. Parses context from a single line of JavaScript, for functions, variable declarations, methods, prototype properties, prototype methods etc.")
+* [parse-comments](https://www.npmjs.com/package/parse-comments): Parse code comments from JavaScript or any language that uses the same format. | [homepage](https://github.com/jonschlinkert/parse-comments "Parse code comments from JavaScript or any language that uses the same format.")
+
+### Contributors
+
+| **Commits** | **Contributor** |
+| --- | --- |
+| 82 | [jonschlinkert](https://github.com/jonschlinkert) |
+| 4 | [tunnckoCore](https://github.com/tunnckoCore) |
+| 2 | [mk-pmb](https://github.com/mk-pmb) |
+| 1 | [kgryte](https://github.com/kgryte) |
+| 1 | [briandipalma](https://github.com/briandipalma) |
+| 1 | [epicoxymoron](https://github.com/epicoxymoron) |
+| 1 | [XuluWarrior](https://github.com/XuluWarrior) |
+
+### Author
+
+**Jon Schlinkert**
+
+* [GitHub Profile](https://github.com/jonschlinkert)
+* [Twitter Profile](https://twitter.com/jonschlinkert)
+* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
+
+### License
+
+Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
+Released under the [MIT License](LICENSE).
+
+***
+
+_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on November 13, 2019._
\ No newline at end of file
diff --git a/node_modules/strip-comments/index.js b/node_modules/strip-comments/index.js
new file mode 100644
index 0000000..7dcedb3
--- /dev/null
+++ b/node_modules/strip-comments/index.js
@@ -0,0 +1,116 @@
+/*!
+ * strip-comments
+ * Copyright (c) 2014-present, Jon Schlinkert.
+ * Released under the MIT License.
+ */
+
+'use strict';
+
+const compile = require('./lib/compile');
+const parse = require('./lib/parse');
+
+/**
+ * Strip all code comments from the given `input`, including protected
+ * comments that start with `!`, unless disabled by setting `options.keepProtected`
+ * to true.
+ *
+ * ```js
+ * const str = strip('const foo = "bar";// this is a comment\n /* me too *\/');
+ * console.log(str);
+ * // => 'const foo = "bar";'
+ * ```
+ * @name strip
+ * @param {String} `input` string from which to strip comments
+ * @param {Object} `options` optional options, passed to [extract-comments][extract-comments]
+ * @option {Boolean} [options] `line` if `false` strip only block comments, default `true`
+ * @option {Boolean} [options] `block` if `false` strip only line comments, default `true`
+ * @option {Boolean} [options] `keepProtected` Keep ignored comments (e.g. `/*!` and `//!`)
+ * @option {Boolean} [options] `preserveNewlines` Preserve newlines after comments are stripped
+ * @return {String} modified input
+ * @api public
+ */
+
+const strip = module.exports = (input, options) => {
+ const opts = { ...options, block: true, line: true };
+ return compile(parse(input, opts), opts);
+};
+
+/**
+ * Strip only block comments.
+ *
+ * ```js
+ * const strip = require('..');
+ * const str = strip.block('const foo = "bar";// this is a comment\n /* me too *\/');
+ * console.log(str);
+ * // => 'const foo = "bar";// this is a comment'
+ * ```
+ * @name .block
+ * @param {String} `input` string from which to strip comments
+ * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`)
+ * @return {String} modified string
+ * @api public
+ */
+
+strip.block = (input, options) => {
+ const opts = { ...options, block: true };
+ return compile(parse(input, opts), opts);
+};
+
+/**
+ * Strip only line comments.
+ *
+ * ```js
+ * const str = strip.line('const foo = "bar";// this is a comment\n /* me too *\/');
+ * console.log(str);
+ * // => 'const foo = "bar";\n/* me too *\/'
+ * ```
+ * @name .line
+ * @param {String} `input` string from which to strip comments
+ * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `//!`)
+ * @return {String} modified string
+ * @api public
+ */
+
+strip.line = (input, options) => {
+ const opts = { ...options, line: true };
+ return compile(parse(input, opts), opts);
+};
+
+/**
+ * Strip the first comment from the given `input`. Or, if `opts.keepProtected` is true,
+ * the first non-protected comment will be stripped.
+ *
+ * ```js
+ * const output = strip.first(input, { keepProtected: true });
+ * console.log(output);
+ * // => '//! first comment\nfoo; '
+ * ```
+ * @name .first
+ * @param {String} `input`
+ * @param {Object} `options` pass `opts.keepProtected: true` to keep comments with `!`
+ * @return {String}
+ * @api public
+ */
+
+strip.first = (input, options) => {
+ const opts = { ...options, block: true, line: true, first: true };
+ return compile(parse(input, opts), opts);
+};
+
+/**
+ * Parses a string and returns a basic CST (Concrete Syntax Tree).
+ *
+ * ```js
+ * const strip = require('..');
+ * const str = strip.block('const foo = "bar";// this is a comment\n /* me too *\/');
+ * console.log(str);
+ * // => 'const foo = "bar";// this is a comment'
+ * ```
+ * @name .block
+ * @param {String} `input` string from which to strip comments
+ * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`)
+ * @return {String} modified string
+ * @api public
+ */
+
+strip.parse = parse;
diff --git a/node_modules/strip-comments/lib/Node.js b/node_modules/strip-comments/lib/Node.js
new file mode 100644
index 0000000..c0c81f7
--- /dev/null
+++ b/node_modules/strip-comments/lib/Node.js
@@ -0,0 +1,28 @@
+'use strict';
+
+class Node {
+ constructor(node) {
+ this.type = node.type;
+ if (node.value) this.value = node.value;
+ if (node.match) this.match = node.match;
+ this.newline = node.newline || '';
+ }
+ get protected() {
+ return Boolean(this.match) && this.match[1] === '!';
+ }
+}
+
+class Block extends Node {
+ constructor(node) {
+ super(node);
+ this.nodes = node.nodes || [];
+ }
+ push(node) {
+ this.nodes.push(node);
+ }
+ get protected() {
+ return this.nodes.length > 0 && this.nodes[0].protected === true;
+ }
+}
+
+module.exports = { Node, Block };
diff --git a/node_modules/strip-comments/lib/compile.js b/node_modules/strip-comments/lib/compile.js
new file mode 100644
index 0000000..951ff3e
--- /dev/null
+++ b/node_modules/strip-comments/lib/compile.js
@@ -0,0 +1,63 @@
+'use strict';
+
+const compile = (cst, options = {}) => {
+ const keepProtected = options.safe === true || options.keepProtected === true;
+ let firstSeen = false;
+
+ const walk = (node, parent) => {
+ let output = '';
+ let inner;
+ let lines;
+
+ for (const child of node.nodes) {
+ switch (child.type) {
+ case 'block':
+ if (options.first && firstSeen === true) {
+ output += walk(child, node);
+ break;
+ }
+
+ if (options.preserveNewlines === true) {
+ inner = walk(child, node);
+ lines = inner.split('\n');
+ output += '\n'.repeat(lines.length - 1);
+ break;
+ }
+
+ if (keepProtected === true && child.protected === true) {
+ output += walk(child, node);
+ break;
+ }
+
+ firstSeen = true;
+ break;
+ case 'line':
+ if (options.first && firstSeen === true) {
+ output += child.value;
+ break;
+ }
+
+ if (keepProtected === true && child.protected === true) {
+ output += child.value;
+ }
+
+ firstSeen = true;
+ break;
+ case 'open':
+ case 'close':
+ case 'text':
+ case 'newline':
+ default: {
+ output += child.value || '';
+ break;
+ }
+ }
+ }
+
+ return output;
+ };
+
+ return walk(cst);
+};
+
+module.exports = compile;
diff --git a/node_modules/strip-comments/lib/languages.js b/node_modules/strip-comments/lib/languages.js
new file mode 100644
index 0000000..362776d
--- /dev/null
+++ b/node_modules/strip-comments/lib/languages.js
@@ -0,0 +1,85 @@
+'use strict';
+
+exports.ada = { LINE_REGEX: /^--.*/ };
+exports.apl = { LINE_REGEX: /^⍝.*/ };
+
+exports.applescript = {
+ BLOCK_OPEN_REGEX: /^\(\*/,
+ BLOCK_CLOSE_REGEX: /^\*\)/
+};
+
+exports.csharp = {
+ LINE_REGEX: /^\/\/.*/
+};
+
+exports.haskell = {
+ BLOCK_OPEN_REGEX: /^\{-/,
+ BLOCK_CLOSE_REGEX: /^-\}/,
+ LINE_REGEX: /^--.*/
+};
+
+exports.html = {
+ BLOCK_OPEN_REGEX: /^\n*/,
+ BLOCK_CLOSE_LOOSE_REGEX: /^(?/,
+ BLOCK_CLOSE_STRICT_NEWLINE_REGEX: /^(?(\s*\n+|\n*)/,
+ BLOCK_CLOSE_STRICT_LOOSE_REGEX: /^(?(\s*\n+|\n*)/
+};
+
+exports.javascript = {
+ BLOCK_OPEN_REGEX: /^\/\*\*?(!?)/,
+ BLOCK_CLOSE_REGEX: /^\*\/(\n?)/,
+ LINE_REGEX: /^\/\/(!?).*/
+};
+
+exports.lua = {
+ BLOCK_OPEN_REGEX: /^--\[\[/,
+ BLOCK_CLOSE_REGEX: /^\]\]/,
+ LINE_REGEX: /^--.*/
+};
+
+exports.matlab = {
+ BLOCK_OPEN_REGEX: /^%{/,
+ BLOCK_CLOSE_REGEX: /^%}/,
+ LINE_REGEX: /^%.*/
+};
+
+exports.perl = {
+ LINE_REGEX: /^#.*/
+};
+
+exports.php = {
+ ...exports.javascript,
+ LINE_REGEX: /^(#|\/\/).*?(?=\?>|\n)/
+};
+
+exports.python = {
+ BLOCK_OPEN_REGEX: /^"""/,
+ BLOCK_CLOSE_REGEX: /^"""/,
+ LINE_REGEX: /^#.*/
+};
+
+exports.ruby = {
+ BLOCK_OPEN_REGEX: /^=begin/,
+ BLOCK_CLOSE_REGEX: /^=end/,
+ LINE_REGEX: /^#.*/
+};
+
+exports.shebang = exports.hashbang = {
+ LINE_REGEX: /^#!.*/
+};
+
+exports.c = exports.javascript;
+exports.csharp = exports.javascript;
+exports.css = exports.javascript;
+exports.java = exports.javascript;
+exports.js = exports.javascript;
+exports.less = exports.javascript;
+exports.pascal = exports.applescript;
+exports.ocaml = exports.applescript;
+exports.sass = exports.javascript;
+exports.sql = exports.ada;
+exports.swift = exports.javascript;
+exports.ts = exports.javascript;
+exports.typscript = exports.javascript;
+exports.xml = exports.html;
diff --git a/node_modules/strip-comments/lib/parse.js b/node_modules/strip-comments/lib/parse.js
new file mode 100644
index 0000000..1097ba3
--- /dev/null
+++ b/node_modules/strip-comments/lib/parse.js
@@ -0,0 +1,141 @@
+'use strict';
+
+const { Node, Block } = require('./Node');
+const languages = require('./languages');
+
+const constants = {
+ ESCAPED_CHAR_REGEX: /^\\./,
+ QUOTED_STRING_REGEX: /^(['"`])((?:\\.|[^\1])+?)(\1)/,
+ NEWLINE_REGEX: /^\r*\n/
+};
+
+const parse = (input, options = {}) => {
+ if (typeof input !== 'string') {
+ throw new TypeError('Expected input to be a string');
+ }
+
+ const cst = new Block({ type: 'root', nodes: [] });
+ const stack = [cst];
+ const name = (options.language || 'javascript').toLowerCase();
+ const lang = languages[name];
+
+ if (typeof lang === 'undefined') {
+ throw new Error(`Language "${name}" is not supported by strip-comments`);
+ }
+
+ const { LINE_REGEX, BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX } = lang;
+ let block = cst;
+ let remaining = input;
+ let token;
+ let prev;
+
+ const source = [BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX].filter(Boolean);
+ let tripleQuotes = false;
+
+ if (source.every(regex => regex.source === '^"""')) {
+ tripleQuotes = true;
+ }
+
+ /**
+ * Helpers
+ */
+
+ const consume = (value = remaining[0] || '') => {
+ remaining = remaining.slice(value.length);
+ return value;
+ };
+
+ const scan = (regex, type = 'text') => {
+ const match = regex.exec(remaining);
+ if (match) {
+ consume(match[0]);
+ return { type, value: match[0], match };
+ }
+ };
+
+ const push = node => {
+ if (prev && prev.type === 'text' && node.type === 'text') {
+ prev.value += node.value;
+ return;
+ }
+ block.push(node);
+ if (node.nodes) {
+ stack.push(node);
+ block = node;
+ }
+ prev = node;
+ };
+
+ const pop = () => {
+ if (block.type === 'root') {
+ throw new SyntaxError('Unclosed block comment');
+ }
+ stack.pop();
+ block = stack[stack.length - 1];
+ };
+
+ /**
+ * Parse input string
+ */
+
+ while (remaining !== '') {
+ // escaped characters
+ if ((token = scan(constants.ESCAPED_CHAR_REGEX, 'text'))) {
+ push(new Node(token));
+ continue;
+ }
+
+ // quoted strings
+ if (block.type !== 'block' && (!prev || !/\w$/.test(prev.value)) && !(tripleQuotes && remaining.startsWith('"""'))) {
+ if ((token = scan(constants.QUOTED_STRING_REGEX, 'text'))) {
+ push(new Node(token));
+ continue;
+ }
+ }
+
+ // newlines
+ if ((token = scan(constants.NEWLINE_REGEX, 'newline'))) {
+ push(new Node(token));
+ continue;
+ }
+
+ // block comment open
+ if (BLOCK_OPEN_REGEX && options.block && !(tripleQuotes && block.type === 'block')) {
+ if ((token = scan(BLOCK_OPEN_REGEX, 'open'))) {
+ push(new Block({ type: 'block' }));
+ push(new Node(token));
+ continue;
+ }
+ }
+
+ // block comment close
+ if (BLOCK_CLOSE_REGEX && block.type === 'block' && options.block) {
+ if ((token = scan(BLOCK_CLOSE_REGEX, 'close'))) {
+ token.newline = token.match[1] || '';
+ push(new Node(token));
+ pop();
+ continue;
+ }
+ }
+
+ // line comment
+ if (LINE_REGEX && block.type !== 'block' && options.line) {
+ if ((token = scan(LINE_REGEX, 'line'))) {
+ push(new Node(token));
+ continue;
+ }
+ }
+
+ // Plain text (skip "C" since some languages use "C" to start comments)
+ if ((token = scan(/^[a-zABD-Z0-9\t ]+/, 'text'))) {
+ push(new Node(token));
+ continue;
+ }
+
+ push(new Node({ type: 'text', value: consume(remaining[0]) }));
+ }
+
+ return cst;
+};
+
+module.exports = parse;
diff --git a/node_modules/strip-comments/package.json b/node_modules/strip-comments/package.json
new file mode 100644
index 0000000..7926efe
--- /dev/null
+++ b/node_modules/strip-comments/package.json
@@ -0,0 +1,102 @@
+{
+ "name": "strip-comments",
+ "description": "Strip line and/or block comments from a string. Blazing fast, and works with JavaScript, Sass, CSS, Less.js, and a number of other languages.",
+ "version": "2.0.1",
+ "homepage": "https://github.com/jonschlinkert/strip-comments",
+ "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
+ "repository": "jonschlinkert/strip-comments",
+ "bugs": {
+ "url": "https://github.com/jonschlinkert/strip-comments/issues"
+ },
+ "license": "MIT",
+ "files": [
+ "index.js",
+ "lib"
+ ],
+ "main": "index.js",
+ "engines": {
+ "node": ">=10"
+ },
+ "scripts": {
+ "test": "mocha",
+ "cover": "nyc --reporter=text --reporter=html mocha"
+ },
+ "devDependencies": {
+ "gulp-format-md": "^2.0.0",
+ "mocha": "^6.2.2",
+ "nyc": "^14.1.1"
+ },
+ "keywords": [
+ "ada comments",
+ "apl comments",
+ "applescript comments",
+ "block comment",
+ "block",
+ "block-comment",
+ "c comments",
+ "code comment",
+ "comment",
+ "comments",
+ "csharp comments",
+ "css comments",
+ "css",
+ "hashbang comments",
+ "haskell comments",
+ "html comments",
+ "java comments",
+ "javascript comments",
+ "javascript",
+ "js",
+ "less comments",
+ "less css",
+ "less",
+ "less.js",
+ "lessjs",
+ "line comment",
+ "line comments",
+ "line",
+ "line-comment",
+ "line-comments",
+ "lua comments",
+ "matlab comments",
+ "ocaml comments",
+ "pascal comments",
+ "perl comments",
+ "php comments",
+ "python comments",
+ "remove",
+ "ruby comments",
+ "sass comments",
+ "sass",
+ "shebang comments",
+ "sql comments",
+ "strip",
+ "swift comments",
+ "typscript comments",
+ "xml comments"
+ ],
+ "verb": {
+ "toc": true,
+ "layout": "default",
+ "tasks": [
+ "readme"
+ ],
+ "plugins": [
+ "gulp-format-md"
+ ],
+ "helpers": [
+ "./examples/support/helpers.js"
+ ],
+ "related": {
+ "list": [
+ "code-context",
+ "extract-comments",
+ "parse-code-context",
+ "parse-comments"
+ ]
+ },
+ "lint": {
+ "reflinks": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..da2c6da
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,25 @@
+{
+ "name": "devops",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "devops",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "strip-comments": "^2.0.1"
+ }
+ },
+ "node_modules/strip-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
+ "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7d4a0a7
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "devops",
+ "version": "1.0.0",
+ "description": "",
+ "main": "cleaner.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "strip-comments": "^2.0.1"
+ }
+}