TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
이미지 변환·압축, PDF 병합·분할, JSON 포맷팅·텍스트 정리. 빠르고 무료, 브라우저에서 회원가입 없이 사용
Convert and compress images, merge and split PDFs, format JSON and clean text. Fast, free tools that run in your browser, with no sign-up.
생산성TypeScript · CSSGitHub @boostifymedia4-glitch온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A fast, privacy-friendly website of 69 everyday tools (image, PDF, text, developer) in 25 interface languages. Every tool runs in the visitor's browser; the server only serves static files.
Stack: Vite + React 19 + TypeScript, build-time prerendering (one static HTML file per URL, then hydrated), a small Express server for headers/compression/404s. Brand name is a placeholder: change it in src/config/site.ts and colours in src/styles/tokens.css.README 전문 보기 ↗A fast, privacy-friendly website of 77 everyday tools (image, PDF, text, developer) in 25 interface languages. Every tool runs in the visitor's browser; the server only serves static files.
Stack: Vite + React 19 + TypeScript, build-time prerendering (one static HTML file per URL, then hydrated), a small Express server for headers/compression/404s. Brand name is a placeholder: change it in src/config/site.ts and colours in src/styles/tokens.css.
| Command | What it does |
|---|---|
npm install | Install dependencies (Node 20+) |
npm run dev | Dev server with hot reload (no prerender). Copies the OCR files first. |
npm run check | Type check, lint, tests, then production build |
npm run build | Copies the OCR files, builds, and prerenders every route (about 2,300 pages including the language versions) into dist/ |
npm start | Serve dist/ on PORT (default 3000) |
npm test | Vitest (482 tests; server tests need a prior build) |
SITE_URL=https://your-domain.com npm run build (on Vercel, SITE_URL falls back to the project's production domain)npm start on any Node 20+ host (Hostinger Node.js hosting, a VPS, Render, Fly, etc.). Env vars: PORT, TRUST_PROXY=1 when behind a reverse proxy/CDN (so rate limiting sees real IPs), UPGRADE_INSECURE_REQUESTS=true once HTTPS is in place, and CONTACT_WEBHOOK_URL for the contact form (see Contact form).dist/), but you then lose the security headers and true 404 status, so the Node server is recommended.https://your-domain.com/sitemap.xml in Google Search Console.CONTACT_WEBHOOK_URL (see Contact form); until then the contact form says it is not connected.public/og-image.png (1200×630) for social previews; the build picks it up automatically.Every tool has a colour-coded illustration drawn as inline SVG (no image files, no icon library): src/tools/toolArt.ts is the single table that gives each of the 77 tools a base (sheet, photo, note or code window), a colour, a glyph and, for conversions, a format tag in the format's own colour (PDF red, JPG amber, PNG blue, WEBP purple ...). src/components/ui/ToolArt.tsx draws them and ToolIcon is the only component that shows them (cards, menus, search, related tools, page headers). tests/toolArt.test.ts checks that every tool is mapped, that no two tools look the same and that every colour keeps 3:1 contrast with the white glyph. The icon field in the tool data is kept for the line-icon fallback and tests.
src/tools/data/<category>.ts (slug, name, description, steps, FAQ, limits, related tools, impl key). Put it in one of the groups listed in src/tools/registry.ts; the mega menu, footer, category pages and search are generated from that data.src/tools/impl/<category>/ and register it in src/tools/impl/index.ts.npm run check. The registry tests verify metadata, related links and that every tool has an implementation. The page, URL, sitemap entry, breadcrumbs and structured data are generated automatically.The whole site can be shown in 25 languages: English, Urdu, Arabic, Persian, Spanish, French, German, Portuguese, Italian, Turkish, Chinese (Simplified), Japanese, Korean, Hindi, Indonesian, Bengali, Russian, Dutch, Vietnamese, Polish, Thai, Ukrainian, Romanian, Greek and Czech. English lives at the plain address and every other language under its code (/ur/tools, /zh/privacy), so a page always renders in one language for everyone. The address decides the language; the switcher goes to the same page in the other language and remembers the choice in localStorage (key kitwell-language). <html lang> and dir follow the page (Urdu, Arabic and Persian are right-to-left; Chinese is zh-CN). Every page is prerendered in every language (npm run build writes about 2,100 pages) with a self-referencing canonical, reciprocal hreflang links for all 25 languages plus x-default, localised title, description, Open Graph and structured data, and sitemap.xml entries with xhtml:link alternates. The Privacy Policy, Terms and Cookie information are translated in every language. The coverage checks live in scripts/i18n-audit.mjs and tests/i18n.test.ts / tests/i18nSeo.test.ts. The site has no cookie banner (it sets no cookies), so there is no consent interface to translate.
src/i18n/en/*.ts is the English catalog (one object per area; keys are area.name, plurals are key.one / key.other). Tool content is translated by tool slug in src/i18n/locales/<code>/tools.ts; the other files mirror the English ones. See docs/i18n-conventions.md (rules for developers) and docs/translation-brief.md (rules for translators).node scripts/i18n-audit.mjs --report [--list <code>] finds hardcoded text and unknown keys, lists missing keys per language and writes docs/translation-coverage.md. tests/i18n.test.ts fails when a locale has unknown keys, mismatched {placeholders}, untranslated copies, or a coverage flag in src/i18n/languages.ts that does not match reality. Plural forms follow each language's own CLDR categories.LANGUAGES (src/i18n/languages.ts), create src/i18n/locales/<code>/ and register it in src/i18n/loaders.ts. Each language is its own lazy chunk./contact has a working form (name, email, subject, optional tool/page, message). It posts to POST /api/contact, which validates the message, rate-limits (5 per 15 minutes per IP; CONTACT_RATE_LIMIT), drops honeypot submissions and forwards the message as JSON to the URL in CONTACT_WEBHOOK_URL (a Slack/Discord incoming webhook, Make/Zapier hook, Formspree-style endpoint or your own receiver). The JSON has name, email, topic, message, page, receivedAt, plus text and content (Slack and Discord formats). Nothing is stored on the server. The owner's email address is never shown on the site.
Two entry points share the same rules (server/contactCore.mjs): the Express server (server/contact.mjs) and Vercel serverless functions (api/contact.js, api/contact/status.js) for the static Vercel deployment, which has no Node server. On Vercel set CONTACT_WEBHOOK_URL (and optionally CONTACT_RATE_LIMIT) in the project's environment variables. The Vercel rate limiter is in memory per function instance, so it is best-effort there.
Without CONTACT_WEBHOOK_URL the page says the form is not connected and the endpoint answers 503; it never reports success for a message it did not deliver.
/about is a founder-led story (src/pages/About.tsx, page structure in src/pages/aboutContent.ts, text in the translation catalog (src/i18n/en/about.ts and one about.ts per language), styles in src/styles/about.css, photo component in src/components/about/AboutParts.tsx). It is translated into all 25 languages like every other page (Urdu, Arabic and Persian render right to left). The tool and language counts are read from the registry and the language list, never typed. The portrait lives in public/images/founder/ (ubaid-ullah.jpg, .webp and the 1200x630 social card ubaid-ullah-og.jpg). Looping effects (turning ring, glow, orbits, float, belief-block sweep) and the pointer tilt switch off for visitors who prefer reduced motion.
Eight tools were added to the PDF category (data in src/tools/data/pdfConvert.ts, interfaces in src/tools/impl/pdf/, engines in src/lib/). All run in the browser; nothing is uploaded and there is no server component.
| Tool | Engine |
|---|---|
| Scan to PDF | images to pages (scanFilter.ts: grayscale or adaptive black-and-white clean-up) |
| HTML to PDF | inert DOMParser reader (htmlDoc.ts); never fetches URLs, runs scripts or loads external resources |
| Word to PDF | DOCX reader (docx.ts, officeZip.ts) |
| PowerPoint to PDF | PPTX reader (pptxPdf.ts) |
| Excel to PDF | XLSX reader (xlsx.ts), saved values only |
| PDF to Markdown | pdf.js text positions with heading, list and paragraph heuristics (pdfMarkdown.ts) |
| Repair PDF | xref reconstruction and page-tree rebuild (pdfRepair.ts) |
| PDF to PDF/A | PDF/A-2b preparation (pdfA.ts, sRGB profile built in iccProfile.ts) |
PDFs are laid out by Kitwell's own layout engine (docPdf.ts) with Noto Sans (@fontsource/noto-sans, subset-embedded via @pdf-lib/fontkit): Latin, Latin Extended, Cyrillic, Greek, Vietnamese and Devanagari. Arabic, Hebrew, Thai and CJK text is not supported and shows as "?" with a count in the result notes. Output is not a pixel copy of the source: fonts, spacing, columns, headers/footers, charts and effects differ, and each tool says what was skipped. Legacy .doc/.ppt/.xls and password-protected files are rejected with a clear message. PDF to PDF/A prepares PDF/A-2b in two modes. Keep text and fonts adds the PDF/A identification, XMP metadata, an sRGB output intent and a file ID, and removes JavaScript, forbidden actions, attachments and annotation flags; it refuses (and lists why) when fonts are not embedded or the file uses CMYK or LZW. Turn pages into pictures renders each page (up to 200) and builds an image-only PDF/A. Kitwell itself has no PDF/A validator in the page, so the page says the result is not a certification. The output was checked once, outside the product, with veraPDF 1.30.3 (the open-source reference validator, Java) against the PDF/A-2b profile: keep mode, flatten mode, a PDF with JavaScript, a Launch action and NeedAppearances (fixed by the tool), and PDFs produced by the Word and PowerPoint converters all passed, while an ordinary PDF failed as expected. This is a spot check of those files, not a guarantee for every PDF. The tool also runs its own check (checkPdfA) on each result.
Three optional features need a service outside the browser. Each one stays hidden until it is configured, and none of them is used unless the visitor presses its button.
/share?id=... with a QR code. Files are deleted after SHARE_TTL_HOURS (default 24); SHARE_MAX_MB (default 100) limits the size; SHARE_DISABLED=true switches it off.
npm start): works out of the box and stores files on disk in SHARE_DIR (default: the system temp folder), see server/share.mjs and server/shareCore.mjs. Upload requests are rate limited (SHARE_RATE_LIMIT, default 20 per 10 minutes per IP).BLOB_READ_WRITE_TOKEN is set, and optionally set CRON_SECRET. The functions are in api/share/, files are uploaded straight from the browser with a short-lived token, and vercel.json runs /api/share/cleanup daily to delete expired files (links are also refused after expiry). Without the token the button does not appear.VITE_GOOGLE_CLIENT_ID and VITE_GOOGLE_API_KEY (and VITE_GOOGLE_APP_ID, the project number, which Google recommends) before building. Only the narrow drive.file scope is requested.files.content.write, add your domain to the Chooser/Saver domains and https://your-domain/oauth/dropbox.html as a redirect URI. Set VITE_DROPBOX_APP_KEY before building.These values are public identifiers (no client secret is used anywhere in the browser). The Node server widens its Content-Security-Policy and uses Cross-Origin-Opener-Policy: same-origin-allow-popups only when these variables are present. The Drive and Dropbox code paths follow the providers' documented browser flows (src/lib/cloud.ts) but could not be tested end to end without real credentials; try them once after configuring.
/blog has 48 guides written around the tools. Articles are English only on purpose: other languages show the English text, are marked noindex, point their canonical address at the English article, have no hreflang links and are left out of the sitemap (the blog index and its shared labels are translated).
content/blog/<slug>.md (format described at the top of scripts/build-blog.mjs). Run node scripts/build-blog.mjs and commit the generated src/blog/articles.ts and src/i18n/en/blogArticles.ts. Inside text, <tool_merge_pdf>…</tool_merge_pdf>, <post_slug>…</post_slug> and <all_pdf>…</all_pdf> become internal links.public/images/blog/<slug>.jpg (1200x630, used on the page, Open Graph and structured data) and <slug>-640.webp (cards). The current ones are drawn as SVG and rendered in a browser; tests/blog.test.ts fails when a file is missing.OCR PDF uses tesseract.js (Apache-2.0) with the English "best" LSTM model. Nothing is fetched from a CDN:
scripts/copy-ocr-assets.mjs (run by predev and prebuild) copies the worker, three WebAssembly engine variants and eng.traineddata.gz from node_modules to public/ocr/ (about 12 MB, git-ignored, generated). A visitor downloads only the worker (~110 KB), one engine (~3.9 MB) and the language data (~3 MB), and only when they use OCR.'wasm-unsafe-eval' in script-src. That permits compiling WebAssembly only; eval() and inline scripts remain blocked..traineddata.gz files in public/ocr/lang/ and an entry in src/lib/ocrEngine.ts.crypto.getRandomValues (rejection sampling, no modulo bias) and are never stored or sent.npm audit: 0 known vulnerabilities at time of writing.src/components/ui/AdSlot.tsx renders nothing until site.ads.enabled is set in src/config/site.ts, so there are no empty boxes now. Slots sit below the tool panel and mid-homepage, clearly separated from controls. Before enabling: add the ad script (the CSP in server/index.mjs must then allow Google's domains), update Privacy/Cookie pages, and add a Google-certified consent banner for EEA/UK visitors.
@ # $ *.