[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8858":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":16,"starSnapshotCount":16,"syncStatus":19,"lastSyncTime":37,"discoverSource":38},8858,"chronoframe","HoshinoSuzumi\u002Fchronoframe","HoshinoSuzumi","Self-hosted personal gallery application with online photo management and albums, supporting Live\u002FMotion Photos, EXIF parsing, geolocation recognition, and an explore map.","https:\u002F\u002Fchronoframe.bh8.ga\u002F",null,"Vue",1837,131,4,29,0,13,55,2,19.36,"MIT License",false,"main",true,[26,27,28,29,30,31,32,33],"albums","exif-extraction","geocoding","live-photo","motion-photo","photo-gallery","photo-sharing","webgl-viewer","2026-06-12 02:01:59","# ChronoFrame\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Fsocialify.git.ci\u002FHoshinoSuzumi\u002Fchronoframe\u002Fimage?custom_description=Self-hosted+personal+gallery+application.&description=1&font=KoHo&forks=0&issues=0&logo=https%3A%2F%2Fgithub.com%2FHoshinoSuzumi%2Fchronoframe%2Fraw%2Frefs%2Fheads%2Fmain%2Fpublic%2Ffavicon.svg&name=1&owner=1&pattern=Plus&pulls=0&stargazers=0&theme=Auto\" alt=\"Chronoframe\">\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FHoshinoSuzumi\u002Fchronoframe\u002Freleases\u002Flatest\">\n    \u003Cimg src=\"https:\u002F\u002Fbadgen.net\u002Fgithub\u002Frelease\u002FHoshinoSuzumi\u002Fchronoframe\u002Fstable?icon=docker&label=stable\" alt=\"Latest Release\">\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FHoshinoSuzumi\u002Fchronoframe\u002Freleases?q=beta&expanded=false\">\n    \u003Cimg src=\"https:\u002F\u002Fbadgen.net\u002Fgithub\u002Frelease\u002FHoshinoSuzumi\u002Fchronoframe?icon=docker&label=nightly\" alt=\"Latest Nightly Release\">\n  \u003C\u002Fa>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-green.svg\" alt=\"License\">\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FMM4ZK4Ed7s\">\n    \u003Cimg src=\"https:\u002F\u002Fdcbadge.limes.pink\u002Fapi\u002Fserver\u002Fhttps:\u002F\u002Fdiscord.gg\u002FMM4ZK4Ed7s\" alt=\"Discord Server\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fhellogithub.com\u002Frepository\u002FHoshinoSuzumi\u002Fchronoframe\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fapi.hellogithub.com\u002Fv1\u002Fwidgets\u002Frecommend.svg?rid=947d47ffe8404985908b266e187dec99&claim_uid=kLVoiAFPJaBtr1D&theme=neutral\" alt=\"Featured｜HelloGitHub\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fwww.producthunt.com\u002Fproducts\u002Fchronoframe?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-chronoframe\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fapi.producthunt.com\u002Fwidgets\u002Fembed-image\u002Fv1\u002Ffeatured.svg?post_id=1029556&theme=neutral&t=1761159404569\" alt=\"ChronoFrame - Self&#0045;hosted&#0032;photo&#0032;gallery&#0032;for&#0032;photographers&#0046; | Product Hunt\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" \u002F>\u003C\u002Fa>\n\u003C\u002Fp>\n\n**Languages:** English | [中文](README_zh.md)\n\nA smooth photo display and management application, supporting multiple image formats and large-size image rendering.\n\n[Live Demo: TimoYin's Mems](https:\u002F\u002Flens.bh8.ga)\n\n## ✨ Features\n\n### 🖼️ Powerful Photo Management\n\n- **Manage photos online** - Easily manage and browse photos via the web interface\n- **Explore map** - Browse photo locations on a map\n- **Smart EXIF parsing** - Automatically extracts metadata such as capture time, geolocation, and camera parameters\n- **Reverse geocoding** - Automatically identifies photo shooting locations\n- **Multi-format support** - Supports mainstream formats including JPEG, PNG, HEIC\u002FHEIF\n- **Smart thumbnails** - Efficient thumbnail generation using ThumbHash\n\n### 🔧 Modern Tech Stack\n\n- **Nuxt 4** - Built on the latest Nuxt framework with SSR\u002FSSG support\n- **TypeScript** - Full type safety\n- **TailwindCSS** - Modern CSS framework\n- **Drizzle ORM** - Type-safe database ORM\n\n### ☁️ Flexible Storage Solutions\n\n- **Multiple storage backends** - Supports S3-compatible storage, local filesystem\n- **CDN acceleration** - Configurable CDN URL for faster photo delivery\n\n## 🐳 Deployment\n\nWe recommend deploying with the prebuilt Docker image. [View the image on ghcr](https:\u002F\u002Fgithub.com\u002FHoshinoSuzumi\u002Fchronoframe\u002Fpkgs\u002Fcontainer\u002Fchronoframe)\n\nCreate a `.env` file and configure environment variables.\n\nBelow is a **minimal configuration** example. For complete configuration options, see [Configuration Guide](https:\u002F\u002Fchronoframe.bh8.ga\u002Fguide\u002Fconfiguration.html):\n\n```bash\n# Admin email (required)\nCFRAME_ADMIN_EMAIL=\n# Admin username (optional, default Chronoframe)\nCFRAME_ADMIN_NAME=\n# Admin password (optional, default CF1234@!)\nCFRAME_ADMIN_PASSWORD=\n\n# Site metadata (all optional)\nNUXT_PUBLIC_APP_TITLE=\nNUXT_PUBLIC_APP_SLOGAN=\nNUXT_PUBLIC_APP_AUTHOR=\nNUXT_PUBLIC_APP_AVATAR_URL=\n\n# Map provider (maplibre\u002Fmapbox)\nNUXT_PUBLIC_MAP_PROVIDER=maplibre\n# MapTiler access token for MapLibre\nNUXT_PUBLIC_MAP_MAPLIBRE_TOKEN=\n# Mapbox access token for Mapbox\nNUXT_PUBLIC_MAPBOX_ACCESS_TOKEN=\n\n# Mapbox unrestricted token (optional, reverse geocoding)\nNUXT_MAPBOX_ACCESS_TOKEN=\n\n# Storage provider (local, s3 or openlist)\nNUXT_STORAGE_PROVIDER=local\nNUXT_PROVIDER_LOCAL_PATH=\u002Fapp\u002Fdata\u002Fstorage\n\n# Session password (32‑char random string, required)\nNUXT_SESSION_PASSWORD=\n```\n\n### Pull Image\n\nUse the published image on GitHub Container Registry and Docker Hub. Choose the source that works best for your network:\n\n#### [GitHub Container Registry (GHCR)](https:\u002F\u002Fgithub.com\u002FHoshinoSuzumi\u002Fchronoframe\u002Fpkgs\u002Fcontainer\u002Fchronoframe)\n\n```bash\ndocker pull ghcr.io\u002Fhoshinosuzumi\u002Fchronoframe:latest\n```\n\n#### [Docker Hub](https:\u002F\u002Fhub.docker.com\u002Fr\u002Fhoshinosuzumi\u002Fchronoframe)\n\n```bash\ndocker pull hoshinosuzumi\u002Fchronoframe:latest\n```\n\n### Docker\n\nRun with customized environment variables:\n\n```bash\ndocker run -d --name chronoframe -p 3000:3000 -v $(pwd)\u002Fdata:\u002Fapp\u002Fdata --env-file .env ghcr.io\u002Fhoshinosuzumi\u002Fchronoframe:latest\n```\n\n### Docker Compose\n\nCreate docker-compose.yml:\n\n```yaml\nservices:\n  chronoframe:\n    image: ghcr.io\u002Fhoshinosuzumi\u002Fchronoframe:latest\n    container_name: chronoframe\n    restart: unless-stopped\n    ports:\n      - '3000:3000'\n    volumes:\n      - .\u002Fdata:\u002Fapp\u002Fdata\n    env_file:\n      - .env\n```\n\nStart:\n\n```bash\ndocker compose up -d\n```\n\n## 📖 User Guide\n\n> If `CFRAME_ADMIN_EMAIL` and `CFRAME_ADMIN_PASSWORD` are not set, the default admin account is:\n>\n> - Email: `admin@chronoframe.com`\n> - Password: `CF1234@!`\n\n### Logging into the Dashboard\n\n1. Click avatar to sign in with GitHub OAuth or use email\u002Fpassword login\n\n### Uploading Photos\n\n1. Go to the dashboard at \u002Fdashboard\n2. On the Photos page, select and upload images (supports batch & drag-and-drop)\n3. System will automatically parse EXIF data, generate thumbnails, and perform reverse geocoding\n\n## 📸 Screenshots\n\n![Gallery](.\u002Fdocs\u002Fimages\u002Fscreenshot1.png)\n![Photo Detail](.\u002Fdocs\u002Fimages\u002Fscreenshot2.png)\n![Map Explore](.\u002Fdocs\u002Fimages\u002Fscreenshot3.png)\n![Dashboard](.\u002Fdocs\u002Fimages\u002Fscreenshot4.png)\n\n## 🛠️ Development\n\n### Requirements\n\n- Node.js 18+\n- pnpm 9.0+\n\n### Install dependencies\n\n```bash\n# With pnpm (recommended)\npnpm install\n\n# Or with other package managers\nnpm install\nyarn install\n```\n\n### Configure environment variables\n\n```bash\ncp .env.example .env\n```\n\n### Initialize database\n\n```bash\n# 2. Generate migration files (optional)\npnpm db:generate\n\n# 3. Run database migrations\npnpm db:migrate\n```\n\n### Start development server\n\n```bash\npnpm dev\n```\n\nApp will start at http:\u002F\u002Flocalhost:3000.\n\n### Project Structure\n\n```\nchronoframe\u002F\n├── app\u002F                    # Nuxt app\n│   ├── components\u002F         # Components\n│   ├── pages\u002F              # Page routes\n│   ├── composables\u002F        # Composables\n│   └── stores\u002F             # Pinia stores\n├── packages\u002F\n│   └── webgl-image\u002F        # WebGL image viewer\n├── server\u002F\n│   ├── api\u002F                # API routes\n│   ├── database\u002F           # DB schema & migrations\n│   └── services\u002F           # Business logic services\n└── shared\u002F                 # Shared types & utils\n```\n\n### Build commands\n\n```bash\n# Development (with dependencies build)\npnpm dev\n\n# Build only dependencies\npnpm build:deps\n\n# Production build\npnpm build\n\n# Database operations\npnpm db:generate    # Generate migration files\npnpm db:migrate     # Run migrations\n\n# Preview production build\npnpm preview\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repo\n2. Create a feature branch (git checkout -b feature\u002Famazing-feature)\n3. Commit changes (git commit -m 'Add some amazing feature')\n4. Push to branch (git push origin feature\u002Famazing-feature)\n5. Open a Pull Request\n\n### Coding Guidelines\n\n- Use TypeScript for type safety\n- Follow ESLint and Prettier conventions\n- Update documentation accordingly\n\n## 📄 License\n\nThis project is licensed under the MIT License.\n\n## 👤 Author\n\n**Timothy Yin**\n\n- Email: master@uniiem.com\n- GitHub: @HoshinoSuzumi\n- Website: bh8.ga\n- Gallery: lens.bh8.ga\n\n## ❓ FAQ\n\n\u003Cdetails>\n  \u003Csummary>How is the admin user created?\u003C\u002Fsummary>\n  \u003Cp>\n    On first startup, an admin user is created based on \u003Ccode>CFRAME_ADMIN_EMAIL\u003C\u002Fcode>, \u003Ccode>CFRAME_ADMIN_NAME\u003C\u002Fcode>, and \u003Ccode>CFRAME_ADMIN_PASSWORD\u003C\u002Fcode>. The email must match your GitHub account email used for login.\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\u003Cdetails>\n  \u003Csummary>Which image formats are supported?\u003C\u002Fsummary>\n  \u003Cp>\n    Supported formats: JPEG, PNG, HEIC\u002FHEIF, MOV (for Live Photos).\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\u003Cdetails>\n  \u003Csummary>Why can’t I use GitHub\u002FLocal storage?\u003C\u002Fsummary>\n  \u003Cp>\n    Currently only S3-compatible storage is supported. GitHub and local storage support is planned.\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\u003Cdetails>\n  \u003Csummary>Why is a map service required and how to configure it?\u003C\u002Fsummary>\n  \u003Cp>\n    The map is used to browse photo locations and render mini-maps in photo details. Currently Mapbox is used. After registering, \u003Ca href=\"https:\u002F\u002Fconsole.mapbox.com\u002Faccount\u002Faccess-tokens\u002F\">get an access token\u003C\u002Fa> and set it to the \u003Ccode>MAPBOX_TOKEN\u003C\u002Fcode> variable.\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\u003Cdetails>\n  \u003Csummary>Why wasn’t my MOV file recognized as a Live Photo?\u003C\u002Fsummary>\n  \u003Cp>\n    Ensure the image (.heic) and video (.mov) share the same filename (e.g., \u003Ccode>IMG_1234.heic\u003C\u002Fcode> and \u003Ccode>IMG_1234.mov\u003C\u002Fcode>). Upload order does not matter. If not recognized, you can trigger pairing manually from the dashboard.\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\u003Cdetails>\n  \u003Csummary>How do I import existing photos from storage?\u003C\u002Fsummary>\n  \u003Cp>\n    Direct import of existing photos is not yet supported. A directory scanning import feature is planned.\n  \u003C\u002Fp>\n\u003C\u002Fdetails>\n\n## 🙏 Acknowledgements\n\nThis project was inspired by Afilmory, another excellent personal gallery project.\n\nThanks to the following open-source projects and libraries:\n\n- [Nuxt](https:\u002F\u002Fnuxt.com\u002F)\n- [TailwindCSS](https:\u002F\u002Ftailwindcss.com\u002F)\n- [Drizzle ORM](https:\u002F\u002Form.drizzle.team\u002F)\n\n## ⭐️ Star History\n\n\u003Ca href=\"https:\u002F\u002Fwww.star-history.com\u002F#HoshinoSuzumi\u002Fchronoframe&type=date&legend=top-left\">\n \u003Cpicture>\n   \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=HoshinoSuzumi\u002Fchronoframe&type=date&theme=dark&legend=top-left\" \u002F>\n   \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=HoshinoSuzumi\u002Fchronoframe&type=date&legend=top-left\" \u002F>\n   \u003Cimg alt=\"Star History Chart\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=HoshinoSuzumi\u002Fchronoframe&type=date&legend=top-left\" \u002F>\n \u003C\u002Fpicture>\n\u003C\u002Fa>\n","ChronoFrame 是一个自托管的个人图库应用，支持在线照片管理和相册创建。其核心功能包括Live\u002FMotion照片支持、EXIF元数据解析、地理位置识别以及探索地图。该应用采用Vue框架构建，并利用了Nuxt 4、TypeScript和TailwindCSS等现代技术栈来提供流畅的照片展示与管理体验。此外，它还支持多种图片格式及大尺寸图片渲染，并通过智能缩略图生成技术优化了用户体验。ChronoFrame适用于需要高效组织个人或团队数字照片资源的场景，特别是对于摄影爱好者来说，它能够很好地满足他们对照片存储、查看及分享的需求。","2026-06-11 03:20:04","top_language"]