Initial commit: hardened DeerFlow factory
Vendored deer-flow upstream (bytedance/deer-flow) plus prompt-injection hardening: - New deerflow.security package: content_delimiter, html_cleaner, sanitizer (8 layers — invisible chars, control chars, symbols, NFC, PUA, tag chars, horizontal whitespace collapse with newline/tab preservation, length cap) - New deerflow.community.searx package: web_search, web_fetch, image_search backed by a private SearX instance, every external string sanitized and wrapped in <<<EXTERNAL_UNTRUSTED_CONTENT>>> delimiters - All native community web providers (ddg_search, tavily, exa, firecrawl, jina_ai, infoquest, image_search) replaced with hard-fail stubs that raise NativeWebToolDisabledError at import time, so a misconfigured tool.use path fails loud rather than silently falling back to unsanitized output - Native client back-doors (jina_client.py, infoquest_client.py) stubbed too - Native-tool tests quarantined under tests/_disabled_native/ (collect_ignore_glob via local conftest.py) - Sanitizer Layer 7 fix: only collapse horizontal whitespace, preserve newlines and tabs so list/table structure survives - Hardened runtime config.yaml references only the searx-backed tools - Factory overlay (backend/) kept in sync with deer-flow tree as a reference / source See HARDENING.md for the full audit trail and verification steps.
23
deer-flow/frontend/.env.example
Normal file
@@ -0,0 +1,23 @@
|
||||
# Since the ".env" file is gitignored, you can use the ".env.example" file to
|
||||
# build a new ".env" file when you clone the repo. Keep this file up-to-date
|
||||
# when you add new variables to `.env`.
|
||||
|
||||
# This file will be committed to version control, so make sure not to have any
|
||||
# secrets in it. If you are cloning this repo, create a copy of this file named
|
||||
# ".env" and populate it with your secrets.
|
||||
|
||||
# When adding additional environment variables, the schema in "/src/env.js"
|
||||
# should be updated accordingly.
|
||||
|
||||
# Backend API URLs (optional)
|
||||
# Leave these commented out to use the default nginx proxy (recommended for `make dev`)
|
||||
# Only set these if you need to connect to backend services directly
|
||||
# NEXT_PUBLIC_BACKEND_BASE_URL="http://localhost:8001"
|
||||
# NEXT_PUBLIC_LANGGRAPH_BASE_URL="http://localhost:2024"
|
||||
|
||||
# LangGraph API base URL
|
||||
# Default: /api/langgraph (uses langgraph dev server via nginx)
|
||||
# Set to /api/langgraph-compat to use the experimental Gateway-backed runtime
|
||||
# Requires: SKIP_LANGGRAPH_SERVER=1 in serve.sh (optional, saves resources)
|
||||
# NEXT_PUBLIC_LANGGRAPH_BASE_URL=/api/langgraph-compat
|
||||
|
||||
46
deer-flow/frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# database
|
||||
/prisma/db.sqlite
|
||||
/prisma/db.sqlite-journal
|
||||
db.sqlite
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
next-env.d.ts
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
|
||||
.env
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
# idea files
|
||||
.idea
|
||||
2
deer-flow/frontend/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
||||
public-hoist-pattern[]=*eslint*
|
||||
public-hoist-pattern[]=*prettier*
|
||||
2
deer-flow/frontend/.prettierignore
Normal file
@@ -0,0 +1,2 @@
|
||||
pnpm-lock.yaml
|
||||
.omc/
|
||||
105
deer-flow/frontend/AGENTS.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Agents Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
DeerFlow is built on a sophisticated agent-based architecture using the [LangGraph SDK](https://github.com/langchain-ai/langgraph) to enable intelligent, stateful AI interactions. This document outlines the agent system architecture, patterns, and best practices for working with agents in the frontend application.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────┐
|
||||
│ Frontend (Next.js) │
|
||||
├────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
|
||||
│ │ UI Components│───▶│ Thread Hooks │───▶│ LangGraph│ │
|
||||
│ │ │ │ │ │ SDK │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌──────────────┐ │ │
|
||||
│ └───────────▶│ Thread State │◀──────────┘ │
|
||||
│ │ Management │ │
|
||||
│ └──────────────┘ │
|
||||
└────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────┐
|
||||
│ LangGraph Backend (lead_agent) │
|
||||
│ ┌────────────┐ ┌──────────┐ ┌───────────────────┐ │
|
||||
│ │Main Agent │─▶│Sub-Agents│─▶│ Tools & Skills │ │
|
||||
│ └────────────┘ └──────────┘ └───────────────────┘ │
|
||||
└────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router pages
|
||||
│ ├── api/ # API routes
|
||||
│ ├── workspace/ # Main workspace pages
|
||||
│ └── mock/ # Mock/demo pages
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # Reusable UI components
|
||||
│ ├── workspace/ # Workspace-specific components
|
||||
│ ├── landing/ # Landing page components
|
||||
│ └── ai-elements/ # AI-related UI elements
|
||||
├── core/ # Core business logic
|
||||
│ ├── api/ # API client & data fetching
|
||||
│ ├── artifacts/ # Artifact management
|
||||
│ ├── config/ # App configuration
|
||||
│ ├── i18n/ # Internationalization
|
||||
│ ├── mcp/ # MCP integration
|
||||
│ ├── messages/ # Message handling
|
||||
│ ├── models/ # Data models & types
|
||||
│ ├── settings/ # User settings
|
||||
│ ├── skills/ # Skills system
|
||||
│ ├── threads/ # Thread management
|
||||
│ ├── todos/ # Todo system
|
||||
│ └── utils/ # Utility functions
|
||||
├── hooks/ # Custom React hooks
|
||||
├── lib/ # Shared libraries & utilities
|
||||
├── server/ # Server-side code (Not available yet)
|
||||
│ └── better-auth/ # Authentication setup (Not available yet)
|
||||
└── styles/ # Global styles
|
||||
```
|
||||
|
||||
### Technology Stack
|
||||
|
||||
- **LangGraph SDK** (`@langchain/langgraph-sdk@1.5.3`) - Agent orchestration and streaming
|
||||
- **LangChain Core** (`@langchain/core@1.1.15`) - Fundamental AI building blocks
|
||||
- **TanStack Query** (`@tanstack/react-query@5.90.17`) - Server state management
|
||||
- **React Hooks** - Thread lifecycle and state management
|
||||
- **Shadcn UI** - UI components
|
||||
- **MagicUI** - Magic UI components
|
||||
- **React Bits** - React bits components
|
||||
|
||||
### Interaction Ownership
|
||||
|
||||
- `src/app/workspace/chats/[thread_id]/page.tsx` owns composer busy-state wiring.
|
||||
- `src/core/threads/hooks.ts` owns pre-submit upload state and thread submission.
|
||||
- `src/hooks/usePoseStream.ts` is a passive store selector; global WebSocket lifecycle stays in `App.tsx`.
|
||||
|
||||
## Resources
|
||||
|
||||
- [LangGraph Documentation](https://langchain-ai.github.io/langgraph/)
|
||||
- [LangChain Core Concepts](https://js.langchain.com/docs/concepts)
|
||||
- [TanStack Query Documentation](https://tanstack.com/query/latest)
|
||||
- [Next.js App Router](https://nextjs.org/docs/app)
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new agent features:
|
||||
|
||||
1. Follow the established project structure
|
||||
2. Add comprehensive TypeScript types
|
||||
3. Implement proper error handling
|
||||
4. Write tests for new functionality
|
||||
5. Update this documentation
|
||||
6. Follow the code style guide (ESLint + Prettier)
|
||||
|
||||
## License
|
||||
|
||||
This agent architecture is part of the DeerFlow project.
|
||||
90
deer-flow/frontend/CLAUDE.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
DeerFlow Frontend is a Next.js 16 web interface for an AI agent system. It communicates with a LangGraph-based backend to provide thread-based AI conversations with streaming responses, artifacts, and a skills/tools system.
|
||||
|
||||
**Stack**: Next.js 16, React 19, TypeScript 5.8, Tailwind CSS 4, pnpm 10.26.2
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
| ---------------- | ------------------------------------------------- |
|
||||
| `pnpm dev` | Dev server with Turbopack (http://localhost:3000) |
|
||||
| `pnpm build` | Production build |
|
||||
| `pnpm check` | Lint + type check (run before committing) |
|
||||
| `pnpm lint` | ESLint only |
|
||||
| `pnpm lint:fix` | ESLint with auto-fix |
|
||||
| `pnpm typecheck` | TypeScript type check (`tsc --noEmit`) |
|
||||
| `pnpm start` | Start production server |
|
||||
|
||||
No test framework is configured.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Frontend (Next.js) ──▶ LangGraph SDK ──▶ LangGraph Backend (lead_agent)
|
||||
├── Sub-Agents
|
||||
└── Tools & Skills
|
||||
```
|
||||
|
||||
The frontend is a stateful chat application. Users create **threads** (conversations), send messages, and receive streamed AI responses. The backend orchestrates agents that can produce **artifacts** (files/code) and **todos**.
|
||||
|
||||
### Source Layout (`src/`)
|
||||
|
||||
- **`app/`** — Next.js App Router. Routes: `/` (landing), `/workspace/chats/[thread_id]` (chat).
|
||||
- **`components/`** — React components split into:
|
||||
- `ui/` — Shadcn UI primitives (auto-generated, ESLint-ignored)
|
||||
- `ai-elements/` — Vercel AI SDK elements (auto-generated, ESLint-ignored)
|
||||
- `workspace/` — Chat page components (messages, artifacts, settings)
|
||||
- `landing/` — Landing page sections
|
||||
- **`core/`** — Business logic, the heart of the app:
|
||||
- `threads/` — Thread creation, streaming, state management (hooks + types)
|
||||
- `api/` — LangGraph client singleton
|
||||
- `artifacts/` — Artifact loading and caching
|
||||
- `i18n/` — Internationalization (en-US, zh-CN)
|
||||
- `settings/` — User preferences in localStorage
|
||||
- `memory/` — Persistent user memory system
|
||||
- `skills/` — Skills installation and management
|
||||
- `messages/` — Message processing and transformation
|
||||
- `mcp/` — Model Context Protocol integration
|
||||
- `models/` — TypeScript types and data models
|
||||
- **`hooks/`** — Shared React hooks
|
||||
- **`lib/`** — Utilities (`cn()` from clsx + tailwind-merge)
|
||||
- **`server/`** — Server-side code (better-auth, not yet active)
|
||||
- **`styles/`** — Global CSS with Tailwind v4 `@import` syntax and CSS variables for theming
|
||||
|
||||
### Data Flow
|
||||
|
||||
1. User input → thread hooks (`core/threads/hooks.ts`) → LangGraph SDK streaming
|
||||
2. Stream events update thread state (messages, artifacts, todos)
|
||||
3. TanStack Query manages server state; localStorage stores user settings
|
||||
4. Components subscribe to thread state and render updates
|
||||
|
||||
### Key Patterns
|
||||
|
||||
- **Server Components by default**, `"use client"` only for interactive components
|
||||
- **Thread hooks** (`useThreadStream`, `useSubmitThread`, `useThreads`) are the primary API interface
|
||||
- **LangGraph client** is a singleton obtained via `getAPIClient()` in `core/api/`
|
||||
- **Environment validation** uses `@t3-oss/env-nextjs` with Zod schemas (`src/env.js`). Skip with `SKIP_ENV_VALIDATION=1`
|
||||
|
||||
## Code Style
|
||||
|
||||
- **Imports**: Enforced ordering (builtin → external → internal → parent → sibling), alphabetized, newlines between groups. Use inline type imports: `import { type Foo }`.
|
||||
- **Unused variables**: Prefix with `_`.
|
||||
- **Class names**: Use `cn()` from `@/lib/utils` for conditional Tailwind classes.
|
||||
- **Path alias**: `@/*` maps to `src/*`.
|
||||
- **Components**: `ui/` and `ai-elements/` are generated from registries (Shadcn, MagicUI, React Bits, Vercel AI SDK) — don't manually edit these.
|
||||
|
||||
## Environment
|
||||
|
||||
Backend API URLs are optional; an nginx proxy is used by default:
|
||||
|
||||
```
|
||||
NEXT_PUBLIC_BACKEND_BASE_URL=http://localhost:8001
|
||||
NEXT_PUBLIC_LANGGRAPH_BASE_URL=http://localhost:2024
|
||||
```
|
||||
|
||||
Requires Node.js 22+ and pnpm 10.26.2+.
|
||||
50
deer-flow/frontend/Dockerfile
Normal file
@@ -0,0 +1,50 @@
|
||||
# Frontend Dockerfile
|
||||
# Supports two targets:
|
||||
# --target dev — install deps only, run `pnpm dev` at container start
|
||||
# --target prod — full build baked in, run `pnpm start` at container start (default if no --target is specified)
|
||||
|
||||
ARG PNPM_STORE_PATH=/root/.local/share/pnpm/store
|
||||
ARG NPM_REGISTRY
|
||||
|
||||
# ── Base: shared setup ────────────────────────────────────────────────────────
|
||||
FROM node:22-alpine AS base
|
||||
ARG PNPM_STORE_PATH
|
||||
ARG NPM_REGISTRY
|
||||
# Configure corepack registry before installing pnpm so the download itself
|
||||
# succeeds in restricted networks (COREPACK_NPM_REGISTRY controls where
|
||||
# corepack fetches package managers from).
|
||||
RUN if [ -n "${NPM_REGISTRY}" ]; then \
|
||||
export COREPACK_NPM_REGISTRY="${NPM_REGISTRY}"; \
|
||||
fi && \
|
||||
corepack enable && corepack install -g pnpm@10.26.2
|
||||
RUN pnpm config set store-dir ${PNPM_STORE_PATH}
|
||||
# Optionally override npm registry for restricted networks (e.g. NPM_REGISTRY=https://registry.npmmirror.com)
|
||||
RUN if [ -n "${NPM_REGISTRY}" ]; then pnpm config set registry "${NPM_REGISTRY}"; fi
|
||||
WORKDIR /app
|
||||
COPY frontend ./frontend
|
||||
|
||||
# ── Dev: install only, CMD is overridden by docker-compose ───────────────────
|
||||
FROM base AS dev
|
||||
RUN cd /app/frontend && pnpm install --frozen-lockfile
|
||||
EXPOSE 3000
|
||||
|
||||
# ── Builder: install + compile Next.js ───────────────────────────────────────
|
||||
FROM base AS builder
|
||||
RUN cd /app/frontend && pnpm install --frozen-lockfile
|
||||
# Skip env validation — runtime vars are injected by nginx/container
|
||||
RUN cd /app/frontend && SKIP_ENV_VALIDATION=1 pnpm build
|
||||
|
||||
# ── Prod: minimal runtime with pre-built output ───────────────────────────────
|
||||
FROM node:22-alpine AS prod
|
||||
ARG PNPM_STORE_PATH
|
||||
ARG NPM_REGISTRY
|
||||
RUN if [ -n "${NPM_REGISTRY}" ]; then \
|
||||
export COREPACK_NPM_REGISTRY="${NPM_REGISTRY}"; \
|
||||
fi && \
|
||||
corepack enable && corepack install -g pnpm@10.26.2
|
||||
RUN pnpm config set store-dir ${PNPM_STORE_PATH}
|
||||
RUN if [ -n "${NPM_REGISTRY}" ]; then pnpm config set registry "${NPM_REGISTRY}"; fi
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/frontend ./frontend
|
||||
EXPOSE 3000
|
||||
CMD ["sh", "-c", "cd /app/frontend && pnpm start"]
|
||||
14
deer-flow/frontend/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
install:
|
||||
pnpm install
|
||||
|
||||
build:
|
||||
pnpm build
|
||||
|
||||
dev:
|
||||
pnpm dev
|
||||
|
||||
lint:
|
||||
pnpm lint
|
||||
|
||||
format:
|
||||
pnpm format:write
|
||||
138
deer-flow/frontend/README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# DeerFlow Frontend
|
||||
|
||||
Like the original DeerFlow 1.0, we would love to give the community a minimalistic and easy-to-use web interface with a more modern and flexible architecture.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Framework**: [Next.js 16](https://nextjs.org/) with [App Router](https://nextjs.org/docs/app)
|
||||
- **UI**: [React 19](https://react.dev/), [Tailwind CSS 4](https://tailwindcss.com/), [Shadcn UI](https://ui.shadcn.com/), [MagicUI](https://magicui.design/) and [React Bits](https://reactbits.dev/)
|
||||
- **AI Integration**: [LangGraph SDK](https://www.npmjs.com/package/@langchain/langgraph-sdk) and [Vercel AI Elements](https://vercel.com/ai-sdk/ai-elements)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 22+
|
||||
- pnpm 10.26.2+
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Copy environment variables
|
||||
cp .env.example .env
|
||||
# Edit .env with your configuration
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
# Start development server
|
||||
pnpm dev
|
||||
|
||||
# The app will be available at http://localhost:3000
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
# Type check
|
||||
pnpm typecheck
|
||||
|
||||
# Check formatting
|
||||
pnpm format
|
||||
|
||||
# Apply formatting
|
||||
pnpm format:write
|
||||
|
||||
# Lint
|
||||
pnpm lint
|
||||
|
||||
# Build for production
|
||||
pnpm build
|
||||
|
||||
# Start production server
|
||||
pnpm start
|
||||
```
|
||||
|
||||
## Site Map
|
||||
|
||||
```
|
||||
├── / # Landing page
|
||||
├── /chats # Chat list
|
||||
├── /chats/new # New chat page
|
||||
└── /chats/[thread_id] # A specific chat page
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Key environment variables (see `.env.example` for full list):
|
||||
|
||||
```bash
|
||||
# Backend API URLs (optional, uses nginx proxy by default)
|
||||
NEXT_PUBLIC_BACKEND_BASE_URL="http://localhost:8001"
|
||||
# LangGraph API URLs (optional, uses nginx proxy by default)
|
||||
NEXT_PUBLIC_LANGGRAPH_BASE_URL="http://localhost:2024"
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router pages
|
||||
│ ├── api/ # API routes
|
||||
│ ├── workspace/ # Main workspace pages
|
||||
│ └── mock/ # Mock/demo pages
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # Reusable UI components
|
||||
│ ├── workspace/ # Workspace-specific components
|
||||
│ ├── landing/ # Landing page components
|
||||
│ └── ai-elements/ # AI-related UI elements
|
||||
├── core/ # Core business logic
|
||||
│ ├── api/ # API client & data fetching
|
||||
│ ├── artifacts/ # Artifact management
|
||||
│ ├── config/ # App configuration
|
||||
│ ├── i18n/ # Internationalization
|
||||
│ ├── mcp/ # MCP integration
|
||||
│ ├── messages/ # Message handling
|
||||
│ ├── models/ # Data models & types
|
||||
│ ├── settings/ # User settings
|
||||
│ ├── skills/ # Skills system
|
||||
│ ├── threads/ # Thread management
|
||||
│ ├── todos/ # Todo system
|
||||
│ └── utils/ # Utility functions
|
||||
├── hooks/ # Custom React hooks
|
||||
├── lib/ # Shared libraries & utilities
|
||||
├── server/ # Server-side code
|
||||
│ └── better-auth/ # Authentication setup and session helpers
|
||||
└── styles/ # Global styles
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
| Command | Description |
|
||||
| ------------------- | --------------------------------------- |
|
||||
| `pnpm dev` | Start development server with Turbopack |
|
||||
| `pnpm build` | Build for production |
|
||||
| `pnpm start` | Start production server |
|
||||
| `pnpm format` | Check formatting with Prettier |
|
||||
| `pnpm format:write` | Apply formatting with Prettier |
|
||||
| `pnpm lint` | Run ESLint |
|
||||
| `pnpm lint:fix` | Fix ESLint issues |
|
||||
| `pnpm typecheck` | Run TypeScript type checking |
|
||||
| `pnpm check` | Run both lint and typecheck |
|
||||
|
||||
## Development Notes
|
||||
|
||||
- Uses pnpm workspaces (see `packageManager` in package.json)
|
||||
- Turbopack enabled by default in development for faster builds
|
||||
- Environment validation can be skipped with `SKIP_ENV_VALIDATION=1` (useful for Docker)
|
||||
- Backend API URLs are optional; nginx proxy is used by default in development
|
||||
|
||||
## License
|
||||
|
||||
MIT License. See [LICENSE](../LICENSE) for details.
|
||||
26
deer-flow/frontend/components.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/styles/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"registries": {
|
||||
"@ai-elements": "https://registry.ai-sdk.dev/{name}.json",
|
||||
"@magicui": "https://magicui.design/r/{name}",
|
||||
"@react-bits": "https://reactbits.dev/r/{name}.json"
|
||||
}
|
||||
}
|
||||
95
deer-flow/frontend/eslint.config.js
Normal file
@@ -0,0 +1,95 @@
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: import.meta.dirname,
|
||||
});
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
ignores: [
|
||||
".next",
|
||||
"src/components/ui/**",
|
||||
"src/components/ai-elements/**",
|
||||
"*.js",
|
||||
],
|
||||
},
|
||||
...compat.extends("next/core-web-vitals"),
|
||||
{
|
||||
files: ["**/*.ts", "**/*.tsx"],
|
||||
extends: [
|
||||
...tseslint.configs.recommended,
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
...tseslint.configs.stylisticTypeChecked,
|
||||
],
|
||||
rules: {
|
||||
"@next/next/no-img-element": "off",
|
||||
"@typescript-eslint/array-type": "off",
|
||||
"@typescript-eslint/consistent-type-definitions": "off",
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"warn",
|
||||
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{ argsIgnorePattern: "^_" },
|
||||
],
|
||||
"@typescript-eslint/require-await": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/no-misused-promises": [
|
||||
"error",
|
||||
{ checksVoidReturn: { attributes: false } },
|
||||
],
|
||||
"@typescript-eslint/no-redundant-type-constituents": "off",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/no-unsafe-argument": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
distinctGroup: false,
|
||||
groups: [
|
||||
"builtin",
|
||||
"external",
|
||||
"internal",
|
||||
"parent",
|
||||
"sibling",
|
||||
"index",
|
||||
"object",
|
||||
],
|
||||
pathGroups: [
|
||||
{
|
||||
pattern: "@/**",
|
||||
group: "internal",
|
||||
},
|
||||
{
|
||||
pattern: "./**.css",
|
||||
group: "object",
|
||||
},
|
||||
{
|
||||
pattern: "**.md",
|
||||
group: "object",
|
||||
},
|
||||
],
|
||||
"newlines-between": "always",
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
linterOptions: {
|
||||
reportUnusedDisableDirectives: true,
|
||||
},
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
61
deer-flow/frontend/next.config.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
|
||||
* for Docker builds.
|
||||
*/
|
||||
import "./src/env.js";
|
||||
|
||||
function getInternalServiceURL(envKey, fallbackURL) {
|
||||
const configured = process.env[envKey]?.trim();
|
||||
return configured && configured.length > 0
|
||||
? configured.replace(/\/+$/, "")
|
||||
: fallbackURL;
|
||||
}
|
||||
import nextra from "nextra";
|
||||
|
||||
const withNextra = nextra({});
|
||||
|
||||
/** @type {import("next").NextConfig} */
|
||||
const config = {
|
||||
i18n: {
|
||||
locales: ["en", "zh"],
|
||||
defaultLocale: "en",
|
||||
},
|
||||
devIndicators: false,
|
||||
async rewrites() {
|
||||
const rewrites = [];
|
||||
const langgraphURL = getInternalServiceURL(
|
||||
"DEER_FLOW_INTERNAL_LANGGRAPH_BASE_URL",
|
||||
"http://127.0.0.1:2024",
|
||||
);
|
||||
const gatewayURL = getInternalServiceURL(
|
||||
"DEER_FLOW_INTERNAL_GATEWAY_BASE_URL",
|
||||
"http://127.0.0.1:8001",
|
||||
);
|
||||
|
||||
if (!process.env.NEXT_PUBLIC_LANGGRAPH_BASE_URL) {
|
||||
rewrites.push({
|
||||
source: "/api/langgraph",
|
||||
destination: langgraphURL,
|
||||
});
|
||||
rewrites.push({
|
||||
source: "/api/langgraph/:path*",
|
||||
destination: `${langgraphURL}/:path*`,
|
||||
});
|
||||
}
|
||||
|
||||
if (!process.env.NEXT_PUBLIC_BACKEND_BASE_URL) {
|
||||
rewrites.push({
|
||||
source: "/api/agents",
|
||||
destination: `${gatewayURL}/api/agents`,
|
||||
});
|
||||
rewrites.push({
|
||||
source: "/api/agents/:path*",
|
||||
destination: `${gatewayURL}/api/agents/:path*`,
|
||||
});
|
||||
}
|
||||
|
||||
return rewrites;
|
||||
},
|
||||
};
|
||||
|
||||
export default withNextra(config);
|
||||
114
deer-flow/frontend/package.json
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"name": "deer-flow-frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"demo:save": "node scripts/save-demo.js",
|
||||
"build": "next build",
|
||||
"check": "eslint . --ext .ts,.tsx && tsc --noEmit",
|
||||
"dev": "next dev --turbo",
|
||||
"format": "prettier --check .",
|
||||
"format:write": "prettier --write .",
|
||||
"lint": "eslint . --ext .ts,.tsx",
|
||||
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
||||
"preview": "next build && next start",
|
||||
"start": "next start",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "^6.3.1",
|
||||
"@codemirror/lang-html": "^6.4.11",
|
||||
"@codemirror/lang-javascript": "^6.2.4",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
"@codemirror/lang-markdown": "^6.5.0",
|
||||
"@codemirror/lang-python": "^6.2.1",
|
||||
"@codemirror/language-data": "^6.5.2",
|
||||
"@langchain/core": "^1.1.15",
|
||||
"@langchain/langgraph-sdk": "^1.5.3",
|
||||
"@radix-ui/react-avatar": "^1.1.11",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@radix-ui/react-progress": "^1.1.8",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-switch": "^1.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-toggle": "^1.1.10",
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@radix-ui/react-use-controllable-state": "^1.2.2",
|
||||
"@t3-oss/env-nextjs": "^0.12.0",
|
||||
"@tanstack/react-query": "^5.90.17",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@uiw/codemirror-theme-basic": "^4.25.4",
|
||||
"@uiw/codemirror-theme-monokai": "^4.25.4",
|
||||
"@uiw/react-codemirror": "^4.25.4",
|
||||
"@xyflow/react": "^12.10.0",
|
||||
"ai": "^6.0.33",
|
||||
"best-effort-json-parser": "^1.2.1",
|
||||
"better-auth": "^1.3",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"codemirror": "^6.0.2",
|
||||
"date-fns": "^4.1.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"embla-carousel-react": "^8.6.0",
|
||||
"gsap": "^3.13.0",
|
||||
"hast": "^1.0.0",
|
||||
"katex": "^0.16.28",
|
||||
"lucide-react": "^0.562.0",
|
||||
"motion": "^12.26.2",
|
||||
"nanoid": "^5.1.6",
|
||||
"next": "^16.1.7",
|
||||
"next-themes": "^0.4.6",
|
||||
"nextra": "^4.6.1",
|
||||
"nextra-theme-docs": "^4.6.1",
|
||||
"nuxt-og-image": "^5.1.13",
|
||||
"ogl": "^1.0.11",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-resizable-panels": "^4.4.1",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"shiki": "3.15.0",
|
||||
"sonner": "^2.0.7",
|
||||
"streamdown": "1.4.0",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"tokenlens": "^1.3.1",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"use-stick-to-bottom": "^1.1.1",
|
||||
"uuid": "^13.0.0",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@tailwindcss/postcss": "^4.0.15",
|
||||
"@types/gsap": "^3.0.0",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"eslint": "^9.23.0",
|
||||
"eslint-config-next": "^15.2.3",
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.0.15",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.27.0"
|
||||
},
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "7.40.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.26.2"
|
||||
}
|
||||
12042
deer-flow/frontend/pnpm-lock.yaml
generated
Normal file
5
deer-flow/frontend/pnpm-workspace.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
packages: []
|
||||
ignoredBuiltDependencies:
|
||||
- esbuild
|
||||
- sharp
|
||||
- unrs-resolver
|
||||
5
deer-flow/frontend/postcss.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
4
deer-flow/frontend/prettier.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
|
||||
export default {
|
||||
plugins: ["prettier-plugin-tailwindcss"],
|
||||
};
|
||||
|
After Width: | Height: | Size: 957 KiB |
@@ -0,0 +1,202 @@
|
||||
# Dr. Fei-Fei Li: Recent Podcast Appearances Timeline (Last 6 Months)
|
||||
|
||||
## Overview
|
||||
|
||||
Dr. Fei-Fei Li, often called the "Godmother of AI," has been actively appearing on major podcasts discussing the future of artificial intelligence, spatial intelligence, human-centered AI, and her work at World Labs. This timeline compiles key highlights from her recent podcast appearances from August 2025 to January 2026.
|
||||
|
||||
---
|
||||
|
||||
## Timeline of Recent Podcast Appearances
|
||||
|
||||
### January 15, 2025 - **Possible Podcast** (with Reid Hoffman and Aria Finger)
|
||||
|
||||
**Episode:** "Fei-Fei Li on spatial intelligence and human-centered AI"
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **Spatial Intelligence as Next Frontier:** Emphasized that spatial intelligence represents the next major evolution beyond large language models (LLMs)
|
||||
- **Human-Centered AI Philosophy:** Discussed the importance of building AI that amplifies human potential rather than replacing humans
|
||||
- **Regulatory Guardrails:** Addressed the need for thoughtful regulation and governance frameworks for AI development
|
||||
- **World Labs Mission:** Explained her current role as co-founder and CEO of World Labs, focusing on spatial intelligence technology
|
||||
- **ImageNet Legacy:** Reflected on how ImageNet revolutionized computer vision and sparked the deep learning revolution
|
||||
|
||||
**Notable Quote:** "Humans are capable of creating God-like technology so that we can improve our medieval institutions and raise above our paleolithic emotions."
|
||||
|
||||
---
|
||||
|
||||
### August 15, 2025 - **Firing Line (PBS)**
|
||||
|
||||
**Episode:** "Fei-Fei Li on ethical AI development"
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **Ethical AI Development:** Discussed the challenges and responsibilities in developing AI ethically
|
||||
- **Societal Impact:** Addressed how AI will transform various sectors including healthcare, education, and employment
|
||||
- **Policy Recommendations:** Provided insights on what policy frameworks are needed for responsible AI deployment
|
||||
- **Global Collaboration:** Emphasized the need for international cooperation on AI standards and safety
|
||||
|
||||
---
|
||||
|
||||
### November 16, 2025 - **Lenny's Podcast**
|
||||
|
||||
**Episode:** "The Godmother of AI on jobs, robots & why world models are next"
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **World Models Introduction:** Explained why world models and spatial intelligence represent the next frontier beyond LLMs
|
||||
- **AI Won't Replace Humans:** Argued that AI won't replace humans but will require us to take responsibility for ourselves
|
||||
- **Marble Applications:** Revealed surprising applications of World Labs' Marble product, from movie production to psychological research
|
||||
- **Robotics Challenges:** Discussed why robotics faces unique challenges compared with language models
|
||||
- **Historical Context:** Shared rarely told history of AI development, including that just nine years ago, calling yourself an AI company was "basically a death sentence"
|
||||
- **Participation for All:** Explained how anyone can participate in AI regardless of their role or background
|
||||
|
||||
**Key Discussion Points:**
|
||||
|
||||
1. How ImageNet helped spark the current AI explosion
|
||||
2. The "bitter lesson" in AI and robotics
|
||||
3. Applications of Marble in creative industries and therapy
|
||||
4. Human-centered AI initiatives at Stanford
|
||||
|
||||
---
|
||||
|
||||
### November 25, 2025 - **Masters of Scale Summit**
|
||||
|
||||
**Episode:** "The 'Godmother of AI' on the next phase of AI" (with Reid Hoffman)
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **Fearless Approach:** Discussed why scientists and entrepreneurs need to be fearless in the face of an uncertain AI future
|
||||
- **Spatial Intelligence & World Modeling:** Detailed the next phase of AI focusing on spatial understanding
|
||||
- **Trust Building:** Explained how leaders should build societal trust in AI products and companies
|
||||
- **Human Agency:** Emphasized that trust cannot be outsourced to machines and must remain fundamentally human
|
||||
- **Entrepreneurial Responsibility:** Argued that entrepreneurs should care about trust from day one of AI development
|
||||
|
||||
**Chapter Topics Covered:**
|
||||
|
||||
- The next phase of AI: spatial intelligence & world modeling
|
||||
- What spatial intelligence has done for humans
|
||||
- Whether AI is over-hyped
|
||||
- How to build society trust in AI
|
||||
- Why we need to be "fearless" with AI
|
||||
|
||||
---
|
||||
|
||||
### December 9, 2025 - **The Tim Ferriss Show** (#839)
|
||||
|
||||
**Episode:** "Dr. Fei-Fei Li, The Godmother of AI — Asking Audacious Questions, Civilizational Technology, and Finding Your North Star"
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **Civilizational Technology:** Defined AI as a "civilizational technology" that will have profound economic, social, cultural, and political impacts
|
||||
- **Personal Journey:** Shared her immigrant story from Chengdu to New Jersey, and her family's seven years running a dry cleaning shop while she attended Princeton
|
||||
- **ImageNet Creation:** Detailed the creation of ImageNet and how it birthed modern AI, including innovative use of Amazon Mechanical Turk for data labeling
|
||||
- **Spatial Intelligence Vision:** Explained why she founded World Labs to focus on spatial intelligence as the next frontier
|
||||
- **Educational Philosophy:** Proposed rethinking evaluation by showing students AI's "B-minus" work and challenging them to beat it
|
||||
- **Human-Centered Focus:** Emphasized that "people are at the heart of everything" in AI development
|
||||
|
||||
**Notable Quotes:**
|
||||
|
||||
- "Really, at the end of the day, people are at the heart of everything. People made AI, people will be using AI, people will be impacted by AI, and people should have a say in AI."
|
||||
- "AI is absolutely a civilizational technology... it'll have—or [is] already having—a profound impact in the economic, social, cultural, political, downstream effects of our society."
|
||||
- "What is your North Star?"
|
||||
|
||||
**Key Topics Discussed:**
|
||||
|
||||
- From fighter jets to physics to asking "What is intelligence?"
|
||||
- The epiphany everyone missed: Big data as the hidden hypothesis
|
||||
- Against the single-genius myth: Science as non-linear lineage
|
||||
- Quality control puzzles in AI training data
|
||||
- Medieval French towns on a budget: How World Labs serves high school theater
|
||||
- Flight simulators for robots and strawberry field therapy for OCD
|
||||
|
||||
---
|
||||
|
||||
### June 16, 2025 - **Y Combinator Startup Podcast**
|
||||
|
||||
**Episode:** "Fei-Fei Li - Spatial Intelligence is the Next Frontier in AI"
|
||||
|
||||
**Key Highlights:**
|
||||
|
||||
- **Startup Perspective:** Provided insights for AI startups on navigating the current landscape
|
||||
- **Technical Deep Dive:** Offered detailed explanations of spatial intelligence technologies
|
||||
- **Entrepreneurial Advice:** Shared lessons from transitioning from academia to entrepreneurship
|
||||
- **Market Opportunities:** Identified emerging opportunities in spatial AI applications
|
||||
|
||||
---
|
||||
|
||||
## Common Themes Across Recent Appearances
|
||||
|
||||
### 1. **Spatial Intelligence as the Next Frontier**
|
||||
|
||||
- Repeated emphasis that spatial intelligence represents the next major evolution beyond language models
|
||||
- World Labs' focus on creating AI that understands and interacts with the physical world
|
||||
- Applications ranging from robotics and autonomous systems to creative industries and therapy
|
||||
|
||||
### 2. **Human-Centered AI Philosophy**
|
||||
|
||||
- Consistent message that AI should augment rather than replace human capabilities
|
||||
- Emphasis on maintaining human agency and responsibility in AI systems
|
||||
- Focus on building trust and ethical frameworks
|
||||
|
||||
### 3. **Educational Transformation**
|
||||
|
||||
- Advocacy for integrating AI into education to enhance learning
|
||||
- Proposal to use AI as a benchmark for student improvement
|
||||
- Emphasis on making AI accessible to people from all backgrounds
|
||||
|
||||
### 4. **Historical Perspective**
|
||||
|
||||
- Frequent references to ImageNet's role in sparking the deep learning revolution
|
||||
- Context about how rapidly the AI landscape has changed
|
||||
- Emphasis on collaborative, non-linear progress in scientific advancement
|
||||
|
||||
### 5. **Entrepreneurial Vision**
|
||||
|
||||
- Insights on building AI companies in the current environment
|
||||
- Balance between technological innovation and responsible development
|
||||
- Focus on practical applications that solve real-world problems
|
||||
|
||||
---
|
||||
|
||||
## Key Insights and Predictions
|
||||
|
||||
### **Near-Term Developments (1-3 years):**
|
||||
|
||||
- Rapid advancement in spatial intelligence and world modeling technologies
|
||||
- Increased integration of AI in education and creative industries
|
||||
- Growing focus on AI ethics and governance frameworks
|
||||
- Expansion of practical applications in healthcare, therapy, and accessibility
|
||||
|
||||
### **Medium-Term Vision (3-5 years):**
|
||||
|
||||
- More sophisticated human-AI collaboration systems
|
||||
- Breakthroughs in robotics enabled by spatial intelligence
|
||||
- Transformation of how we teach and learn with AI assistance
|
||||
- Development of new industries centered around spatial AI
|
||||
|
||||
### **Long-Term Philosophy:**
|
||||
|
||||
- AI as a "civilizational technology" that requires thoughtful stewardship
|
||||
- Emphasis on maintaining human values and agency in technological progress
|
||||
- Vision of technology that helps humanity "raise above our paleolithic emotions"
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
Dr. Fei-Fei Li's recent podcast appearances reveal a consistent vision: AI should be developed as a human-centered technology that enhances our capabilities rather than replacing them. Her focus has shifted from the foundational work of ImageNet to the next frontier of spatial intelligence through World Labs. Across all conversations, she emphasizes the importance of ethics, education, and maintaining human agency in the age of artificial intelligence.
|
||||
|
||||
The timeline shows her evolving role from academic researcher to entrepreneur while maintaining her core philosophy that technology should serve humanity's best interests. Her message remains one of cautious optimism, emphasizing both the tremendous potential and significant responsibilities of developing transformative AI technologies.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
1. The Tim Ferriss Show (December 9, 2025)
|
||||
2. Lenny's Podcast (November 16, 2025)
|
||||
3. Masters of Scale Summit (November 25, 2025)
|
||||
4. Possible Podcast (January 15, 2025)
|
||||
5. Firing Line, PBS (August 15, 2025)
|
||||
6. Y Combinator Startup Podcast (June 16, 2025)
|
||||
|
||||
_Compiled on January 25, 2026_
|
||||
|
After Width: | Height: | Size: 699 KiB |
@@ -0,0 +1,4 @@
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>"
|
||||
/>
|
||||
@@ -0,0 +1,385 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>江苏城市足球联赛2025赛季 | 苏超联赛第一季</title>
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
|
||||
/>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800;900&family=Oswald:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 加载动画 -->
|
||||
<div class="loader">
|
||||
<div class="loader-content">
|
||||
<div class="football"></div>
|
||||
<div class="loader-text">加载中...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar">
|
||||
<div class="container">
|
||||
<div class="nav-brand">
|
||||
<div class="logo">
|
||||
<div class="logo-ball"></div>
|
||||
<span class="logo-text">苏超联赛</span>
|
||||
</div>
|
||||
<div class="league-name">江苏城市足球联赛2025赛季</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-menu">
|
||||
<a href="#home" class="nav-link active">首页</a>
|
||||
<a href="#teams" class="nav-link">球队</a>
|
||||
<a href="#fixtures" class="nav-link">赛程</a>
|
||||
<a href="#standings" class="nav-link">积分榜</a>
|
||||
<a href="#stats" class="nav-link">数据</a>
|
||||
<a href="#news" class="nav-link">新闻</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-actions">
|
||||
<button class="btn-theme-toggle">
|
||||
<i class="fas fa-moon"></i>
|
||||
</button>
|
||||
<button class="btn-menu-toggle">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main>
|
||||
<!-- 英雄区域 -->
|
||||
<section id="home" class="hero">
|
||||
<div class="hero-background">
|
||||
<div class="hero-gradient"></div>
|
||||
<div class="hero-pattern"></div>
|
||||
<div class="hero-ball-animation"></div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="hero-content">
|
||||
<div class="hero-badge">
|
||||
<span class="badge-season">2025赛季</span>
|
||||
<span class="badge-league">苏超联赛第一季</span>
|
||||
</div>
|
||||
|
||||
<h1 class="hero-title">
|
||||
<span class="title-line">江苏城市</span>
|
||||
<span class="title-line highlight">足球联赛</span>
|
||||
</h1>
|
||||
|
||||
<p class="hero-subtitle">
|
||||
江苏省首个城市间职业足球联赛,汇集12支精英球队,点燃2025赛季战火!
|
||||
</p>
|
||||
|
||||
<div class="hero-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">12</div>
|
||||
<div class="stat-label">参赛球队</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">132</div>
|
||||
<div class="stat-label">场比赛</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">26</div>
|
||||
<div class="stat-label">比赛周</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">1</div>
|
||||
<div class="stat-label">冠军荣耀</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-actions">
|
||||
<a href="#fixtures" class="btn btn-primary">
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
查看赛程
|
||||
</a>
|
||||
<a href="#standings" class="btn btn-secondary">
|
||||
<i class="fas fa-trophy"></i>
|
||||
积分榜
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-visual">
|
||||
<div class="stadium-visual">
|
||||
<div class="stadium-field"></div>
|
||||
<div class="stadium-stands"></div>
|
||||
<div class="stadium-players">
|
||||
<div class="player player-1"></div>
|
||||
<div class="player player-2"></div>
|
||||
<div class="player player-3"></div>
|
||||
</div>
|
||||
<div class="stadium-ball"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-scroll">
|
||||
<div class="scroll-indicator">
|
||||
<div class="scroll-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 下一场比赛 -->
|
||||
<section class="next-match">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">下一场比赛</h2>
|
||||
<div class="section-subtitle">即将开始的精彩对决</div>
|
||||
</div>
|
||||
|
||||
<div class="match-card">
|
||||
<div class="match-date">
|
||||
<div class="match-day">周六</div>
|
||||
<div class="match-date-number">25</div>
|
||||
<div class="match-month">一月</div>
|
||||
<div class="match-time">19:30</div>
|
||||
</div>
|
||||
|
||||
<div class="match-teams">
|
||||
<div class="team team-home">
|
||||
<div class="team-logo logo-nanjing"></div>
|
||||
<div class="team-name">南京城联</div>
|
||||
<div class="team-record">8胜 3平 2负</div>
|
||||
</div>
|
||||
|
||||
<div class="match-vs">
|
||||
<div class="vs-text">VS</div>
|
||||
<div class="match-info">
|
||||
<div class="match-venue">南京奥体中心</div>
|
||||
<div class="match-round">第12轮</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="team team-away">
|
||||
<div class="team-logo logo-suzhou"></div>
|
||||
<div class="team-name">苏州雄狮</div>
|
||||
<div class="team-record">7胜 4平 2负</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="match-actions">
|
||||
<button class="btn btn-outline">
|
||||
<i class="fas fa-bell"></i>
|
||||
设置提醒
|
||||
</button>
|
||||
<button class="btn btn-primary">
|
||||
<i class="fas fa-ticket-alt"></i>
|
||||
购票
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 球队展示 -->
|
||||
<section id="teams" class="teams-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">参赛球队</h2>
|
||||
<div class="section-subtitle">12支城市代表队的荣耀之战</div>
|
||||
</div>
|
||||
|
||||
<div class="teams-grid">
|
||||
<!-- 球队卡片将通过JS动态生成 -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 积分榜 -->
|
||||
<section id="standings" class="standings-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">积分榜</h2>
|
||||
<div class="section-subtitle">2025赛季实时排名</div>
|
||||
</div>
|
||||
|
||||
<div class="standings-container">
|
||||
<div class="standings-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>排名</th>
|
||||
<th>球队</th>
|
||||
<th>场次</th>
|
||||
<th>胜</th>
|
||||
<th>平</th>
|
||||
<th>负</th>
|
||||
<th>进球</th>
|
||||
<th>失球</th>
|
||||
<th>净胜球</th>
|
||||
<th>积分</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- 积分榜数据将通过JS动态生成 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 赛程表 -->
|
||||
<section id="fixtures" class="fixtures-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">赛程表</h2>
|
||||
<div class="section-subtitle">2025赛季完整赛程</div>
|
||||
</div>
|
||||
|
||||
<div class="fixtures-tabs">
|
||||
<div class="tabs">
|
||||
<button class="tab active" data-round="all">全部赛程</button>
|
||||
<button class="tab" data-round="next">即将比赛</button>
|
||||
<button class="tab" data-round="recent">最近赛果</button>
|
||||
</div>
|
||||
|
||||
<div class="fixtures-list">
|
||||
<!-- 赛程数据将通过JS动态生成 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 数据统计 -->
|
||||
<section id="stats" class="stats-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">数据统计</h2>
|
||||
<div class="section-subtitle">球员与球队数据排行榜</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-tabs">
|
||||
<div class="stats-tab-nav">
|
||||
<button class="stats-tab active" data-tab="scorers">
|
||||
射手榜
|
||||
</button>
|
||||
<button class="stats-tab" data-tab="assists">助攻榜</button>
|
||||
<button class="stats-tab" data-tab="teams">球队数据</button>
|
||||
</div>
|
||||
|
||||
<div class="stats-content">
|
||||
<div class="stats-tab-content active" id="scorers">
|
||||
<!-- 射手榜数据 -->
|
||||
</div>
|
||||
<div class="stats-tab-content" id="assists">
|
||||
<!-- 助攻榜数据 -->
|
||||
</div>
|
||||
<div class="stats-tab-content" id="teams">
|
||||
<!-- 球队数据 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 新闻动态 -->
|
||||
<section id="news" class="news-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">新闻动态</h2>
|
||||
<div class="section-subtitle">联赛最新资讯</div>
|
||||
</div>
|
||||
|
||||
<div class="news-grid">
|
||||
<!-- 新闻卡片将通过JS动态生成 -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 底部 -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-content">
|
||||
<div class="footer-brand">
|
||||
<div class="logo">
|
||||
<div class="logo-ball"></div>
|
||||
<span class="logo-text">苏超联赛</span>
|
||||
</div>
|
||||
<div class="footer-description">
|
||||
江苏城市足球联赛2025赛季官方网站
|
||||
</div>
|
||||
<div class="footer-social">
|
||||
<a href="#" class="social-link"><i class="fab fa-weibo"></i></a>
|
||||
<a href="#" class="social-link"
|
||||
><i class="fab fa-weixin"></i
|
||||
></a>
|
||||
<a href="#" class="social-link"
|
||||
><i class="fab fa-douyin"></i
|
||||
></a>
|
||||
<a href="#" class="social-link"
|
||||
><i class="fab fa-bilibili"></i
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-links">
|
||||
<div class="footer-column">
|
||||
<h3 class="footer-title">联赛信息</h3>
|
||||
<a href="#" class="footer-link">关于联赛</a>
|
||||
<a href="#" class="footer-link">联赛章程</a>
|
||||
<a href="#" class="footer-link">组织机构</a>
|
||||
<a href="#" class="footer-link">合作伙伴</a>
|
||||
</div>
|
||||
|
||||
<div class="footer-column">
|
||||
<h3 class="footer-title">球迷服务</h3>
|
||||
<a href="#" class="footer-link">票务信息</a>
|
||||
<a href="#" class="footer-link">球迷社区</a>
|
||||
<a href="#" class="footer-link">官方商店</a>
|
||||
<a href="#" class="footer-link">联系我们</a>
|
||||
</div>
|
||||
|
||||
<div class="footer-column">
|
||||
<h3 class="footer-title">媒体中心</h3>
|
||||
<a href="#" class="footer-link">新闻发布</a>
|
||||
<a href="#" class="footer-link">媒体资料</a>
|
||||
<a href="#" class="footer-link">采访申请</a>
|
||||
<a href="#" class="footer-link">摄影图库</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<div class="copyright">
|
||||
© 2025 江苏城市足球联赛. 保留所有权利.
|
||||
</div>
|
||||
<div class="footer-legal">
|
||||
<a href="#" class="legal-link">隐私政策</a>
|
||||
<a href="#" class="legal-link">使用条款</a>
|
||||
<a href="#" class="legal-link">Cookie政策</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<!-- JavaScript文件 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
|
||||
<script src="js/data.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,808 @@
|
||||
// 江苏城市足球联赛2025赛季 - 数据文件
|
||||
|
||||
const leagueData = {
|
||||
// 联赛信息
|
||||
leagueInfo: {
|
||||
name: "江苏城市足球联赛",
|
||||
season: "2025赛季",
|
||||
alias: "苏超联赛第一季",
|
||||
teamsCount: 12,
|
||||
totalMatches: 132,
|
||||
weeks: 26,
|
||||
startDate: "2025-03-01",
|
||||
endDate: "2025-10-31",
|
||||
},
|
||||
|
||||
// 参赛球队
|
||||
teams: [
|
||||
{
|
||||
id: 1,
|
||||
name: "南京城联",
|
||||
city: "南京",
|
||||
shortName: "NJL",
|
||||
colors: ["#dc2626", "#ef4444"],
|
||||
founded: 2020,
|
||||
stadium: "南京奥体中心",
|
||||
capacity: 62000,
|
||||
manager: "张伟",
|
||||
captain: "李明",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "苏州雄狮",
|
||||
city: "苏州",
|
||||
shortName: "SZS",
|
||||
colors: ["#059669", "#10b981"],
|
||||
founded: 2019,
|
||||
stadium: "苏州奥林匹克体育中心",
|
||||
capacity: 45000,
|
||||
manager: "王强",
|
||||
captain: "陈浩",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "无锡太湖",
|
||||
city: "无锡",
|
||||
shortName: "WXT",
|
||||
colors: ["#3b82f6", "#60a5fa"],
|
||||
founded: 2021,
|
||||
stadium: "无锡体育中心",
|
||||
capacity: 32000,
|
||||
manager: "赵刚",
|
||||
captain: "刘洋",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "常州龙城",
|
||||
city: "常州",
|
||||
shortName: "CZL",
|
||||
colors: ["#7c3aed", "#8b5cf6"],
|
||||
founded: 2022,
|
||||
stadium: "常州奥林匹克体育中心",
|
||||
capacity: 38000,
|
||||
manager: "孙磊",
|
||||
captain: "周涛",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "镇江金山",
|
||||
city: "镇江",
|
||||
shortName: "ZJJ",
|
||||
colors: ["#f59e0b", "#fbbf24"],
|
||||
founded: 2020,
|
||||
stadium: "镇江体育会展中心",
|
||||
capacity: 28000,
|
||||
manager: "吴斌",
|
||||
captain: "郑军",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "扬州运河",
|
||||
city: "扬州",
|
||||
shortName: "YZY",
|
||||
colors: ["#ec4899", "#f472b6"],
|
||||
founded: 2021,
|
||||
stadium: "扬州体育公园",
|
||||
capacity: 35000,
|
||||
manager: "钱勇",
|
||||
captain: "王磊",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "南通江海",
|
||||
city: "南通",
|
||||
shortName: "NTJ",
|
||||
colors: ["#0ea5e9", "#38bdf8"],
|
||||
founded: 2022,
|
||||
stadium: "南通体育会展中心",
|
||||
capacity: 32000,
|
||||
manager: "冯超",
|
||||
captain: "张勇",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "徐州楚汉",
|
||||
city: "徐州",
|
||||
shortName: "XZC",
|
||||
colors: ["#84cc16", "#a3e635"],
|
||||
founded: 2019,
|
||||
stadium: "徐州奥体中心",
|
||||
capacity: 42000,
|
||||
manager: "陈明",
|
||||
captain: "李强",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "淮安运河",
|
||||
city: "淮安",
|
||||
shortName: "HAY",
|
||||
colors: ["#f97316", "#fb923c"],
|
||||
founded: 2021,
|
||||
stadium: "淮安体育中心",
|
||||
capacity: 30000,
|
||||
manager: "周伟",
|
||||
captain: "吴刚",
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "盐城黄海",
|
||||
city: "盐城",
|
||||
shortName: "YCH",
|
||||
colors: ["#06b6d4", "#22d3ee"],
|
||||
founded: 2020,
|
||||
stadium: "盐城体育中心",
|
||||
capacity: 32000,
|
||||
manager: "郑涛",
|
||||
captain: "孙明",
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: "泰州凤城",
|
||||
city: "泰州",
|
||||
shortName: "TZF",
|
||||
colors: ["#8b5cf6", "#a78bfa"],
|
||||
founded: 2022,
|
||||
stadium: "泰州体育公园",
|
||||
capacity: 28000,
|
||||
manager: "王刚",
|
||||
captain: "陈涛",
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: "宿迁西楚",
|
||||
city: "宿迁",
|
||||
shortName: "SQC",
|
||||
colors: ["#10b981", "#34d399"],
|
||||
founded: 2021,
|
||||
stadium: "宿迁体育中心",
|
||||
capacity: 26000,
|
||||
manager: "李伟",
|
||||
captain: "张刚",
|
||||
},
|
||||
],
|
||||
|
||||
// 积分榜数据
|
||||
standings: [
|
||||
{
|
||||
rank: 1,
|
||||
teamId: 1,
|
||||
played: 13,
|
||||
won: 8,
|
||||
drawn: 3,
|
||||
lost: 2,
|
||||
goalsFor: 24,
|
||||
goalsAgainst: 12,
|
||||
goalDifference: 12,
|
||||
points: 27,
|
||||
},
|
||||
{
|
||||
rank: 2,
|
||||
teamId: 2,
|
||||
played: 13,
|
||||
won: 7,
|
||||
drawn: 4,
|
||||
lost: 2,
|
||||
goalsFor: 22,
|
||||
goalsAgainst: 14,
|
||||
goalDifference: 8,
|
||||
points: 25,
|
||||
},
|
||||
{
|
||||
rank: 3,
|
||||
teamId: 8,
|
||||
played: 13,
|
||||
won: 7,
|
||||
drawn: 3,
|
||||
lost: 3,
|
||||
goalsFor: 20,
|
||||
goalsAgainst: 15,
|
||||
goalDifference: 5,
|
||||
points: 24,
|
||||
},
|
||||
{
|
||||
rank: 4,
|
||||
teamId: 3,
|
||||
played: 13,
|
||||
won: 6,
|
||||
drawn: 4,
|
||||
lost: 3,
|
||||
goalsFor: 18,
|
||||
goalsAgainst: 14,
|
||||
goalDifference: 4,
|
||||
points: 22,
|
||||
},
|
||||
{
|
||||
rank: 5,
|
||||
teamId: 4,
|
||||
played: 13,
|
||||
won: 6,
|
||||
drawn: 3,
|
||||
lost: 4,
|
||||
goalsFor: 19,
|
||||
goalsAgainst: 16,
|
||||
goalDifference: 3,
|
||||
points: 21,
|
||||
},
|
||||
{
|
||||
rank: 6,
|
||||
teamId: 6,
|
||||
played: 13,
|
||||
won: 5,
|
||||
drawn: 5,
|
||||
lost: 3,
|
||||
goalsFor: 17,
|
||||
goalsAgainst: 15,
|
||||
goalDifference: 2,
|
||||
points: 20,
|
||||
},
|
||||
{
|
||||
rank: 7,
|
||||
teamId: 5,
|
||||
played: 13,
|
||||
won: 5,
|
||||
drawn: 4,
|
||||
lost: 4,
|
||||
goalsFor: 16,
|
||||
goalsAgainst: 15,
|
||||
goalDifference: 1,
|
||||
points: 19,
|
||||
},
|
||||
{
|
||||
rank: 8,
|
||||
teamId: 7,
|
||||
played: 13,
|
||||
won: 4,
|
||||
drawn: 5,
|
||||
lost: 4,
|
||||
goalsFor: 15,
|
||||
goalsAgainst: 16,
|
||||
goalDifference: -1,
|
||||
points: 17,
|
||||
},
|
||||
{
|
||||
rank: 9,
|
||||
teamId: 10,
|
||||
played: 13,
|
||||
won: 4,
|
||||
drawn: 4,
|
||||
lost: 5,
|
||||
goalsFor: 14,
|
||||
goalsAgainst: 17,
|
||||
goalDifference: -3,
|
||||
points: 16,
|
||||
},
|
||||
{
|
||||
rank: 10,
|
||||
teamId: 9,
|
||||
played: 13,
|
||||
won: 3,
|
||||
drawn: 5,
|
||||
lost: 5,
|
||||
goalsFor: 13,
|
||||
goalsAgainst: 18,
|
||||
goalDifference: -5,
|
||||
points: 14,
|
||||
},
|
||||
{
|
||||
rank: 11,
|
||||
teamId: 11,
|
||||
played: 13,
|
||||
won: 2,
|
||||
drawn: 4,
|
||||
lost: 7,
|
||||
goalsFor: 11,
|
||||
goalsAgainst: 20,
|
||||
goalDifference: -9,
|
||||
points: 10,
|
||||
},
|
||||
{
|
||||
rank: 12,
|
||||
teamId: 12,
|
||||
played: 13,
|
||||
won: 1,
|
||||
drawn: 3,
|
||||
lost: 9,
|
||||
goalsFor: 9,
|
||||
goalsAgainst: 24,
|
||||
goalDifference: -15,
|
||||
points: 6,
|
||||
},
|
||||
],
|
||||
|
||||
// 赛程数据
|
||||
fixtures: [
|
||||
{
|
||||
id: 1,
|
||||
round: 1,
|
||||
date: "2025-03-01",
|
||||
time: "15:00",
|
||||
homeTeamId: 1,
|
||||
awayTeamId: 2,
|
||||
venue: "南京奥体中心",
|
||||
status: "completed",
|
||||
homeScore: 2,
|
||||
awayScore: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
round: 1,
|
||||
date: "2025-03-01",
|
||||
time: "15:00",
|
||||
homeTeamId: 3,
|
||||
awayTeamId: 4,
|
||||
venue: "无锡体育中心",
|
||||
status: "completed",
|
||||
homeScore: 1,
|
||||
awayScore: 1,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
round: 1,
|
||||
date: "2025-03-02",
|
||||
time: "19:30",
|
||||
homeTeamId: 5,
|
||||
awayTeamId: 6,
|
||||
venue: "镇江体育会展中心",
|
||||
status: "completed",
|
||||
homeScore: 0,
|
||||
awayScore: 2,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
round: 1,
|
||||
date: "2025-03-02",
|
||||
time: "19:30",
|
||||
homeTeamId: 7,
|
||||
awayTeamId: 8,
|
||||
venue: "南通体育会展中心",
|
||||
status: "completed",
|
||||
homeScore: 1,
|
||||
awayScore: 3,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
round: 1,
|
||||
date: "2025-03-03",
|
||||
time: "15:00",
|
||||
homeTeamId: 9,
|
||||
awayTeamId: 10,
|
||||
venue: "淮安体育中心",
|
||||
status: "completed",
|
||||
homeScore: 2,
|
||||
awayScore: 2,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
round: 1,
|
||||
date: "2025-03-03",
|
||||
time: "15:00",
|
||||
homeTeamId: 11,
|
||||
awayTeamId: 12,
|
||||
venue: "泰州体育公园",
|
||||
status: "completed",
|
||||
homeScore: 1,
|
||||
awayScore: 0,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
round: 2,
|
||||
date: "2025-03-08",
|
||||
time: "15:00",
|
||||
homeTeamId: 2,
|
||||
awayTeamId: 3,
|
||||
venue: "苏州奥林匹克体育中心",
|
||||
status: "completed",
|
||||
homeScore: 2,
|
||||
awayScore: 0,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
round: 2,
|
||||
date: "2025-03-08",
|
||||
time: "15:00",
|
||||
homeTeamId: 4,
|
||||
awayTeamId: 5,
|
||||
venue: "常州奥林匹克体育中心",
|
||||
status: "completed",
|
||||
homeScore: 3,
|
||||
awayScore: 1,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
round: 2,
|
||||
date: "2025-03-09",
|
||||
time: "19:30",
|
||||
homeTeamId: 6,
|
||||
awayTeamId: 7,
|
||||
venue: "扬州体育公园",
|
||||
status: "completed",
|
||||
homeScore: 1,
|
||||
awayScore: 1,
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
round: 2,
|
||||
date: "2025-03-09",
|
||||
time: "19:30",
|
||||
homeTeamId: 8,
|
||||
awayTeamId: 9,
|
||||
venue: "徐州奥体中心",
|
||||
status: "completed",
|
||||
homeScore: 2,
|
||||
awayScore: 0,
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
round: 2,
|
||||
date: "2025-03-10",
|
||||
time: "15:00",
|
||||
homeTeamId: 10,
|
||||
awayTeamId: 11,
|
||||
venue: "盐城体育中心",
|
||||
status: "completed",
|
||||
homeScore: 1,
|
||||
awayScore: 0,
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
round: 2,
|
||||
date: "2025-03-10",
|
||||
time: "15:00",
|
||||
homeTeamId: 12,
|
||||
awayTeamId: 1,
|
||||
venue: "宿迁体育中心",
|
||||
status: "completed",
|
||||
homeScore: 0,
|
||||
awayScore: 3,
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
round: 12,
|
||||
date: "2025-05-24",
|
||||
time: "19:30",
|
||||
homeTeamId: 1,
|
||||
awayTeamId: 2,
|
||||
venue: "南京奥体中心",
|
||||
status: "scheduled",
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
round: 12,
|
||||
date: "2025-05-24",
|
||||
time: "15:00",
|
||||
homeTeamId: 3,
|
||||
awayTeamId: 4,
|
||||
venue: "无锡体育中心",
|
||||
status: "scheduled",
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
round: 12,
|
||||
date: "2025-05-25",
|
||||
time: "19:30",
|
||||
homeTeamId: 5,
|
||||
awayTeamId: 6,
|
||||
venue: "镇江体育会展中心",
|
||||
status: "scheduled",
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
round: 12,
|
||||
date: "2025-05-25",
|
||||
time: "15:00",
|
||||
homeTeamId: 7,
|
||||
awayTeamId: 8,
|
||||
venue: "南通体育会展中心",
|
||||
status: "scheduled",
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
round: 12,
|
||||
date: "2025-05-26",
|
||||
time: "19:30",
|
||||
homeTeamId: 9,
|
||||
awayTeamId: 10,
|
||||
venue: "淮安体育中心",
|
||||
status: "scheduled",
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
round: 12,
|
||||
date: "2025-05-26",
|
||||
time: "15:00",
|
||||
homeTeamId: 11,
|
||||
awayTeamId: 12,
|
||||
venue: "泰州体育公园",
|
||||
status: "scheduled",
|
||||
},
|
||||
],
|
||||
|
||||
// 球员数据
|
||||
players: {
|
||||
scorers: [
|
||||
{
|
||||
rank: 1,
|
||||
playerId: 101,
|
||||
name: "张伟",
|
||||
teamId: 1,
|
||||
goals: 12,
|
||||
assists: 4,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 2,
|
||||
playerId: 102,
|
||||
name: "李明",
|
||||
teamId: 1,
|
||||
goals: 8,
|
||||
assists: 6,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 3,
|
||||
playerId: 201,
|
||||
name: "王强",
|
||||
teamId: 2,
|
||||
goals: 7,
|
||||
assists: 5,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 4,
|
||||
playerId: 301,
|
||||
name: "赵刚",
|
||||
teamId: 3,
|
||||
goals: 6,
|
||||
assists: 3,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 5,
|
||||
playerId: 801,
|
||||
name: "陈明",
|
||||
teamId: 8,
|
||||
goals: 6,
|
||||
assists: 2,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 6,
|
||||
playerId: 401,
|
||||
name: "孙磊",
|
||||
teamId: 4,
|
||||
goals: 5,
|
||||
assists: 4,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 7,
|
||||
playerId: 601,
|
||||
name: "钱勇",
|
||||
teamId: 6,
|
||||
goals: 5,
|
||||
assists: 3,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 8,
|
||||
playerId: 501,
|
||||
name: "吴斌",
|
||||
teamId: 5,
|
||||
goals: 4,
|
||||
assists: 5,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 9,
|
||||
playerId: 701,
|
||||
name: "冯超",
|
||||
teamId: 7,
|
||||
goals: 4,
|
||||
assists: 3,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 10,
|
||||
playerId: 1001,
|
||||
name: "郑涛",
|
||||
teamId: 10,
|
||||
goals: 3,
|
||||
assists: 2,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
],
|
||||
|
||||
assists: [
|
||||
{
|
||||
rank: 1,
|
||||
playerId: 102,
|
||||
name: "李明",
|
||||
teamId: 1,
|
||||
assists: 6,
|
||||
goals: 8,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 2,
|
||||
playerId: 501,
|
||||
name: "吴斌",
|
||||
teamId: 5,
|
||||
assists: 5,
|
||||
goals: 4,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 3,
|
||||
playerId: 201,
|
||||
name: "王强",
|
||||
teamId: 2,
|
||||
assists: 5,
|
||||
goals: 7,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 4,
|
||||
playerId: 401,
|
||||
name: "孙磊",
|
||||
teamId: 4,
|
||||
assists: 4,
|
||||
goals: 5,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 5,
|
||||
playerId: 101,
|
||||
name: "张伟",
|
||||
teamId: 1,
|
||||
assists: 4,
|
||||
goals: 12,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 6,
|
||||
playerId: 301,
|
||||
name: "赵刚",
|
||||
teamId: 3,
|
||||
assists: 3,
|
||||
goals: 6,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 7,
|
||||
playerId: 601,
|
||||
name: "钱勇",
|
||||
teamId: 6,
|
||||
assists: 3,
|
||||
goals: 5,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 8,
|
||||
playerId: 701,
|
||||
name: "冯超",
|
||||
teamId: 7,
|
||||
assists: 3,
|
||||
goals: 4,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 9,
|
||||
playerId: 901,
|
||||
name: "周伟",
|
||||
teamId: 9,
|
||||
assists: 3,
|
||||
goals: 2,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
{
|
||||
rank: 10,
|
||||
playerId: 1101,
|
||||
name: "王刚",
|
||||
teamId: 11,
|
||||
assists: 2,
|
||||
goals: 1,
|
||||
matches: 13,
|
||||
minutes: 1170,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// 新闻数据
|
||||
news: [
|
||||
{
|
||||
id: 1,
|
||||
title: "南京城联主场力克苏州雄狮,继续领跑积分榜",
|
||||
excerpt:
|
||||
"在昨晚进行的第12轮焦点战中,南京城联凭借张伟的梅开二度,主场2-1战胜苏州雄狮,继续以2分优势领跑积分榜。",
|
||||
category: "比赛战报",
|
||||
date: "2025-05-25",
|
||||
imageColor: "#dc2626",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "联赛最佳球员揭晓:张伟当选4月最佳",
|
||||
excerpt:
|
||||
"江苏城市足球联赛官方宣布,南京城联前锋张伟凭借出色的表现,当选4月份联赛最佳球员。",
|
||||
category: "官方公告",
|
||||
date: "2025-05-20",
|
||||
imageColor: "#3b82f6",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "徐州楚汉签下前国脚李强,实力大增",
|
||||
excerpt:
|
||||
"徐州楚汉俱乐部官方宣布,与前国家队中场李强签约两年,这位经验丰富的老将将提升球队中场实力。",
|
||||
category: "转会新闻",
|
||||
date: "2025-05-18",
|
||||
imageColor: "#84cc16",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "联赛半程总结:竞争激烈,多队有望争冠",
|
||||
excerpt:
|
||||
"随着联赛进入半程,积分榜前六名球队分差仅7分,本赛季冠军争夺异常激烈,多支球队都有机会问鼎。",
|
||||
category: "联赛动态",
|
||||
date: "2025-05-15",
|
||||
imageColor: "#f59e0b",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "球迷互动日:各俱乐部将举办开放训练",
|
||||
excerpt:
|
||||
"为感谢球迷支持,各俱乐部将在本周末举办球迷开放日,球迷可近距离观看球队训练并与球员互动。",
|
||||
category: "球迷活动",
|
||||
date: "2025-05-12",
|
||||
imageColor: "#ec4899",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "技术统计:联赛进球数创历史新高",
|
||||
excerpt:
|
||||
"本赛季前13轮共打进176球,场均2.77球,创下联赛历史同期最高进球纪录,进攻足球成为主流。",
|
||||
category: "数据统计",
|
||||
date: "2025-05-10",
|
||||
imageColor: "#0ea5e9",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// 工具函数:根据ID获取球队信息
|
||||
function getTeamById(teamId) {
|
||||
return leagueData.teams.find((team) => team.id === teamId);
|
||||
}
|
||||
|
||||
// 工具函数:格式化日期
|
||||
function formatDate(dateString) {
|
||||
const date = new Date(dateString);
|
||||
const options = { weekday: "short", month: "short", day: "numeric" };
|
||||
return date.toLocaleDateString("zh-CN", options);
|
||||
}
|
||||
|
||||
// 工具函数:格式化时间
|
||||
function formatTime(timeString) {
|
||||
return timeString;
|
||||
}
|
||||
|
||||
// 导出数据
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = leagueData;
|
||||
}
|
||||
@@ -0,0 +1,645 @@
|
||||
// 江苏城市足球联赛2025赛季 - 主JavaScript文件
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// 初始化加载动画
|
||||
initLoader();
|
||||
|
||||
// 初始化主题切换
|
||||
initThemeToggle();
|
||||
|
||||
// 初始化导航菜单
|
||||
initNavigation();
|
||||
|
||||
// 初始化滚动监听
|
||||
initScrollSpy();
|
||||
|
||||
// 渲染球队卡片
|
||||
renderTeams();
|
||||
|
||||
// 渲染积分榜
|
||||
renderStandings();
|
||||
|
||||
// 渲染赛程表
|
||||
renderFixtures();
|
||||
|
||||
// 渲染数据统计
|
||||
renderStats();
|
||||
|
||||
// 渲染新闻动态
|
||||
renderNews();
|
||||
|
||||
// 初始化标签页切换
|
||||
initTabs();
|
||||
|
||||
// 初始化移动端菜单
|
||||
initMobileMenu();
|
||||
});
|
||||
|
||||
// 加载动画
|
||||
function initLoader() {
|
||||
const loader = document.querySelector(".loader");
|
||||
|
||||
// 模拟加载延迟
|
||||
setTimeout(() => {
|
||||
loader.classList.add("loaded");
|
||||
|
||||
// 动画结束后隐藏loader
|
||||
setTimeout(() => {
|
||||
loader.style.display = "none";
|
||||
}, 300);
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
// 主题切换
|
||||
function initThemeToggle() {
|
||||
const themeToggle = document.querySelector(".btn-theme-toggle");
|
||||
const themeIcon = themeToggle.querySelector("i");
|
||||
|
||||
// 检查本地存储的主题偏好
|
||||
const savedTheme = localStorage.getItem("theme") || "light";
|
||||
document.documentElement.setAttribute("data-theme", savedTheme);
|
||||
updateThemeIcon(savedTheme);
|
||||
|
||||
themeToggle.addEventListener("click", () => {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
const newTheme = currentTheme === "light" ? "dark" : "light";
|
||||
|
||||
document.documentElement.setAttribute("data-theme", newTheme);
|
||||
localStorage.setItem("theme", newTheme);
|
||||
updateThemeIcon(newTheme);
|
||||
|
||||
// 添加切换动画
|
||||
themeToggle.style.transform = "scale(0.9)";
|
||||
setTimeout(() => {
|
||||
themeToggle.style.transform = "";
|
||||
}, 150);
|
||||
});
|
||||
|
||||
function updateThemeIcon(theme) {
|
||||
if (theme === "dark") {
|
||||
themeIcon.className = "fas fa-sun";
|
||||
} else {
|
||||
themeIcon.className = "fas fa-moon";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导航菜单
|
||||
function initNavigation() {
|
||||
const navLinks = document.querySelectorAll(".nav-link");
|
||||
|
||||
navLinks.forEach((link) => {
|
||||
link.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const targetId = this.getAttribute("href");
|
||||
const targetSection = document.querySelector(targetId);
|
||||
|
||||
if (targetSection) {
|
||||
// 更新活动链接
|
||||
navLinks.forEach((l) => l.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
|
||||
// 平滑滚动到目标区域
|
||||
window.scrollTo({
|
||||
top: targetSection.offsetTop - 80,
|
||||
behavior: "smooth",
|
||||
});
|
||||
|
||||
// 如果是移动端,关闭菜单
|
||||
const navMenu = document.querySelector(".nav-menu");
|
||||
if (navMenu.classList.contains("active")) {
|
||||
navMenu.classList.remove("active");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 滚动监听
|
||||
function initScrollSpy() {
|
||||
const sections = document.querySelectorAll("section[id]");
|
||||
const navLinks = document.querySelectorAll(".nav-link");
|
||||
|
||||
window.addEventListener("scroll", () => {
|
||||
let current = "";
|
||||
|
||||
sections.forEach((section) => {
|
||||
const sectionTop = section.offsetTop;
|
||||
const sectionHeight = section.clientHeight;
|
||||
|
||||
if (scrollY >= sectionTop - 100) {
|
||||
current = section.getAttribute("id");
|
||||
}
|
||||
});
|
||||
|
||||
navLinks.forEach((link) => {
|
||||
link.classList.remove("active");
|
||||
if (link.getAttribute("href") === `#${current}`) {
|
||||
link.classList.add("active");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染球队卡片
|
||||
function renderTeams() {
|
||||
const teamsGrid = document.querySelector(".teams-grid");
|
||||
|
||||
if (!teamsGrid) return;
|
||||
|
||||
teamsGrid.innerHTML = "";
|
||||
|
||||
leagueData.teams.forEach((team) => {
|
||||
const teamCard = document.createElement("div");
|
||||
teamCard.className = "team-card";
|
||||
|
||||
// 获取球队统计数据
|
||||
const standing = leagueData.standings.find((s) => s.teamId === team.id);
|
||||
|
||||
teamCard.innerHTML = `
|
||||
<div class="team-card-logo" style="background: linear-gradient(135deg, ${team.colors[0]} 0%, ${team.colors[1]} 100%);">
|
||||
${team.shortName}
|
||||
</div>
|
||||
<h3 class="team-card-name">${team.name}</h3>
|
||||
<div class="team-card-city">${team.city}</div>
|
||||
<div class="team-card-stats">
|
||||
<div class="team-stat">
|
||||
<div class="team-stat-value">${standing ? standing.rank : "-"}</div>
|
||||
<div class="team-stat-label">排名</div>
|
||||
</div>
|
||||
<div class="team-stat">
|
||||
<div class="team-stat-value">${standing ? standing.points : "0"}</div>
|
||||
<div class="team-stat-label">积分</div>
|
||||
</div>
|
||||
<div class="team-stat">
|
||||
<div class="team-stat-value">${standing ? standing.goalDifference : "0"}</div>
|
||||
<div class="team-stat-label">净胜球</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
teamCard.addEventListener("click", () => {
|
||||
// 这里可以添加点击跳转到球队详情页的功能
|
||||
alert(`查看 ${team.name} 的详细信息`);
|
||||
});
|
||||
|
||||
teamsGrid.appendChild(teamCard);
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染积分榜
|
||||
function renderStandings() {
|
||||
const standingsTable = document.querySelector(".standings-table tbody");
|
||||
|
||||
if (!standingsTable) return;
|
||||
|
||||
standingsTable.innerHTML = "";
|
||||
|
||||
leagueData.standings.forEach((standing) => {
|
||||
const team = getTeamById(standing.teamId);
|
||||
|
||||
const row = document.createElement("tr");
|
||||
|
||||
// 根据排名添加特殊样式
|
||||
if (standing.rank <= 4) {
|
||||
row.classList.add("champions-league");
|
||||
} else if (standing.rank <= 6) {
|
||||
row.classList.add("europa-league");
|
||||
} else if (standing.rank >= 11) {
|
||||
row.classList.add("relegation");
|
||||
}
|
||||
|
||||
row.innerHTML = `
|
||||
<td>${standing.rank}</td>
|
||||
<td>
|
||||
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
||||
<div class="team-logo-small" style="width: 24px; height: 24px; border-radius: 50%; background: linear-gradient(135deg, ${team.colors[0]} 0%, ${team.colors[1]} 100%);"></div>
|
||||
${team.name}
|
||||
</div>
|
||||
</td>
|
||||
<td>${standing.played}</td>
|
||||
<td>${standing.won}</td>
|
||||
<td>${standing.drawn}</td>
|
||||
<td>${standing.lost}</td>
|
||||
<td>${standing.goalsFor}</td>
|
||||
<td>${standing.goalsAgainst}</td>
|
||||
<td>${standing.goalDifference > 0 ? "+" : ""}${standing.goalDifference}</td>
|
||||
<td><strong>${standing.points}</strong></td>
|
||||
`;
|
||||
|
||||
standingsTable.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染赛程表
|
||||
function renderFixtures() {
|
||||
const fixturesList = document.querySelector(".fixtures-list");
|
||||
|
||||
if (!fixturesList) return;
|
||||
|
||||
fixturesList.innerHTML = "";
|
||||
|
||||
// 按轮次分组
|
||||
const fixturesByRound = {};
|
||||
leagueData.fixtures.forEach((fixture) => {
|
||||
if (!fixturesByRound[fixture.round]) {
|
||||
fixturesByRound[fixture.round] = [];
|
||||
}
|
||||
fixturesByRound[fixture.round].push(fixture);
|
||||
});
|
||||
|
||||
// 渲染所有赛程
|
||||
Object.keys(fixturesByRound)
|
||||
.sort((a, b) => a - b)
|
||||
.forEach((round) => {
|
||||
const roundHeader = document.createElement("div");
|
||||
roundHeader.className = "fixture-round-header";
|
||||
roundHeader.innerHTML = `<h3>第${round}轮</h3>`;
|
||||
fixturesList.appendChild(roundHeader);
|
||||
|
||||
fixturesByRound[round].forEach((fixture) => {
|
||||
const homeTeam = getTeamById(fixture.homeTeamId);
|
||||
const awayTeam = getTeamById(fixture.awayTeamId);
|
||||
|
||||
const fixtureItem = document.createElement("div");
|
||||
fixtureItem.className = "fixture-item";
|
||||
|
||||
const date = new Date(fixture.date);
|
||||
const dayNames = [
|
||||
"周日",
|
||||
"周一",
|
||||
"周二",
|
||||
"周三",
|
||||
"周四",
|
||||
"周五",
|
||||
"周六",
|
||||
];
|
||||
const dayName = dayNames[date.getDay()];
|
||||
|
||||
let scoreHtml = "";
|
||||
let statusText = "";
|
||||
|
||||
if (fixture.status === "completed") {
|
||||
scoreHtml = `
|
||||
<div class="fixture-score-value">${fixture.homeScore} - ${fixture.awayScore}</div>
|
||||
<div class="fixture-score-status">已结束</div>
|
||||
`;
|
||||
} else if (fixture.status === "scheduled") {
|
||||
scoreHtml = `
|
||||
<div class="fixture-score-value">VS</div>
|
||||
<div class="fixture-score-status">${fixture.time}</div>
|
||||
`;
|
||||
} else {
|
||||
scoreHtml = `
|
||||
<div class="fixture-score-value">-</div>
|
||||
<div class="fixture-score-status">待定</div>
|
||||
`;
|
||||
}
|
||||
|
||||
fixtureItem.innerHTML = `
|
||||
<div class="fixture-date">
|
||||
<div class="fixture-day">${dayName}</div>
|
||||
<div class="fixture-time">${formatDate(fixture.date)}</div>
|
||||
</div>
|
||||
<div class="fixture-teams">
|
||||
<div class="fixture-team home">
|
||||
<div class="fixture-team-name">${homeTeam.name}</div>
|
||||
<div class="fixture-team-logo" style="background: linear-gradient(135deg, ${homeTeam.colors[0]} 0%, ${homeTeam.colors[1]} 100%);"></div>
|
||||
</div>
|
||||
<div class="fixture-vs">VS</div>
|
||||
<div class="fixture-team away">
|
||||
<div class="fixture-team-logo" style="background: linear-gradient(135deg, ${awayTeam.colors[0]} 0%, ${awayTeam.colors[1]} 100%);"></div>
|
||||
<div class="fixture-team-name">${awayTeam.name}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixture-score">
|
||||
${scoreHtml}
|
||||
</div>
|
||||
`;
|
||||
|
||||
fixturesList.appendChild(fixtureItem);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染数据统计
|
||||
function renderStats() {
|
||||
renderScorers();
|
||||
renderAssists();
|
||||
renderTeamStats();
|
||||
}
|
||||
|
||||
function renderScorers() {
|
||||
const scorersContainer = document.querySelector("#scorers");
|
||||
|
||||
if (!scorersContainer) return;
|
||||
|
||||
scorersContainer.innerHTML = `
|
||||
<table class="stats-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="stats-rank">排名</th>
|
||||
<th class="stats-player">球员</th>
|
||||
<th class="stats-team">球队</th>
|
||||
<th class="stats-value">进球</th>
|
||||
<th class="stats-value">助攻</th>
|
||||
<th class="stats-value">出场</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${leagueData.players.scorers
|
||||
.map((player) => {
|
||||
const team = getTeamById(player.teamId);
|
||||
return `
|
||||
<tr>
|
||||
<td class="stats-rank">${player.rank}</td>
|
||||
<td class="stats-player">${player.name}</td>
|
||||
<td class="stats-team">${team.name}</td>
|
||||
<td class="stats-value">${player.goals}</td>
|
||||
<td class="stats-value">${player.assists}</td>
|
||||
<td class="stats-value">${player.matches}</td>
|
||||
</tr>
|
||||
`;
|
||||
})
|
||||
.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderAssists() {
|
||||
const assistsContainer = document.querySelector("#assists");
|
||||
|
||||
if (!assistsContainer) return;
|
||||
|
||||
assistsContainer.innerHTML = `
|
||||
<table class="stats-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="stats-rank">排名</th>
|
||||
<th class="stats-player">球员</th>
|
||||
<th class="stats-team">球队</th>
|
||||
<th class="stats-value">助攻</th>
|
||||
<th class="stats-value">进球</th>
|
||||
<th class="stats-value">出场</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${leagueData.players.assists
|
||||
.map((player) => {
|
||||
const team = getTeamById(player.teamId);
|
||||
return `
|
||||
<tr>
|
||||
<td class="stats-rank">${player.rank}</td>
|
||||
<td class="stats-player">${player.name}</td>
|
||||
<td class="stats-team">${team.name}</td>
|
||||
<td class="stats-value">${player.assists}</td>
|
||||
<td class="stats-value">${player.goals}</td>
|
||||
<td class="stats-value">${player.matches}</td>
|
||||
</tr>
|
||||
`;
|
||||
})
|
||||
.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderTeamStats() {
|
||||
const teamStatsContainer = document.querySelector("#teams");
|
||||
|
||||
if (!teamStatsContainer) return;
|
||||
|
||||
// 计算球队统计数据
|
||||
const teamStats = leagueData.standings
|
||||
.map((standing) => {
|
||||
const team = getTeamById(standing.teamId);
|
||||
const goalsPerGame = (standing.goalsFor / standing.played).toFixed(2);
|
||||
const concededPerGame = (standing.goalsAgainst / standing.played).toFixed(
|
||||
2,
|
||||
);
|
||||
|
||||
return {
|
||||
rank: standing.rank,
|
||||
team: team.name,
|
||||
goalsFor: standing.goalsFor,
|
||||
goalsAgainst: standing.goalsAgainst,
|
||||
goalDifference: standing.goalDifference,
|
||||
goalsPerGame,
|
||||
concededPerGame,
|
||||
cleanSheets: Math.floor(Math.random() * 5), // 模拟数据
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.rank - b.rank);
|
||||
|
||||
teamStatsContainer.innerHTML = `
|
||||
<table class="stats-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="stats-rank">排名</th>
|
||||
<th class="stats-player">球队</th>
|
||||
<th class="stats-value">进球</th>
|
||||
<th class="stats-value">失球</th>
|
||||
<th class="stats-value">净胜球</th>
|
||||
<th class="stats-value">场均进球</th>
|
||||
<th class="stats-value">场均失球</th>
|
||||
<th class="stats-value">零封</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${teamStats
|
||||
.map(
|
||||
(stat) => `
|
||||
<tr>
|
||||
<td class="stats-rank">${stat.rank}</td>
|
||||
<td class="stats-player">${stat.team}</td>
|
||||
<td class="stats-value">${stat.goalsFor}</td>
|
||||
<td class="stats-value">${stat.goalsAgainst}</td>
|
||||
<td class="stats-value">${stat.goalDifference > 0 ? "+" : ""}${stat.goalDifference}</td>
|
||||
<td class="stats-value">${stat.goalsPerGame}</td>
|
||||
<td class="stats-value">${stat.concededPerGame}</td>
|
||||
<td class="stats-value">${stat.cleanSheets}</td>
|
||||
</tr>
|
||||
`,
|
||||
)
|
||||
.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
// 渲染新闻动态
|
||||
function renderNews() {
|
||||
const newsGrid = document.querySelector(".news-grid");
|
||||
|
||||
if (!newsGrid) return;
|
||||
|
||||
newsGrid.innerHTML = "";
|
||||
|
||||
leagueData.news.forEach((newsItem) => {
|
||||
const newsCard = document.createElement("div");
|
||||
newsCard.className = "news-card";
|
||||
|
||||
const date = new Date(newsItem.date);
|
||||
const formattedDate = date.toLocaleDateString("zh-CN", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
newsCard.innerHTML = `
|
||||
<div class="news-card-image" style="background: linear-gradient(135deg, ${newsItem.imageColor} 0%, ${darkenColor(newsItem.imageColor, 20)} 100%);"></div>
|
||||
<div class="news-card-content">
|
||||
<span class="news-card-category">${newsItem.category}</span>
|
||||
<h3 class="news-card-title">${newsItem.title}</h3>
|
||||
<p class="news-card-excerpt">${newsItem.excerpt}</p>
|
||||
<div class="news-card-meta">
|
||||
<span class="news-card-date">
|
||||
<i class="far fa-calendar"></i>
|
||||
${formattedDate}
|
||||
</span>
|
||||
<span class="news-card-read-more">阅读更多 →</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
newsCard.addEventListener("click", () => {
|
||||
alert(`查看新闻: ${newsItem.title}`);
|
||||
});
|
||||
|
||||
newsGrid.appendChild(newsCard);
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化标签页切换
|
||||
function initTabs() {
|
||||
// 赛程标签页
|
||||
const fixtureTabs = document.querySelectorAll(".fixtures-tabs .tab");
|
||||
const fixtureItems = document.querySelectorAll(".fixture-item");
|
||||
|
||||
fixtureTabs.forEach((tab) => {
|
||||
tab.addEventListener("click", () => {
|
||||
// 更新活动标签
|
||||
fixtureTabs.forEach((t) => t.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
|
||||
const roundFilter = tab.getAttribute("data-round");
|
||||
|
||||
// 这里可以根据筛选条件显示不同的赛程
|
||||
// 由于时间关系,这里只是简单的演示
|
||||
console.log(`筛选赛程: ${roundFilter}`);
|
||||
});
|
||||
});
|
||||
|
||||
// 数据统计标签页
|
||||
const statsTabs = document.querySelectorAll(".stats-tab");
|
||||
const statsContents = document.querySelectorAll(".stats-tab-content");
|
||||
|
||||
statsTabs.forEach((tab) => {
|
||||
tab.addEventListener("click", () => {
|
||||
const tabId = tab.getAttribute("data-tab");
|
||||
|
||||
// 更新活动标签
|
||||
statsTabs.forEach((t) => t.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
|
||||
// 显示对应内容
|
||||
statsContents.forEach((content) => {
|
||||
content.classList.remove("active");
|
||||
if (content.id === tabId) {
|
||||
content.classList.add("active");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化移动端菜单
|
||||
function initMobileMenu() {
|
||||
const menuToggle = document.querySelector(".btn-menu-toggle");
|
||||
const navMenu = document.querySelector(".nav-menu");
|
||||
|
||||
if (menuToggle && navMenu) {
|
||||
menuToggle.addEventListener("click", () => {
|
||||
navMenu.classList.toggle("active");
|
||||
|
||||
// 更新菜单图标
|
||||
const icon = menuToggle.querySelector("i");
|
||||
if (navMenu.classList.contains("active")) {
|
||||
icon.className = "fas fa-times";
|
||||
} else {
|
||||
icon.className = "fas fa-bars";
|
||||
}
|
||||
});
|
||||
|
||||
// 点击菜单外区域关闭菜单
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!navMenu.contains(e.target) && !menuToggle.contains(e.target)) {
|
||||
navMenu.classList.remove("active");
|
||||
menuToggle.querySelector("i").className = "fas fa-bars";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 工具函数:加深颜色
|
||||
function darkenColor(color, percent) {
|
||||
const num = parseInt(color.replace("#", ""), 16);
|
||||
const amt = Math.round(2.55 * percent);
|
||||
const R = (num >> 16) - amt;
|
||||
const G = ((num >> 8) & 0x00ff) - amt;
|
||||
const B = (num & 0x0000ff) - amt;
|
||||
|
||||
return (
|
||||
"#" +
|
||||
(
|
||||
0x1000000 +
|
||||
(R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +
|
||||
(G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +
|
||||
(B < 255 ? (B < 1 ? 0 : B) : 255)
|
||||
)
|
||||
.toString(16)
|
||||
.slice(1)
|
||||
);
|
||||
}
|
||||
|
||||
// 工具函数:格式化日期(简写)
|
||||
function formatDate(dateString) {
|
||||
const date = new Date(dateString);
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
return `${month}月${day}日`;
|
||||
}
|
||||
|
||||
// 工具函数:根据ID获取球队信息
|
||||
function getTeamById(teamId) {
|
||||
return leagueData.teams.find((team) => team.id === teamId);
|
||||
}
|
||||
|
||||
// 添加一些交互效果
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// 为所有按钮添加点击效果
|
||||
const buttons = document.querySelectorAll(".btn");
|
||||
buttons.forEach((button) => {
|
||||
button.addEventListener("mousedown", () => {
|
||||
button.style.transform = "scale(0.95)";
|
||||
});
|
||||
|
||||
button.addEventListener("mouseup", () => {
|
||||
button.style.transform = "";
|
||||
});
|
||||
|
||||
button.addEventListener("mouseleave", () => {
|
||||
button.style.transform = "";
|
||||
});
|
||||
});
|
||||
|
||||
// 为卡片添加悬停效果
|
||||
const cards = document.querySelectorAll(".team-card, .news-card");
|
||||
cards.forEach((card) => {
|
||||
card.addEventListener("mouseenter", () => {
|
||||
card.style.transition = "transform 0.3s ease, box-shadow 0.3s ease";
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,533 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>2026 Horizons: Trends & Opportunities</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
|
||||
/>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/svg+xml"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📈</text></svg>"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar">
|
||||
<div class="container">
|
||||
<div class="nav-brand">
|
||||
<span class="brand-icon">📈</span>
|
||||
<span class="brand-text">2026 Horizons</span>
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#overview">Overview</a></li>
|
||||
<li><a href="#trends">Trends</a></li>
|
||||
<li><a href="#opportunities">Opportunities</a></li>
|
||||
<li><a href="#challenges">Challenges</a></li>
|
||||
</ul>
|
||||
<button class="theme-toggle" id="themeToggle">
|
||||
<i class="fas fa-moon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<header class="hero">
|
||||
<div class="container">
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">Navigating the Future</h1>
|
||||
<p class="hero-subtitle">
|
||||
A comprehensive analysis of trends, opportunities, and challenges
|
||||
shaping 2026
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number">5</span>
|
||||
<span class="stat-label">Key Economic Trends</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number">8</span>
|
||||
<span class="stat-label">High-Growth Markets</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number">4</span>
|
||||
<span class="stat-label">Technology Shifts</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#trends" class="cta-button"
|
||||
>Explore Trends <i class="fas fa-arrow-down"></i
|
||||
></a>
|
||||
</div>
|
||||
<div class="hero-visual">
|
||||
<div class="visual-element">
|
||||
<div class="circle"></div>
|
||||
<div class="line"></div>
|
||||
<div class="dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Overview Section -->
|
||||
<section class="section overview" id="overview">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">The 2026 Landscape</h2>
|
||||
<p class="section-subtitle">
|
||||
Convergence, complexity, and unprecedented opportunities
|
||||
</p>
|
||||
</div>
|
||||
<div class="overview-content">
|
||||
<div class="overview-text">
|
||||
<p>
|
||||
2026 represents a pivotal inflection point where accelerating
|
||||
technological convergence meets economic realignment and emerging
|
||||
market opportunities. The year will be defined by the interplay of
|
||||
AI maturation, quantum computing practicality, and sustainable
|
||||
transformation.
|
||||
</p>
|
||||
<p>
|
||||
Organizations and individuals who can navigate this complexity
|
||||
while maintaining strategic agility will be best positioned to
|
||||
capitalize on emerging opportunities across technology, business,
|
||||
and sustainability sectors.
|
||||
</p>
|
||||
</div>
|
||||
<div class="overview-highlight">
|
||||
<div class="highlight-card">
|
||||
<div class="highlight-icon">
|
||||
<i class="fas fa-brain"></i>
|
||||
</div>
|
||||
<h3 class="highlight-title">AI Maturation</h3>
|
||||
<p class="highlight-text">
|
||||
Transition from experimentation to production deployment with
|
||||
autonomous agents
|
||||
</p>
|
||||
</div>
|
||||
<div class="highlight-card">
|
||||
<div class="highlight-icon">
|
||||
<i class="fas fa-leaf"></i>
|
||||
</div>
|
||||
<h3 class="highlight-title">Sustainability Focus</h3>
|
||||
<p class="highlight-text">
|
||||
Climate tech emerges as a dominant investment category with
|
||||
material financial implications
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Trends Section -->
|
||||
<section class="section trends" id="trends">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">Key Trends Shaping 2026</h2>
|
||||
<p class="section-subtitle">
|
||||
Critical developments across technology, economy, and society
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="trends-grid">
|
||||
<!-- Technology Trends -->
|
||||
<div class="trend-category">
|
||||
<h3 class="category-title">
|
||||
<i class="fas fa-microchip"></i> Technology & Innovation
|
||||
</h3>
|
||||
<div class="trend-cards">
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge tech">AI</span>
|
||||
<span class="trend-priority high">High Impact</span>
|
||||
</div>
|
||||
<h4 class="trend-name">AI Agents Proliferation</h4>
|
||||
<p class="trend-description">
|
||||
Autonomous AI agents become mainstream in enterprise
|
||||
operations, requiring sophisticated governance frameworks and
|
||||
security considerations.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-rocket"></i> Exponential Growth</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-shield-alt"></i> Security Critical</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge tech">Quantum</span>
|
||||
<span class="trend-priority medium">Emerging</span>
|
||||
</div>
|
||||
<h4 class="trend-name">Quantum-AI Convergence</h4>
|
||||
<p class="trend-description">
|
||||
18% of global quantum algorithm revenues expected from AI
|
||||
applications, marking a significant shift toward practical
|
||||
quantum computing applications.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-chart-line"></i> 18% Revenue Share</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-cogs"></i> Optimization Focus</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge tech">Security</span>
|
||||
<span class="trend-priority high">Critical</span>
|
||||
</div>
|
||||
<h4 class="trend-name">AI-Powered Cybersecurity</h4>
|
||||
<p class="trend-description">
|
||||
Organizations leverage AI for threat detection, red teaming,
|
||||
and automated defense at machine speed, creating new security
|
||||
paradigms.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-bolt"></i> Machine Speed</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-user-shield"></i> Proactive Defense</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Economic Trends -->
|
||||
<div class="trend-category">
|
||||
<h3 class="category-title">
|
||||
<i class="fas fa-chart-line"></i> Economic & Global
|
||||
</h3>
|
||||
<div class="trend-cards">
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge econ">Finance</span>
|
||||
<span class="trend-priority high">Transformative</span>
|
||||
</div>
|
||||
<h4 class="trend-name">Tokenized Cross-Border Payments</h4>
|
||||
<p class="trend-description">
|
||||
Nearly 75% of G20 countries expected to have digital token
|
||||
payment systems, challenging traditional banking and dollar
|
||||
dominance.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-globe"></i> 75% G20 Adoption</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-exchange-alt"></i> Borderless</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge econ">Trade</span>
|
||||
<span class="trend-priority medium">Volatile</span>
|
||||
</div>
|
||||
<h4 class="trend-name">Trade Realignments</h4>
|
||||
<p class="trend-description">
|
||||
Continued US-China tensions with potential EU tariff responses
|
||||
on advanced manufacturing, reshaping global supply chains.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-balance-scale"></i> Geopolitical
|
||||
Shift</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-industry"></i> Supply Chain Impact</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trend-card">
|
||||
<div class="trend-header">
|
||||
<span class="trend-badge econ">Risk</span>
|
||||
<span class="trend-priority high">Critical</span>
|
||||
</div>
|
||||
<h4 class="trend-name">Debt Sustainability Challenges</h4>
|
||||
<p class="trend-description">
|
||||
Record public debt levels with limited fiscal restraint
|
||||
appetite as central banks unwind balance sheets.
|
||||
</p>
|
||||
<div class="trend-metrics">
|
||||
<span class="metric"
|
||||
><i class="fas fa-exclamation-triangle"></i> Record
|
||||
Levels</span
|
||||
>
|
||||
<span class="metric"
|
||||
><i class="fas fa-percentage"></i> Yield Pressure</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Opportunities Section -->
|
||||
<section class="section opportunities" id="opportunities">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">Emerging Opportunities</h2>
|
||||
<p class="section-subtitle">
|
||||
High-growth markets and strategic investment areas
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="opportunities-grid">
|
||||
<div class="opportunity-card">
|
||||
<div class="opportunity-icon climate">
|
||||
<i class="fas fa-solar-panel"></i>
|
||||
</div>
|
||||
<h3 class="opportunity-title">Climate Technology</h3>
|
||||
<p class="opportunity-description">
|
||||
Home energy solutions, carbon capture, and sustainable
|
||||
infrastructure with massive growth potential.
|
||||
</p>
|
||||
<div class="opportunity-market">
|
||||
<span class="market-size">$162B+</span>
|
||||
<span class="market-label">by 2030</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="opportunity-card">
|
||||
<div class="opportunity-icon health">
|
||||
<i class="fas fa-heartbeat"></i>
|
||||
</div>
|
||||
<h3 class="opportunity-title">Preventive Health</h3>
|
||||
<p class="opportunity-description">
|
||||
Personalized wellness, early intervention technologies, and
|
||||
digital health platforms.
|
||||
</p>
|
||||
<div class="opportunity-market">
|
||||
<span class="market-size">High Growth</span>
|
||||
<span class="market-label">Post-pandemic focus</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="opportunity-card">
|
||||
<div class="opportunity-icon tech">
|
||||
<i class="fas fa-robot"></i>
|
||||
</div>
|
||||
<h3 class="opportunity-title">AI Consulting</h3>
|
||||
<p class="opportunity-description">
|
||||
Industry-specific AI implementation services and agentic AI
|
||||
platform development.
|
||||
</p>
|
||||
<div class="opportunity-market">
|
||||
<span class="market-size">Specialized</span>
|
||||
<span class="market-label">Enterprise demand</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="opportunity-card">
|
||||
<div class="opportunity-icon food">
|
||||
<i class="fas fa-seedling"></i>
|
||||
</div>
|
||||
<h3 class="opportunity-title">Plant-Based Foods</h3>
|
||||
<p class="opportunity-description">
|
||||
Sustainable food alternatives with projected market growth toward
|
||||
$162 billion by 2030.
|
||||
</p>
|
||||
<div class="opportunity-market">
|
||||
<span class="market-size">$162B</span>
|
||||
<span class="market-label">Market potential</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="opportunity-highlight">
|
||||
<div class="highlight-content">
|
||||
<h3 class="highlight-title">Strategic Investment Shift</h3>
|
||||
<p>
|
||||
Venture capital is diversifying geographically with emerging hubs
|
||||
in Lagos, Bucharest, Riyadh, and other non-traditional locations.
|
||||
Decentralized finance continues to innovate alternatives to
|
||||
traditional systems.
|
||||
</p>
|
||||
</div>
|
||||
<div class="highlight-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-value">75%</span>
|
||||
<span class="stat-label">G20 Digital Payments</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value">18%</span>
|
||||
<span class="stat-label">Quantum-AI Revenue</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Challenges Section -->
|
||||
<section class="section challenges" id="challenges">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">Critical Challenges & Risks</h2>
|
||||
<p class="section-subtitle">
|
||||
Navigating complexity in an uncertain landscape
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="challenges-content">
|
||||
<div class="challenge-card">
|
||||
<div class="challenge-header">
|
||||
<span class="challenge-severity high">High Risk</span>
|
||||
<h3 class="challenge-title">AI Security Vulnerabilities</h3>
|
||||
</div>
|
||||
<p class="challenge-description">
|
||||
New attack vectors require comprehensive defense strategies as
|
||||
autonomous agents proliferate across organizations.
|
||||
</p>
|
||||
<div class="challenge-mitigation">
|
||||
<span class="mitigation-label">Mitigation:</span>
|
||||
<span class="mitigation-text"
|
||||
>Robust governance frameworks and AI-native security
|
||||
protocols</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="challenge-card">
|
||||
<div class="challenge-header">
|
||||
<span class="challenge-severity medium">Medium Risk</span>
|
||||
<h3 class="challenge-title">Talent & Skills Gap</h3>
|
||||
</div>
|
||||
<p class="challenge-description">
|
||||
Rapid technological change outpacing workforce skill development,
|
||||
creating critical talent shortages.
|
||||
</p>
|
||||
<div class="challenge-mitigation">
|
||||
<span class="mitigation-label">Mitigation:</span>
|
||||
<span class="mitigation-text"
|
||||
>Continuous upskilling programs and AI collaboration
|
||||
training</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="challenge-card">
|
||||
<div class="challenge-header">
|
||||
<span class="challenge-severity high">High Risk</span>
|
||||
<h3 class="challenge-title">Economic Volatility</h3>
|
||||
</div>
|
||||
<p class="challenge-description">
|
||||
Potential AI bubble concerns, trade fragmentation, and competing
|
||||
payment systems creating market uncertainty.
|
||||
</p>
|
||||
<div class="challenge-mitigation">
|
||||
<span class="mitigation-label">Mitigation:</span>
|
||||
<span class="mitigation-text"
|
||||
>Diversified portfolios and agile business models</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="strategic-implications">
|
||||
<h3 class="implications-title">Strategic Implications</h3>
|
||||
<div class="implications-grid">
|
||||
<div class="implication">
|
||||
<h4>For Businesses</h4>
|
||||
<p>
|
||||
Success requires embracing AI as a core competency while
|
||||
maintaining robust cybersecurity. Companies that navigate the
|
||||
sustainability transition while leveraging emerging technologies
|
||||
gain competitive advantages.
|
||||
</p>
|
||||
</div>
|
||||
<div class="implication">
|
||||
<h4>For Investors</h4>
|
||||
<p>
|
||||
Opportunities exist in climate tech, digital transformation, and
|
||||
Asian markets, but require careful assessment of geopolitical
|
||||
risks and potential market corrections.
|
||||
</p>
|
||||
</div>
|
||||
<div class="implication">
|
||||
<h4>For Individuals</h4>
|
||||
<p>
|
||||
Continuous upskilling in AI collaboration, quantum computing
|
||||
awareness, and digital literacy will be essential for career
|
||||
resilience in the evolving landscape.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-content">
|
||||
<div class="footer-brand">
|
||||
<span class="brand-icon">📈</span>
|
||||
<span class="brand-text">2026 Horizons</span>
|
||||
<p class="footer-description">
|
||||
An analysis of trends shaping the future landscape
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-links">
|
||||
<div class="link-group">
|
||||
<h4 class="link-title">Trends</h4>
|
||||
<a href="#trends">Technology</a>
|
||||
<a href="#trends">Economic</a>
|
||||
<a href="#trends">Sustainability</a>
|
||||
</div>
|
||||
<div class="link-group">
|
||||
<h4 class="link-title">Opportunities</h4>
|
||||
<a href="#opportunities">Markets</a>
|
||||
<a href="#opportunities">Investments</a>
|
||||
<a href="#opportunities">Startups</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<div class="copyright">
|
||||
<p>
|
||||
© 2026 Horizons Analysis. Based on current research and
|
||||
expert predictions.
|
||||
</p>
|
||||
</div>
|
||||
<div class="deerflow-branding">
|
||||
<a
|
||||
href="https://deerflow.tech"
|
||||
target="_blank"
|
||||
class="deerflow-link"
|
||||
>
|
||||
<span class="deerflow-icon">✦</span>
|
||||
<span class="deerflow-text">Created by Deerflow</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,187 @@
|
||||
// 2026 Horizons - Interactive Features
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Theme Toggle
|
||||
const themeToggle = document.getElementById("themeToggle");
|
||||
const themeIcon = themeToggle.querySelector("i");
|
||||
|
||||
// Check for saved theme or prefer-color-scheme
|
||||
const savedTheme = localStorage.getItem("theme");
|
||||
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
|
||||
if (savedTheme === "dark" || (!savedTheme && prefersDark)) {
|
||||
document.documentElement.setAttribute("data-theme", "dark");
|
||||
themeIcon.className = "fas fa-sun";
|
||||
}
|
||||
|
||||
themeToggle.addEventListener("click", function () {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
|
||||
if (currentTheme === "dark") {
|
||||
document.documentElement.removeAttribute("data-theme");
|
||||
themeIcon.className = "fas fa-moon";
|
||||
localStorage.setItem("theme", "light");
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", "dark");
|
||||
themeIcon.className = "fas fa-sun";
|
||||
localStorage.setItem("theme", "dark");
|
||||
}
|
||||
});
|
||||
|
||||
// Smooth scroll for navigation links
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const targetId = this.getAttribute("href");
|
||||
if (targetId === "#") return;
|
||||
|
||||
const targetElement = document.querySelector(targetId);
|
||||
if (targetElement) {
|
||||
const headerHeight = document.querySelector(".navbar").offsetHeight;
|
||||
const targetPosition = targetElement.offsetTop - headerHeight - 20;
|
||||
|
||||
window.scrollTo({
|
||||
top: targetPosition,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Navbar scroll effect
|
||||
const navbar = document.querySelector(".navbar");
|
||||
let lastScrollTop = 0;
|
||||
|
||||
window.addEventListener("scroll", function () {
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
// Hide/show navbar on scroll
|
||||
if (scrollTop > lastScrollTop && scrollTop > 100) {
|
||||
navbar.style.transform = "translateY(-100%)";
|
||||
} else {
|
||||
navbar.style.transform = "translateY(0)";
|
||||
}
|
||||
|
||||
lastScrollTop = scrollTop;
|
||||
|
||||
// Add shadow when scrolled
|
||||
if (scrollTop > 10) {
|
||||
navbar.style.boxShadow = "var(--shadow-md)";
|
||||
} else {
|
||||
navbar.style.boxShadow = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Animate elements on scroll
|
||||
const observerOptions = {
|
||||
threshold: 0.1,
|
||||
rootMargin: "0px 0px -50px 0px",
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add("fade-in");
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Observe elements to animate
|
||||
document
|
||||
.querySelectorAll(
|
||||
".trend-card, .opportunity-card, .challenge-card, .highlight-card",
|
||||
)
|
||||
.forEach((el) => {
|
||||
observer.observe(el);
|
||||
});
|
||||
|
||||
// Stats counter animation
|
||||
const stats = document.querySelectorAll(".stat-number");
|
||||
|
||||
const statsObserver = new IntersectionObserver(
|
||||
function (entries) {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const stat = entry.target;
|
||||
const targetValue = parseInt(stat.textContent);
|
||||
let currentValue = 0;
|
||||
const increment = targetValue / 50;
|
||||
const duration = 1500;
|
||||
const stepTime = Math.floor(duration / 50);
|
||||
|
||||
const timer = setInterval(() => {
|
||||
currentValue += increment;
|
||||
if (currentValue >= targetValue) {
|
||||
stat.textContent = targetValue;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
stat.textContent = Math.floor(currentValue);
|
||||
}
|
||||
}, stepTime);
|
||||
|
||||
statsObserver.unobserve(stat);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.5 },
|
||||
);
|
||||
|
||||
stats.forEach((stat) => {
|
||||
statsObserver.observe(stat);
|
||||
});
|
||||
|
||||
// Hover effects for cards
|
||||
document
|
||||
.querySelectorAll(".trend-card, .opportunity-card, .challenge-card")
|
||||
.forEach((card) => {
|
||||
card.addEventListener("mouseenter", function () {
|
||||
this.style.zIndex = "10";
|
||||
});
|
||||
|
||||
card.addEventListener("mouseleave", function () {
|
||||
this.style.zIndex = "1";
|
||||
});
|
||||
});
|
||||
|
||||
// Current year in footer
|
||||
const currentYear = new Date().getFullYear();
|
||||
const yearElement = document.querySelector(".copyright p");
|
||||
if (yearElement) {
|
||||
yearElement.textContent = yearElement.textContent.replace(
|
||||
"2026",
|
||||
currentYear,
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize animations
|
||||
setTimeout(() => {
|
||||
document.body.style.opacity = "1";
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Add CSS for initial load
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
body {
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.8s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
@@ -0,0 +1,120 @@
|
||||
# The Leica Master's Eye: Capturing the Decisive Moment in the Age of AI
|
||||
|
||||
_By DeerFlow 2.0 | January 28, 2026_
|
||||
|
||||
## The Enduring Legacy of Leica Street Photography
|
||||
|
||||
For nearly a century, the name Leica has been synonymous with street photography excellence. From Henri Cartier-Bresson's pioneering "decisive moment" to Joel Meyerowitz's vibrant color studies, Leica cameras have been the tool of choice for masters who seek to capture the poetry of everyday life. But what exactly defines the "Leica look," and can this elusive aesthetic be translated into the realm of artificial intelligence-generated imagery?
|
||||
|
||||
Through extensive research into Leica photography characteristics and careful prompt engineering, I've generated three authentic AIGC street photos that embody the spirit of Leica master photographers. These images demonstrate how AI can learn from photographic tradition while creating something entirely new.
|
||||
|
||||
## The Leica Aesthetic: More Than Just Gear
|
||||
|
||||
My research reveals several key characteristics that define Leica master photography:
|
||||
|
||||
### 1. The Decisive Moment Philosophy
|
||||
|
||||
Henri Cartier-Bresson famously described photography as "the simultaneous recognition, in a fraction of a second, of the significance of an event." This philosophy emphasizes perfect timing where all visual elements align to create meaning beyond the literal scene.
|
||||
|
||||
### 2. Rangefinder Discretion
|
||||
|
||||
Leica's compact rangefinder design allows photographers to become part of the scene rather than observers behind bulky equipment. The quiet shutter and manual focus encourage deliberate, thoughtful composition.
|
||||
|
||||
### 3. Lens Character
|
||||
|
||||
Leica lenses are renowned for their "creamy bokeh" (background blur), natural color rendering, and three-dimensional "pop." Each lens has distinct characteristics—from the clinical sharpness of Summicron lenses to the dreamy quality of Noctilux wide-open.
|
||||
|
||||
### 4. Film-Like Aesthetic
|
||||
|
||||
Even with digital Leicas, photographers often emulate film characteristics: natural grain, subtle color shifts, and a certain "organic" quality that avoids the sterile perfection of some digital photography.
|
||||
|
||||
## Three AI-Generated Leica Masterpieces
|
||||
|
||||
### Image 1: Parisian Decisive Moment
|
||||
|
||||

|
||||
|
||||
This image captures the essence of Cartier-Bresson's philosophy. A woman in a red coat leaps over a puddle while a cyclist passes in perfect synchrony. The composition follows the rule of thirds, with the subject positioned at the intersection of grid lines. Shot with a simulated Leica M11 and 35mm Summicron lens at f/2.8, the image features shallow depth of field, natural film grain, and the warm, muted color palette characteristic of Leica photography.
|
||||
|
||||
The "decisive moment" here isn't just about timing—it's about the alignment of multiple elements: the woman's motion, the cyclist's position, the reflection in the puddle, and the directional morning light creating long shadows on wet cobblestones.
|
||||
|
||||
### Image 2: Tokyo Night Reflections
|
||||
|
||||

|
||||
|
||||
Moving to Shinjuku, Tokyo, this image explores the atmospheric possibilities of Leica's legendary Noctilux lens. Simulating a Leica M10-P with a 50mm f/0.95 Noctilux wide open, the image creates extremely shallow depth of field with beautiful bokeh balls from neon signs reflected in wet pavement.
|
||||
|
||||
A salaryman waits under glowing kanji signs, steam rising from a nearby ramen shop. The composition layers foreground reflection, mid-ground subject, and background neon glow to create depth and atmosphere. The color palette emphasizes cool blues and magentas with warm convenience store yellows—a classic Tokyo night aesthetic captured with Leica's cinematic sensibility.
|
||||
|
||||
### Image 3: New York City Candid
|
||||
|
||||

|
||||
|
||||
This Chinatown scene demonstrates the documentary power of Leica's Q2 camera with its fixed 28mm Summilux lens. The wide angle captures environmental context while maintaining intimate proximity to the subjects. A fishmonger hands a live fish to a customer while tourists photograph the scene—a moment of cultural contrast and authentic urban life.
|
||||
|
||||
The 28mm perspective shows multiple layers: the transaction in foreground, tourists in mid-ground, and vibrant Chinatown signage in background. Natural afternoon light creates dappled shadows through market awnings, while steam from street food vendors adds atmospheric depth. The color rendering emphasizes the red signage and natural skin tones characteristic of Leica's color science.
|
||||
|
||||
## Technical Analysis: How AI Learned the Leica Look
|
||||
|
||||
Creating these images required careful prompt engineering based on my research:
|
||||
|
||||
### Camera and Lens Specifications
|
||||
|
||||
Each prompt specified exact equipment:
|
||||
|
||||
- **Paris**: Leica M11 with 35mm f/2 Summicron at f/2.8
|
||||
- **Tokyo**: Leica M10-P with 50mm f/0.95 Noctilux at f/0.95
|
||||
- **NYC**: Leica Q2 with fixed 28mm f/1.7 Summilux at f/2.8
|
||||
|
||||
### Film Simulation
|
||||
|
||||
Different film stocks were simulated:
|
||||
|
||||
- Kodak Portra 400 for Paris (natural skin tones, fine grain)
|
||||
- Cinestill 800T for Tokyo (halation, cinematic look)
|
||||
- Kodak Ektar 100 for NYC (vibrant colors, fine grain)
|
||||
|
||||
### Composition Principles
|
||||
|
||||
- Rule of thirds positioning
|
||||
- Environmental storytelling
|
||||
- Layers of depth (foreground, mid-ground, background)
|
||||
- Diagonal lines for dynamism
|
||||
- Negative space for breathing room
|
||||
|
||||
### Lighting Characteristics
|
||||
|
||||
- Natural, directional light sources
|
||||
- Practical lighting (neon signs, shop windows)
|
||||
- Atmospheric elements (rain, steam, smoke)
|
||||
- Time-of-day specificity (golden hour, night, afternoon)
|
||||
|
||||
## The Future of AI in Photographic Tradition
|
||||
|
||||
These images demonstrate that AI can learn from photographic masters while creating original work. The key lies in understanding the principles behind the aesthetics—not just mimicking surface characteristics.
|
||||
|
||||
### What AI Gets Right:
|
||||
|
||||
- Technical accuracy (bokeh, depth of field, grain)
|
||||
- Composition principles
|
||||
- Lighting simulation
|
||||
- Environmental storytelling
|
||||
|
||||
### What Remains Human:
|
||||
|
||||
- Intentionality and concept development
|
||||
- Emotional connection to subjects
|
||||
- Ethical considerations in street photography
|
||||
- The physical experience of being present
|
||||
|
||||
## Conclusion: A New Tool for Visual Storytelling
|
||||
|
||||
Leica master photography has always been about more than equipment—it's about vision, timing, and human connection. AI-generated imagery offers a new way to explore these principles, allowing us to visualize scenes that might be impossible to capture conventionally.
|
||||
|
||||
These three images represent a bridge between photographic tradition and computational creativity. They honor the legacy of Leica masters while demonstrating that the "decisive moment" can exist in both the physical world and the digital imagination.
|
||||
|
||||
As AI continues to evolve, the most compelling work will likely come from those who understand both the technical possibilities and the humanistic traditions that give photography its enduring power.
|
||||
|
||||
---
|
||||
|
||||
_All images generated using structured prompt engineering based on Leica photography research. Prompts available upon request._
|
||||
|
After Width: | Height: | Size: 997 KiB |
|
After Width: | Height: | Size: 855 KiB |
|
After Width: | Height: | Size: 871 KiB |
|
After Width: | Height: | Size: 788 KiB |
|
After Width: | Height: | Size: 739 KiB |
@@ -0,0 +1,35 @@
|
||||
=== TITANIC DATASET ANALYSIS SUMMARY ===
|
||||
|
||||
Dataset shape: (891, 20)
|
||||
Total passengers: 891
|
||||
Survivors: 342 (38.38%)
|
||||
|
||||
KEY FINDINGS:
|
||||
1. Gender disparity: Female survival rate was much higher than male.
|
||||
- Female: 74.20%
|
||||
- Male: 18.89%
|
||||
|
||||
2. Class disparity: Higher classes had better survival rates.
|
||||
- Class 1: 62.96% (136/216)
|
||||
- Class 2: 47.28% (87/184)
|
||||
- Class 3: 24.24% (119/491)
|
||||
|
||||
3. Children had better survival rates than adults.
|
||||
- Child (0-12): 57.97% (40/69)
|
||||
- Teen (13-18): 42.86% (30/70)
|
||||
- Young Adult (19-30): 35.56% (96/270)
|
||||
- Adult (31-50): 42.32% (102/241)
|
||||
- Senior (51+): 34.38% (22/64)
|
||||
|
||||
4. Passengers with cabins had much higher survival rates.
|
||||
- With cabin: 66.67%
|
||||
- Without cabin: 29.99%
|
||||
|
||||
5. Family size affected survival.
|
||||
- Alone: 30.35%
|
||||
- With family: 50.56%
|
||||
|
||||
6. Embarkation port correlated with survival.
|
||||
- Port C: 55.36% (93/168)
|
||||
- Port Q: 38.96% (30/77)
|
||||
- Port S: 33.70% (217/644)
|
||||
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,892 @@
|
||||
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
|
||||
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
|
||||
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
|
||||
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S
|
||||
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S
|
||||
5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S
|
||||
6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q
|
||||
7,0,1,"McCarthy, Mr. Timothy J",male,54,0,0,17463,51.8625,E46,S
|
||||
8,0,3,"Palsson, Master. Gosta Leonard",male,2,3,1,349909,21.075,,S
|
||||
9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27,0,2,347742,11.1333,,S
|
||||
10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14,1,0,237736,30.0708,,C
|
||||
11,1,3,"Sandstrom, Miss. Marguerite Rut",female,4,1,1,PP 9549,16.7,G6,S
|
||||
12,1,1,"Bonnell, Miss. Elizabeth",female,58,0,0,113783,26.55,C103,S
|
||||
13,0,3,"Saundercock, Mr. William Henry",male,20,0,0,A/5. 2151,8.05,,S
|
||||
14,0,3,"Andersson, Mr. Anders Johan",male,39,1,5,347082,31.275,,S
|
||||
15,0,3,"Vestrom, Miss. Hulda Amanda Adolfina",female,14,0,0,350406,7.8542,,S
|
||||
16,1,2,"Hewlett, Mrs. (Mary D Kingcome) ",female,55,0,0,248706,16,,S
|
||||
17,0,3,"Rice, Master. Eugene",male,2,4,1,382652,29.125,,Q
|
||||
18,1,2,"Williams, Mr. Charles Eugene",male,,0,0,244373,13,,S
|
||||
19,0,3,"Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)",female,31,1,0,345763,18,,S
|
||||
20,1,3,"Masselmani, Mrs. Fatima",female,,0,0,2649,7.225,,C
|
||||
21,0,2,"Fynney, Mr. Joseph J",male,35,0,0,239865,26,,S
|
||||
22,1,2,"Beesley, Mr. Lawrence",male,34,0,0,248698,13,D56,S
|
||||
23,1,3,"McGowan, Miss. Anna ""Annie""",female,15,0,0,330923,8.0292,,Q
|
||||
24,1,1,"Sloper, Mr. William Thompson",male,28,0,0,113788,35.5,A6,S
|
||||
25,0,3,"Palsson, Miss. Torborg Danira",female,8,3,1,349909,21.075,,S
|
||||
26,1,3,"Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)",female,38,1,5,347077,31.3875,,S
|
||||
27,0,3,"Emir, Mr. Farred Chehab",male,,0,0,2631,7.225,,C
|
||||
28,0,1,"Fortune, Mr. Charles Alexander",male,19,3,2,19950,263,C23 C25 C27,S
|
||||
29,1,3,"O'Dwyer, Miss. Ellen ""Nellie""",female,,0,0,330959,7.8792,,Q
|
||||
30,0,3,"Todoroff, Mr. Lalio",male,,0,0,349216,7.8958,,S
|
||||
31,0,1,"Uruchurtu, Don. Manuel E",male,40,0,0,PC 17601,27.7208,,C
|
||||
32,1,1,"Spencer, Mrs. William Augustus (Marie Eugenie)",female,,1,0,PC 17569,146.5208,B78,C
|
||||
33,1,3,"Glynn, Miss. Mary Agatha",female,,0,0,335677,7.75,,Q
|
||||
34,0,2,"Wheadon, Mr. Edward H",male,66,0,0,C.A. 24579,10.5,,S
|
||||
35,0,1,"Meyer, Mr. Edgar Joseph",male,28,1,0,PC 17604,82.1708,,C
|
||||
36,0,1,"Holverson, Mr. Alexander Oskar",male,42,1,0,113789,52,,S
|
||||
37,1,3,"Mamee, Mr. Hanna",male,,0,0,2677,7.2292,,C
|
||||
38,0,3,"Cann, Mr. Ernest Charles",male,21,0,0,A./5. 2152,8.05,,S
|
||||
39,0,3,"Vander Planke, Miss. Augusta Maria",female,18,2,0,345764,18,,S
|
||||
40,1,3,"Nicola-Yarred, Miss. Jamila",female,14,1,0,2651,11.2417,,C
|
||||
41,0,3,"Ahlin, Mrs. Johan (Johanna Persdotter Larsson)",female,40,1,0,7546,9.475,,S
|
||||
42,0,2,"Turpin, Mrs. William John Robert (Dorothy Ann Wonnacott)",female,27,1,0,11668,21,,S
|
||||
43,0,3,"Kraeff, Mr. Theodor",male,,0,0,349253,7.8958,,C
|
||||
44,1,2,"Laroche, Miss. Simonne Marie Anne Andree",female,3,1,2,SC/Paris 2123,41.5792,,C
|
||||
45,1,3,"Devaney, Miss. Margaret Delia",female,19,0,0,330958,7.8792,,Q
|
||||
46,0,3,"Rogers, Mr. William John",male,,0,0,S.C./A.4. 23567,8.05,,S
|
||||
47,0,3,"Lennon, Mr. Denis",male,,1,0,370371,15.5,,Q
|
||||
48,1,3,"O'Driscoll, Miss. Bridget",female,,0,0,14311,7.75,,Q
|
||||
49,0,3,"Samaan, Mr. Youssef",male,,2,0,2662,21.6792,,C
|
||||
50,0,3,"Arnold-Franchi, Mrs. Josef (Josefine Franchi)",female,18,1,0,349237,17.8,,S
|
||||
51,0,3,"Panula, Master. Juha Niilo",male,7,4,1,3101295,39.6875,,S
|
||||
52,0,3,"Nosworthy, Mr. Richard Cater",male,21,0,0,A/4. 39886,7.8,,S
|
||||
53,1,1,"Harper, Mrs. Henry Sleeper (Myna Haxtun)",female,49,1,0,PC 17572,76.7292,D33,C
|
||||
54,1,2,"Faunthorpe, Mrs. Lizzie (Elizabeth Anne Wilkinson)",female,29,1,0,2926,26,,S
|
||||
55,0,1,"Ostby, Mr. Engelhart Cornelius",male,65,0,1,113509,61.9792,B30,C
|
||||
56,1,1,"Woolner, Mr. Hugh",male,,0,0,19947,35.5,C52,S
|
||||
57,1,2,"Rugg, Miss. Emily",female,21,0,0,C.A. 31026,10.5,,S
|
||||
58,0,3,"Novel, Mr. Mansouer",male,28.5,0,0,2697,7.2292,,C
|
||||
59,1,2,"West, Miss. Constance Mirium",female,5,1,2,C.A. 34651,27.75,,S
|
||||
60,0,3,"Goodwin, Master. William Frederick",male,11,5,2,CA 2144,46.9,,S
|
||||
61,0,3,"Sirayanian, Mr. Orsen",male,22,0,0,2669,7.2292,,C
|
||||
62,1,1,"Icard, Miss. Amelie",female,38,0,0,113572,80,B28,
|
||||
63,0,1,"Harris, Mr. Henry Birkhardt",male,45,1,0,36973,83.475,C83,S
|
||||
64,0,3,"Skoog, Master. Harald",male,4,3,2,347088,27.9,,S
|
||||
65,0,1,"Stewart, Mr. Albert A",male,,0,0,PC 17605,27.7208,,C
|
||||
66,1,3,"Moubarek, Master. Gerios",male,,1,1,2661,15.2458,,C
|
||||
67,1,2,"Nye, Mrs. (Elizabeth Ramell)",female,29,0,0,C.A. 29395,10.5,F33,S
|
||||
68,0,3,"Crease, Mr. Ernest James",male,19,0,0,S.P. 3464,8.1583,,S
|
||||
69,1,3,"Andersson, Miss. Erna Alexandra",female,17,4,2,3101281,7.925,,S
|
||||
70,0,3,"Kink, Mr. Vincenz",male,26,2,0,315151,8.6625,,S
|
||||
71,0,2,"Jenkin, Mr. Stephen Curnow",male,32,0,0,C.A. 33111,10.5,,S
|
||||
72,0,3,"Goodwin, Miss. Lillian Amy",female,16,5,2,CA 2144,46.9,,S
|
||||
73,0,2,"Hood, Mr. Ambrose Jr",male,21,0,0,S.O.C. 14879,73.5,,S
|
||||
74,0,3,"Chronopoulos, Mr. Apostolos",male,26,1,0,2680,14.4542,,C
|
||||
75,1,3,"Bing, Mr. Lee",male,32,0,0,1601,56.4958,,S
|
||||
76,0,3,"Moen, Mr. Sigurd Hansen",male,25,0,0,348123,7.65,F G73,S
|
||||
77,0,3,"Staneff, Mr. Ivan",male,,0,0,349208,7.8958,,S
|
||||
78,0,3,"Moutal, Mr. Rahamin Haim",male,,0,0,374746,8.05,,S
|
||||
79,1,2,"Caldwell, Master. Alden Gates",male,0.83,0,2,248738,29,,S
|
||||
80,1,3,"Dowdell, Miss. Elizabeth",female,30,0,0,364516,12.475,,S
|
||||
81,0,3,"Waelens, Mr. Achille",male,22,0,0,345767,9,,S
|
||||
82,1,3,"Sheerlinck, Mr. Jan Baptist",male,29,0,0,345779,9.5,,S
|
||||
83,1,3,"McDermott, Miss. Brigdet Delia",female,,0,0,330932,7.7875,,Q
|
||||
84,0,1,"Carrau, Mr. Francisco M",male,28,0,0,113059,47.1,,S
|
||||
85,1,2,"Ilett, Miss. Bertha",female,17,0,0,SO/C 14885,10.5,,S
|
||||
86,1,3,"Backstrom, Mrs. Karl Alfred (Maria Mathilda Gustafsson)",female,33,3,0,3101278,15.85,,S
|
||||
87,0,3,"Ford, Mr. William Neal",male,16,1,3,W./C. 6608,34.375,,S
|
||||
88,0,3,"Slocovski, Mr. Selman Francis",male,,0,0,SOTON/OQ 392086,8.05,,S
|
||||
89,1,1,"Fortune, Miss. Mabel Helen",female,23,3,2,19950,263,C23 C25 C27,S
|
||||
90,0,3,"Celotti, Mr. Francesco",male,24,0,0,343275,8.05,,S
|
||||
91,0,3,"Christmann, Mr. Emil",male,29,0,0,343276,8.05,,S
|
||||
92,0,3,"Andreasson, Mr. Paul Edvin",male,20,0,0,347466,7.8542,,S
|
||||
93,0,1,"Chaffee, Mr. Herbert Fuller",male,46,1,0,W.E.P. 5734,61.175,E31,S
|
||||
94,0,3,"Dean, Mr. Bertram Frank",male,26,1,2,C.A. 2315,20.575,,S
|
||||
95,0,3,"Coxon, Mr. Daniel",male,59,0,0,364500,7.25,,S
|
||||
96,0,3,"Shorney, Mr. Charles Joseph",male,,0,0,374910,8.05,,S
|
||||
97,0,1,"Goldschmidt, Mr. George B",male,71,0,0,PC 17754,34.6542,A5,C
|
||||
98,1,1,"Greenfield, Mr. William Bertram",male,23,0,1,PC 17759,63.3583,D10 D12,C
|
||||
99,1,2,"Doling, Mrs. John T (Ada Julia Bone)",female,34,0,1,231919,23,,S
|
||||
100,0,2,"Kantor, Mr. Sinai",male,34,1,0,244367,26,,S
|
||||
101,0,3,"Petranec, Miss. Matilda",female,28,0,0,349245,7.8958,,S
|
||||
102,0,3,"Petroff, Mr. Pastcho (""Pentcho"")",male,,0,0,349215,7.8958,,S
|
||||
103,0,1,"White, Mr. Richard Frasar",male,21,0,1,35281,77.2875,D26,S
|
||||
104,0,3,"Johansson, Mr. Gustaf Joel",male,33,0,0,7540,8.6542,,S
|
||||
105,0,3,"Gustafsson, Mr. Anders Vilhelm",male,37,2,0,3101276,7.925,,S
|
||||
106,0,3,"Mionoff, Mr. Stoytcho",male,28,0,0,349207,7.8958,,S
|
||||
107,1,3,"Salkjelsvik, Miss. Anna Kristine",female,21,0,0,343120,7.65,,S
|
||||
108,1,3,"Moss, Mr. Albert Johan",male,,0,0,312991,7.775,,S
|
||||
109,0,3,"Rekic, Mr. Tido",male,38,0,0,349249,7.8958,,S
|
||||
110,1,3,"Moran, Miss. Bertha",female,,1,0,371110,24.15,,Q
|
||||
111,0,1,"Porter, Mr. Walter Chamberlain",male,47,0,0,110465,52,C110,S
|
||||
112,0,3,"Zabour, Miss. Hileni",female,14.5,1,0,2665,14.4542,,C
|
||||
113,0,3,"Barton, Mr. David John",male,22,0,0,324669,8.05,,S
|
||||
114,0,3,"Jussila, Miss. Katriina",female,20,1,0,4136,9.825,,S
|
||||
115,0,3,"Attalah, Miss. Malake",female,17,0,0,2627,14.4583,,C
|
||||
116,0,3,"Pekoniemi, Mr. Edvard",male,21,0,0,STON/O 2. 3101294,7.925,,S
|
||||
117,0,3,"Connors, Mr. Patrick",male,70.5,0,0,370369,7.75,,Q
|
||||
118,0,2,"Turpin, Mr. William John Robert",male,29,1,0,11668,21,,S
|
||||
119,0,1,"Baxter, Mr. Quigg Edmond",male,24,0,1,PC 17558,247.5208,B58 B60,C
|
||||
120,0,3,"Andersson, Miss. Ellis Anna Maria",female,2,4,2,347082,31.275,,S
|
||||
121,0,2,"Hickman, Mr. Stanley George",male,21,2,0,S.O.C. 14879,73.5,,S
|
||||
122,0,3,"Moore, Mr. Leonard Charles",male,,0,0,A4. 54510,8.05,,S
|
||||
123,0,2,"Nasser, Mr. Nicholas",male,32.5,1,0,237736,30.0708,,C
|
||||
124,1,2,"Webber, Miss. Susan",female,32.5,0,0,27267,13,E101,S
|
||||
125,0,1,"White, Mr. Percival Wayland",male,54,0,1,35281,77.2875,D26,S
|
||||
126,1,3,"Nicola-Yarred, Master. Elias",male,12,1,0,2651,11.2417,,C
|
||||
127,0,3,"McMahon, Mr. Martin",male,,0,0,370372,7.75,,Q
|
||||
128,1,3,"Madsen, Mr. Fridtjof Arne",male,24,0,0,C 17369,7.1417,,S
|
||||
129,1,3,"Peter, Miss. Anna",female,,1,1,2668,22.3583,F E69,C
|
||||
130,0,3,"Ekstrom, Mr. Johan",male,45,0,0,347061,6.975,,S
|
||||
131,0,3,"Drazenoic, Mr. Jozef",male,33,0,0,349241,7.8958,,C
|
||||
132,0,3,"Coelho, Mr. Domingos Fernandeo",male,20,0,0,SOTON/O.Q. 3101307,7.05,,S
|
||||
133,0,3,"Robins, Mrs. Alexander A (Grace Charity Laury)",female,47,1,0,A/5. 3337,14.5,,S
|
||||
134,1,2,"Weisz, Mrs. Leopold (Mathilde Francoise Pede)",female,29,1,0,228414,26,,S
|
||||
135,0,2,"Sobey, Mr. Samuel James Hayden",male,25,0,0,C.A. 29178,13,,S
|
||||
136,0,2,"Richard, Mr. Emile",male,23,0,0,SC/PARIS 2133,15.0458,,C
|
||||
137,1,1,"Newsom, Miss. Helen Monypeny",female,19,0,2,11752,26.2833,D47,S
|
||||
138,0,1,"Futrelle, Mr. Jacques Heath",male,37,1,0,113803,53.1,C123,S
|
||||
139,0,3,"Osen, Mr. Olaf Elon",male,16,0,0,7534,9.2167,,S
|
||||
140,0,1,"Giglio, Mr. Victor",male,24,0,0,PC 17593,79.2,B86,C
|
||||
141,0,3,"Boulos, Mrs. Joseph (Sultana)",female,,0,2,2678,15.2458,,C
|
||||
142,1,3,"Nysten, Miss. Anna Sofia",female,22,0,0,347081,7.75,,S
|
||||
143,1,3,"Hakkarainen, Mrs. Pekka Pietari (Elin Matilda Dolck)",female,24,1,0,STON/O2. 3101279,15.85,,S
|
||||
144,0,3,"Burke, Mr. Jeremiah",male,19,0,0,365222,6.75,,Q
|
||||
145,0,2,"Andrew, Mr. Edgardo Samuel",male,18,0,0,231945,11.5,,S
|
||||
146,0,2,"Nicholls, Mr. Joseph Charles",male,19,1,1,C.A. 33112,36.75,,S
|
||||
147,1,3,"Andersson, Mr. August Edvard (""Wennerstrom"")",male,27,0,0,350043,7.7958,,S
|
||||
148,0,3,"Ford, Miss. Robina Maggie ""Ruby""",female,9,2,2,W./C. 6608,34.375,,S
|
||||
149,0,2,"Navratil, Mr. Michel (""Louis M Hoffman"")",male,36.5,0,2,230080,26,F2,S
|
||||
150,0,2,"Byles, Rev. Thomas Roussel Davids",male,42,0,0,244310,13,,S
|
||||
151,0,2,"Bateman, Rev. Robert James",male,51,0,0,S.O.P. 1166,12.525,,S
|
||||
152,1,1,"Pears, Mrs. Thomas (Edith Wearne)",female,22,1,0,113776,66.6,C2,S
|
||||
153,0,3,"Meo, Mr. Alfonzo",male,55.5,0,0,A.5. 11206,8.05,,S
|
||||
154,0,3,"van Billiard, Mr. Austin Blyler",male,40.5,0,2,A/5. 851,14.5,,S
|
||||
155,0,3,"Olsen, Mr. Ole Martin",male,,0,0,Fa 265302,7.3125,,S
|
||||
156,0,1,"Williams, Mr. Charles Duane",male,51,0,1,PC 17597,61.3792,,C
|
||||
157,1,3,"Gilnagh, Miss. Katherine ""Katie""",female,16,0,0,35851,7.7333,,Q
|
||||
158,0,3,"Corn, Mr. Harry",male,30,0,0,SOTON/OQ 392090,8.05,,S
|
||||
159,0,3,"Smiljanic, Mr. Mile",male,,0,0,315037,8.6625,,S
|
||||
160,0,3,"Sage, Master. Thomas Henry",male,,8,2,CA. 2343,69.55,,S
|
||||
161,0,3,"Cribb, Mr. John Hatfield",male,44,0,1,371362,16.1,,S
|
||||
162,1,2,"Watt, Mrs. James (Elizabeth ""Bessie"" Inglis Milne)",female,40,0,0,C.A. 33595,15.75,,S
|
||||
163,0,3,"Bengtsson, Mr. John Viktor",male,26,0,0,347068,7.775,,S
|
||||
164,0,3,"Calic, Mr. Jovo",male,17,0,0,315093,8.6625,,S
|
||||
165,0,3,"Panula, Master. Eino Viljami",male,1,4,1,3101295,39.6875,,S
|
||||
166,1,3,"Goldsmith, Master. Frank John William ""Frankie""",male,9,0,2,363291,20.525,,S
|
||||
167,1,1,"Chibnall, Mrs. (Edith Martha Bowerman)",female,,0,1,113505,55,E33,S
|
||||
168,0,3,"Skoog, Mrs. William (Anna Bernhardina Karlsson)",female,45,1,4,347088,27.9,,S
|
||||
169,0,1,"Baumann, Mr. John D",male,,0,0,PC 17318,25.925,,S
|
||||
170,0,3,"Ling, Mr. Lee",male,28,0,0,1601,56.4958,,S
|
||||
171,0,1,"Van der hoef, Mr. Wyckoff",male,61,0,0,111240,33.5,B19,S
|
||||
172,0,3,"Rice, Master. Arthur",male,4,4,1,382652,29.125,,Q
|
||||
173,1,3,"Johnson, Miss. Eleanor Ileen",female,1,1,1,347742,11.1333,,S
|
||||
174,0,3,"Sivola, Mr. Antti Wilhelm",male,21,0,0,STON/O 2. 3101280,7.925,,S
|
||||
175,0,1,"Smith, Mr. James Clinch",male,56,0,0,17764,30.6958,A7,C
|
||||
176,0,3,"Klasen, Mr. Klas Albin",male,18,1,1,350404,7.8542,,S
|
||||
177,0,3,"Lefebre, Master. Henry Forbes",male,,3,1,4133,25.4667,,S
|
||||
178,0,1,"Isham, Miss. Ann Elizabeth",female,50,0,0,PC 17595,28.7125,C49,C
|
||||
179,0,2,"Hale, Mr. Reginald",male,30,0,0,250653,13,,S
|
||||
180,0,3,"Leonard, Mr. Lionel",male,36,0,0,LINE,0,,S
|
||||
181,0,3,"Sage, Miss. Constance Gladys",female,,8,2,CA. 2343,69.55,,S
|
||||
182,0,2,"Pernot, Mr. Rene",male,,0,0,SC/PARIS 2131,15.05,,C
|
||||
183,0,3,"Asplund, Master. Clarence Gustaf Hugo",male,9,4,2,347077,31.3875,,S
|
||||
184,1,2,"Becker, Master. Richard F",male,1,2,1,230136,39,F4,S
|
||||
185,1,3,"Kink-Heilmann, Miss. Luise Gretchen",female,4,0,2,315153,22.025,,S
|
||||
186,0,1,"Rood, Mr. Hugh Roscoe",male,,0,0,113767,50,A32,S
|
||||
187,1,3,"O'Brien, Mrs. Thomas (Johanna ""Hannah"" Godfrey)",female,,1,0,370365,15.5,,Q
|
||||
188,1,1,"Romaine, Mr. Charles Hallace (""Mr C Rolmane"")",male,45,0,0,111428,26.55,,S
|
||||
189,0,3,"Bourke, Mr. John",male,40,1,1,364849,15.5,,Q
|
||||
190,0,3,"Turcin, Mr. Stjepan",male,36,0,0,349247,7.8958,,S
|
||||
191,1,2,"Pinsky, Mrs. (Rosa)",female,32,0,0,234604,13,,S
|
||||
192,0,2,"Carbines, Mr. William",male,19,0,0,28424,13,,S
|
||||
193,1,3,"Andersen-Jensen, Miss. Carla Christine Nielsine",female,19,1,0,350046,7.8542,,S
|
||||
194,1,2,"Navratil, Master. Michel M",male,3,1,1,230080,26,F2,S
|
||||
195,1,1,"Brown, Mrs. James Joseph (Margaret Tobin)",female,44,0,0,PC 17610,27.7208,B4,C
|
||||
196,1,1,"Lurette, Miss. Elise",female,58,0,0,PC 17569,146.5208,B80,C
|
||||
197,0,3,"Mernagh, Mr. Robert",male,,0,0,368703,7.75,,Q
|
||||
198,0,3,"Olsen, Mr. Karl Siegwart Andreas",male,42,0,1,4579,8.4042,,S
|
||||
199,1,3,"Madigan, Miss. Margaret ""Maggie""",female,,0,0,370370,7.75,,Q
|
||||
200,0,2,"Yrois, Miss. Henriette (""Mrs Harbeck"")",female,24,0,0,248747,13,,S
|
||||
201,0,3,"Vande Walle, Mr. Nestor Cyriel",male,28,0,0,345770,9.5,,S
|
||||
202,0,3,"Sage, Mr. Frederick",male,,8,2,CA. 2343,69.55,,S
|
||||
203,0,3,"Johanson, Mr. Jakob Alfred",male,34,0,0,3101264,6.4958,,S
|
||||
204,0,3,"Youseff, Mr. Gerious",male,45.5,0,0,2628,7.225,,C
|
||||
205,1,3,"Cohen, Mr. Gurshon ""Gus""",male,18,0,0,A/5 3540,8.05,,S
|
||||
206,0,3,"Strom, Miss. Telma Matilda",female,2,0,1,347054,10.4625,G6,S
|
||||
207,0,3,"Backstrom, Mr. Karl Alfred",male,32,1,0,3101278,15.85,,S
|
||||
208,1,3,"Albimona, Mr. Nassef Cassem",male,26,0,0,2699,18.7875,,C
|
||||
209,1,3,"Carr, Miss. Helen ""Ellen""",female,16,0,0,367231,7.75,,Q
|
||||
210,1,1,"Blank, Mr. Henry",male,40,0,0,112277,31,A31,C
|
||||
211,0,3,"Ali, Mr. Ahmed",male,24,0,0,SOTON/O.Q. 3101311,7.05,,S
|
||||
212,1,2,"Cameron, Miss. Clear Annie",female,35,0,0,F.C.C. 13528,21,,S
|
||||
213,0,3,"Perkin, Mr. John Henry",male,22,0,0,A/5 21174,7.25,,S
|
||||
214,0,2,"Givard, Mr. Hans Kristensen",male,30,0,0,250646,13,,S
|
||||
215,0,3,"Kiernan, Mr. Philip",male,,1,0,367229,7.75,,Q
|
||||
216,1,1,"Newell, Miss. Madeleine",female,31,1,0,35273,113.275,D36,C
|
||||
217,1,3,"Honkanen, Miss. Eliina",female,27,0,0,STON/O2. 3101283,7.925,,S
|
||||
218,0,2,"Jacobsohn, Mr. Sidney Samuel",male,42,1,0,243847,27,,S
|
||||
219,1,1,"Bazzani, Miss. Albina",female,32,0,0,11813,76.2917,D15,C
|
||||
220,0,2,"Harris, Mr. Walter",male,30,0,0,W/C 14208,10.5,,S
|
||||
221,1,3,"Sunderland, Mr. Victor Francis",male,16,0,0,SOTON/OQ 392089,8.05,,S
|
||||
222,0,2,"Bracken, Mr. James H",male,27,0,0,220367,13,,S
|
||||
223,0,3,"Green, Mr. George Henry",male,51,0,0,21440,8.05,,S
|
||||
224,0,3,"Nenkoff, Mr. Christo",male,,0,0,349234,7.8958,,S
|
||||
225,1,1,"Hoyt, Mr. Frederick Maxfield",male,38,1,0,19943,90,C93,S
|
||||
226,0,3,"Berglund, Mr. Karl Ivar Sven",male,22,0,0,PP 4348,9.35,,S
|
||||
227,1,2,"Mellors, Mr. William John",male,19,0,0,SW/PP 751,10.5,,S
|
||||
228,0,3,"Lovell, Mr. John Hall (""Henry"")",male,20.5,0,0,A/5 21173,7.25,,S
|
||||
229,0,2,"Fahlstrom, Mr. Arne Jonas",male,18,0,0,236171,13,,S
|
||||
230,0,3,"Lefebre, Miss. Mathilde",female,,3,1,4133,25.4667,,S
|
||||
231,1,1,"Harris, Mrs. Henry Birkhardt (Irene Wallach)",female,35,1,0,36973,83.475,C83,S
|
||||
232,0,3,"Larsson, Mr. Bengt Edvin",male,29,0,0,347067,7.775,,S
|
||||
233,0,2,"Sjostedt, Mr. Ernst Adolf",male,59,0,0,237442,13.5,,S
|
||||
234,1,3,"Asplund, Miss. Lillian Gertrud",female,5,4,2,347077,31.3875,,S
|
||||
235,0,2,"Leyson, Mr. Robert William Norman",male,24,0,0,C.A. 29566,10.5,,S
|
||||
236,0,3,"Harknett, Miss. Alice Phoebe",female,,0,0,W./C. 6609,7.55,,S
|
||||
237,0,2,"Hold, Mr. Stephen",male,44,1,0,26707,26,,S
|
||||
238,1,2,"Collyer, Miss. Marjorie ""Lottie""",female,8,0,2,C.A. 31921,26.25,,S
|
||||
239,0,2,"Pengelly, Mr. Frederick William",male,19,0,0,28665,10.5,,S
|
||||
240,0,2,"Hunt, Mr. George Henry",male,33,0,0,SCO/W 1585,12.275,,S
|
||||
241,0,3,"Zabour, Miss. Thamine",female,,1,0,2665,14.4542,,C
|
||||
242,1,3,"Murphy, Miss. Katherine ""Kate""",female,,1,0,367230,15.5,,Q
|
||||
243,0,2,"Coleridge, Mr. Reginald Charles",male,29,0,0,W./C. 14263,10.5,,S
|
||||
244,0,3,"Maenpaa, Mr. Matti Alexanteri",male,22,0,0,STON/O 2. 3101275,7.125,,S
|
||||
245,0,3,"Attalah, Mr. Sleiman",male,30,0,0,2694,7.225,,C
|
||||
246,0,1,"Minahan, Dr. William Edward",male,44,2,0,19928,90,C78,Q
|
||||
247,0,3,"Lindahl, Miss. Agda Thorilda Viktoria",female,25,0,0,347071,7.775,,S
|
||||
248,1,2,"Hamalainen, Mrs. William (Anna)",female,24,0,2,250649,14.5,,S
|
||||
249,1,1,"Beckwith, Mr. Richard Leonard",male,37,1,1,11751,52.5542,D35,S
|
||||
250,0,2,"Carter, Rev. Ernest Courtenay",male,54,1,0,244252,26,,S
|
||||
251,0,3,"Reed, Mr. James George",male,,0,0,362316,7.25,,S
|
||||
252,0,3,"Strom, Mrs. Wilhelm (Elna Matilda Persson)",female,29,1,1,347054,10.4625,G6,S
|
||||
253,0,1,"Stead, Mr. William Thomas",male,62,0,0,113514,26.55,C87,S
|
||||
254,0,3,"Lobb, Mr. William Arthur",male,30,1,0,A/5. 3336,16.1,,S
|
||||
255,0,3,"Rosblom, Mrs. Viktor (Helena Wilhelmina)",female,41,0,2,370129,20.2125,,S
|
||||
256,1,3,"Touma, Mrs. Darwis (Hanne Youssef Razi)",female,29,0,2,2650,15.2458,,C
|
||||
257,1,1,"Thorne, Mrs. Gertrude Maybelle",female,,0,0,PC 17585,79.2,,C
|
||||
258,1,1,"Cherry, Miss. Gladys",female,30,0,0,110152,86.5,B77,S
|
||||
259,1,1,"Ward, Miss. Anna",female,35,0,0,PC 17755,512.3292,,C
|
||||
260,1,2,"Parrish, Mrs. (Lutie Davis)",female,50,0,1,230433,26,,S
|
||||
261,0,3,"Smith, Mr. Thomas",male,,0,0,384461,7.75,,Q
|
||||
262,1,3,"Asplund, Master. Edvin Rojj Felix",male,3,4,2,347077,31.3875,,S
|
||||
263,0,1,"Taussig, Mr. Emil",male,52,1,1,110413,79.65,E67,S
|
||||
264,0,1,"Harrison, Mr. William",male,40,0,0,112059,0,B94,S
|
||||
265,0,3,"Henry, Miss. Delia",female,,0,0,382649,7.75,,Q
|
||||
266,0,2,"Reeves, Mr. David",male,36,0,0,C.A. 17248,10.5,,S
|
||||
267,0,3,"Panula, Mr. Ernesti Arvid",male,16,4,1,3101295,39.6875,,S
|
||||
268,1,3,"Persson, Mr. Ernst Ulrik",male,25,1,0,347083,7.775,,S
|
||||
269,1,1,"Graham, Mrs. William Thompson (Edith Junkins)",female,58,0,1,PC 17582,153.4625,C125,S
|
||||
270,1,1,"Bissette, Miss. Amelia",female,35,0,0,PC 17760,135.6333,C99,S
|
||||
271,0,1,"Cairns, Mr. Alexander",male,,0,0,113798,31,,S
|
||||
272,1,3,"Tornquist, Mr. William Henry",male,25,0,0,LINE,0,,S
|
||||
273,1,2,"Mellinger, Mrs. (Elizabeth Anne Maidment)",female,41,0,1,250644,19.5,,S
|
||||
274,0,1,"Natsch, Mr. Charles H",male,37,0,1,PC 17596,29.7,C118,C
|
||||
275,1,3,"Healy, Miss. Hanora ""Nora""",female,,0,0,370375,7.75,,Q
|
||||
276,1,1,"Andrews, Miss. Kornelia Theodosia",female,63,1,0,13502,77.9583,D7,S
|
||||
277,0,3,"Lindblom, Miss. Augusta Charlotta",female,45,0,0,347073,7.75,,S
|
||||
278,0,2,"Parkes, Mr. Francis ""Frank""",male,,0,0,239853,0,,S
|
||||
279,0,3,"Rice, Master. Eric",male,7,4,1,382652,29.125,,Q
|
||||
280,1,3,"Abbott, Mrs. Stanton (Rosa Hunt)",female,35,1,1,C.A. 2673,20.25,,S
|
||||
281,0,3,"Duane, Mr. Frank",male,65,0,0,336439,7.75,,Q
|
||||
282,0,3,"Olsson, Mr. Nils Johan Goransson",male,28,0,0,347464,7.8542,,S
|
||||
283,0,3,"de Pelsmaeker, Mr. Alfons",male,16,0,0,345778,9.5,,S
|
||||
284,1,3,"Dorking, Mr. Edward Arthur",male,19,0,0,A/5. 10482,8.05,,S
|
||||
285,0,1,"Smith, Mr. Richard William",male,,0,0,113056,26,A19,S
|
||||
286,0,3,"Stankovic, Mr. Ivan",male,33,0,0,349239,8.6625,,C
|
||||
287,1,3,"de Mulder, Mr. Theodore",male,30,0,0,345774,9.5,,S
|
||||
288,0,3,"Naidenoff, Mr. Penko",male,22,0,0,349206,7.8958,,S
|
||||
289,1,2,"Hosono, Mr. Masabumi",male,42,0,0,237798,13,,S
|
||||
290,1,3,"Connolly, Miss. Kate",female,22,0,0,370373,7.75,,Q
|
||||
291,1,1,"Barber, Miss. Ellen ""Nellie""",female,26,0,0,19877,78.85,,S
|
||||
292,1,1,"Bishop, Mrs. Dickinson H (Helen Walton)",female,19,1,0,11967,91.0792,B49,C
|
||||
293,0,2,"Levy, Mr. Rene Jacques",male,36,0,0,SC/Paris 2163,12.875,D,C
|
||||
294,0,3,"Haas, Miss. Aloisia",female,24,0,0,349236,8.85,,S
|
||||
295,0,3,"Mineff, Mr. Ivan",male,24,0,0,349233,7.8958,,S
|
||||
296,0,1,"Lewy, Mr. Ervin G",male,,0,0,PC 17612,27.7208,,C
|
||||
297,0,3,"Hanna, Mr. Mansour",male,23.5,0,0,2693,7.2292,,C
|
||||
298,0,1,"Allison, Miss. Helen Loraine",female,2,1,2,113781,151.55,C22 C26,S
|
||||
299,1,1,"Saalfeld, Mr. Adolphe",male,,0,0,19988,30.5,C106,S
|
||||
300,1,1,"Baxter, Mrs. James (Helene DeLaudeniere Chaput)",female,50,0,1,PC 17558,247.5208,B58 B60,C
|
||||
301,1,3,"Kelly, Miss. Anna Katherine ""Annie Kate""",female,,0,0,9234,7.75,,Q
|
||||
302,1,3,"McCoy, Mr. Bernard",male,,2,0,367226,23.25,,Q
|
||||
303,0,3,"Johnson, Mr. William Cahoone Jr",male,19,0,0,LINE,0,,S
|
||||
304,1,2,"Keane, Miss. Nora A",female,,0,0,226593,12.35,E101,Q
|
||||
305,0,3,"Williams, Mr. Howard Hugh ""Harry""",male,,0,0,A/5 2466,8.05,,S
|
||||
306,1,1,"Allison, Master. Hudson Trevor",male,0.92,1,2,113781,151.55,C22 C26,S
|
||||
307,1,1,"Fleming, Miss. Margaret",female,,0,0,17421,110.8833,,C
|
||||
308,1,1,"Penasco y Castellana, Mrs. Victor de Satode (Maria Josefa Perez de Soto y Vallejo)",female,17,1,0,PC 17758,108.9,C65,C
|
||||
309,0,2,"Abelson, Mr. Samuel",male,30,1,0,P/PP 3381,24,,C
|
||||
310,1,1,"Francatelli, Miss. Laura Mabel",female,30,0,0,PC 17485,56.9292,E36,C
|
||||
311,1,1,"Hays, Miss. Margaret Bechstein",female,24,0,0,11767,83.1583,C54,C
|
||||
312,1,1,"Ryerson, Miss. Emily Borie",female,18,2,2,PC 17608,262.375,B57 B59 B63 B66,C
|
||||
313,0,2,"Lahtinen, Mrs. William (Anna Sylfven)",female,26,1,1,250651,26,,S
|
||||
314,0,3,"Hendekovic, Mr. Ignjac",male,28,0,0,349243,7.8958,,S
|
||||
315,0,2,"Hart, Mr. Benjamin",male,43,1,1,F.C.C. 13529,26.25,,S
|
||||
316,1,3,"Nilsson, Miss. Helmina Josefina",female,26,0,0,347470,7.8542,,S
|
||||
317,1,2,"Kantor, Mrs. Sinai (Miriam Sternin)",female,24,1,0,244367,26,,S
|
||||
318,0,2,"Moraweck, Dr. Ernest",male,54,0,0,29011,14,,S
|
||||
319,1,1,"Wick, Miss. Mary Natalie",female,31,0,2,36928,164.8667,C7,S
|
||||
320,1,1,"Spedden, Mrs. Frederic Oakley (Margaretta Corning Stone)",female,40,1,1,16966,134.5,E34,C
|
||||
321,0,3,"Dennis, Mr. Samuel",male,22,0,0,A/5 21172,7.25,,S
|
||||
322,0,3,"Danoff, Mr. Yoto",male,27,0,0,349219,7.8958,,S
|
||||
323,1,2,"Slayter, Miss. Hilda Mary",female,30,0,0,234818,12.35,,Q
|
||||
324,1,2,"Caldwell, Mrs. Albert Francis (Sylvia Mae Harbaugh)",female,22,1,1,248738,29,,S
|
||||
325,0,3,"Sage, Mr. George John Jr",male,,8,2,CA. 2343,69.55,,S
|
||||
326,1,1,"Young, Miss. Marie Grice",female,36,0,0,PC 17760,135.6333,C32,C
|
||||
327,0,3,"Nysveen, Mr. Johan Hansen",male,61,0,0,345364,6.2375,,S
|
||||
328,1,2,"Ball, Mrs. (Ada E Hall)",female,36,0,0,28551,13,D,S
|
||||
329,1,3,"Goldsmith, Mrs. Frank John (Emily Alice Brown)",female,31,1,1,363291,20.525,,S
|
||||
330,1,1,"Hippach, Miss. Jean Gertrude",female,16,0,1,111361,57.9792,B18,C
|
||||
331,1,3,"McCoy, Miss. Agnes",female,,2,0,367226,23.25,,Q
|
||||
332,0,1,"Partner, Mr. Austen",male,45.5,0,0,113043,28.5,C124,S
|
||||
333,0,1,"Graham, Mr. George Edward",male,38,0,1,PC 17582,153.4625,C91,S
|
||||
334,0,3,"Vander Planke, Mr. Leo Edmondus",male,16,2,0,345764,18,,S
|
||||
335,1,1,"Frauenthal, Mrs. Henry William (Clara Heinsheimer)",female,,1,0,PC 17611,133.65,,S
|
||||
336,0,3,"Denkoff, Mr. Mitto",male,,0,0,349225,7.8958,,S
|
||||
337,0,1,"Pears, Mr. Thomas Clinton",male,29,1,0,113776,66.6,C2,S
|
||||
338,1,1,"Burns, Miss. Elizabeth Margaret",female,41,0,0,16966,134.5,E40,C
|
||||
339,1,3,"Dahl, Mr. Karl Edwart",male,45,0,0,7598,8.05,,S
|
||||
340,0,1,"Blackwell, Mr. Stephen Weart",male,45,0,0,113784,35.5,T,S
|
||||
341,1,2,"Navratil, Master. Edmond Roger",male,2,1,1,230080,26,F2,S
|
||||
342,1,1,"Fortune, Miss. Alice Elizabeth",female,24,3,2,19950,263,C23 C25 C27,S
|
||||
343,0,2,"Collander, Mr. Erik Gustaf",male,28,0,0,248740,13,,S
|
||||
344,0,2,"Sedgwick, Mr. Charles Frederick Waddington",male,25,0,0,244361,13,,S
|
||||
345,0,2,"Fox, Mr. Stanley Hubert",male,36,0,0,229236,13,,S
|
||||
346,1,2,"Brown, Miss. Amelia ""Mildred""",female,24,0,0,248733,13,F33,S
|
||||
347,1,2,"Smith, Miss. Marion Elsie",female,40,0,0,31418,13,,S
|
||||
348,1,3,"Davison, Mrs. Thomas Henry (Mary E Finck)",female,,1,0,386525,16.1,,S
|
||||
349,1,3,"Coutts, Master. William Loch ""William""",male,3,1,1,C.A. 37671,15.9,,S
|
||||
350,0,3,"Dimic, Mr. Jovan",male,42,0,0,315088,8.6625,,S
|
||||
351,0,3,"Odahl, Mr. Nils Martin",male,23,0,0,7267,9.225,,S
|
||||
352,0,1,"Williams-Lambert, Mr. Fletcher Fellows",male,,0,0,113510,35,C128,S
|
||||
353,0,3,"Elias, Mr. Tannous",male,15,1,1,2695,7.2292,,C
|
||||
354,0,3,"Arnold-Franchi, Mr. Josef",male,25,1,0,349237,17.8,,S
|
||||
355,0,3,"Yousif, Mr. Wazli",male,,0,0,2647,7.225,,C
|
||||
356,0,3,"Vanden Steen, Mr. Leo Peter",male,28,0,0,345783,9.5,,S
|
||||
357,1,1,"Bowerman, Miss. Elsie Edith",female,22,0,1,113505,55,E33,S
|
||||
358,0,2,"Funk, Miss. Annie Clemmer",female,38,0,0,237671,13,,S
|
||||
359,1,3,"McGovern, Miss. Mary",female,,0,0,330931,7.8792,,Q
|
||||
360,1,3,"Mockler, Miss. Helen Mary ""Ellie""",female,,0,0,330980,7.8792,,Q
|
||||
361,0,3,"Skoog, Mr. Wilhelm",male,40,1,4,347088,27.9,,S
|
||||
362,0,2,"del Carlo, Mr. Sebastiano",male,29,1,0,SC/PARIS 2167,27.7208,,C
|
||||
363,0,3,"Barbara, Mrs. (Catherine David)",female,45,0,1,2691,14.4542,,C
|
||||
364,0,3,"Asim, Mr. Adola",male,35,0,0,SOTON/O.Q. 3101310,7.05,,S
|
||||
365,0,3,"O'Brien, Mr. Thomas",male,,1,0,370365,15.5,,Q
|
||||
366,0,3,"Adahl, Mr. Mauritz Nils Martin",male,30,0,0,C 7076,7.25,,S
|
||||
367,1,1,"Warren, Mrs. Frank Manley (Anna Sophia Atkinson)",female,60,1,0,110813,75.25,D37,C
|
||||
368,1,3,"Moussa, Mrs. (Mantoura Boulos)",female,,0,0,2626,7.2292,,C
|
||||
369,1,3,"Jermyn, Miss. Annie",female,,0,0,14313,7.75,,Q
|
||||
370,1,1,"Aubart, Mme. Leontine Pauline",female,24,0,0,PC 17477,69.3,B35,C
|
||||
371,1,1,"Harder, Mr. George Achilles",male,25,1,0,11765,55.4417,E50,C
|
||||
372,0,3,"Wiklund, Mr. Jakob Alfred",male,18,1,0,3101267,6.4958,,S
|
||||
373,0,3,"Beavan, Mr. William Thomas",male,19,0,0,323951,8.05,,S
|
||||
374,0,1,"Ringhini, Mr. Sante",male,22,0,0,PC 17760,135.6333,,C
|
||||
375,0,3,"Palsson, Miss. Stina Viola",female,3,3,1,349909,21.075,,S
|
||||
376,1,1,"Meyer, Mrs. Edgar Joseph (Leila Saks)",female,,1,0,PC 17604,82.1708,,C
|
||||
377,1,3,"Landergren, Miss. Aurora Adelia",female,22,0,0,C 7077,7.25,,S
|
||||
378,0,1,"Widener, Mr. Harry Elkins",male,27,0,2,113503,211.5,C82,C
|
||||
379,0,3,"Betros, Mr. Tannous",male,20,0,0,2648,4.0125,,C
|
||||
380,0,3,"Gustafsson, Mr. Karl Gideon",male,19,0,0,347069,7.775,,S
|
||||
381,1,1,"Bidois, Miss. Rosalie",female,42,0,0,PC 17757,227.525,,C
|
||||
382,1,3,"Nakid, Miss. Maria (""Mary"")",female,1,0,2,2653,15.7417,,C
|
||||
383,0,3,"Tikkanen, Mr. Juho",male,32,0,0,STON/O 2. 3101293,7.925,,S
|
||||
384,1,1,"Holverson, Mrs. Alexander Oskar (Mary Aline Towner)",female,35,1,0,113789,52,,S
|
||||
385,0,3,"Plotcharsky, Mr. Vasil",male,,0,0,349227,7.8958,,S
|
||||
386,0,2,"Davies, Mr. Charles Henry",male,18,0,0,S.O.C. 14879,73.5,,S
|
||||
387,0,3,"Goodwin, Master. Sidney Leonard",male,1,5,2,CA 2144,46.9,,S
|
||||
388,1,2,"Buss, Miss. Kate",female,36,0,0,27849,13,,S
|
||||
389,0,3,"Sadlier, Mr. Matthew",male,,0,0,367655,7.7292,,Q
|
||||
390,1,2,"Lehmann, Miss. Bertha",female,17,0,0,SC 1748,12,,C
|
||||
391,1,1,"Carter, Mr. William Ernest",male,36,1,2,113760,120,B96 B98,S
|
||||
392,1,3,"Jansson, Mr. Carl Olof",male,21,0,0,350034,7.7958,,S
|
||||
393,0,3,"Gustafsson, Mr. Johan Birger",male,28,2,0,3101277,7.925,,S
|
||||
394,1,1,"Newell, Miss. Marjorie",female,23,1,0,35273,113.275,D36,C
|
||||
395,1,3,"Sandstrom, Mrs. Hjalmar (Agnes Charlotta Bengtsson)",female,24,0,2,PP 9549,16.7,G6,S
|
||||
396,0,3,"Johansson, Mr. Erik",male,22,0,0,350052,7.7958,,S
|
||||
397,0,3,"Olsson, Miss. Elina",female,31,0,0,350407,7.8542,,S
|
||||
398,0,2,"McKane, Mr. Peter David",male,46,0,0,28403,26,,S
|
||||
399,0,2,"Pain, Dr. Alfred",male,23,0,0,244278,10.5,,S
|
||||
400,1,2,"Trout, Mrs. William H (Jessie L)",female,28,0,0,240929,12.65,,S
|
||||
401,1,3,"Niskanen, Mr. Juha",male,39,0,0,STON/O 2. 3101289,7.925,,S
|
||||
402,0,3,"Adams, Mr. John",male,26,0,0,341826,8.05,,S
|
||||
403,0,3,"Jussila, Miss. Mari Aina",female,21,1,0,4137,9.825,,S
|
||||
404,0,3,"Hakkarainen, Mr. Pekka Pietari",male,28,1,0,STON/O2. 3101279,15.85,,S
|
||||
405,0,3,"Oreskovic, Miss. Marija",female,20,0,0,315096,8.6625,,S
|
||||
406,0,2,"Gale, Mr. Shadrach",male,34,1,0,28664,21,,S
|
||||
407,0,3,"Widegren, Mr. Carl/Charles Peter",male,51,0,0,347064,7.75,,S
|
||||
408,1,2,"Richards, Master. William Rowe",male,3,1,1,29106,18.75,,S
|
||||
409,0,3,"Birkeland, Mr. Hans Martin Monsen",male,21,0,0,312992,7.775,,S
|
||||
410,0,3,"Lefebre, Miss. Ida",female,,3,1,4133,25.4667,,S
|
||||
411,0,3,"Sdycoff, Mr. Todor",male,,0,0,349222,7.8958,,S
|
||||
412,0,3,"Hart, Mr. Henry",male,,0,0,394140,6.8583,,Q
|
||||
413,1,1,"Minahan, Miss. Daisy E",female,33,1,0,19928,90,C78,Q
|
||||
414,0,2,"Cunningham, Mr. Alfred Fleming",male,,0,0,239853,0,,S
|
||||
415,1,3,"Sundman, Mr. Johan Julian",male,44,0,0,STON/O 2. 3101269,7.925,,S
|
||||
416,0,3,"Meek, Mrs. Thomas (Annie Louise Rowley)",female,,0,0,343095,8.05,,S
|
||||
417,1,2,"Drew, Mrs. James Vivian (Lulu Thorne Christian)",female,34,1,1,28220,32.5,,S
|
||||
418,1,2,"Silven, Miss. Lyyli Karoliina",female,18,0,2,250652,13,,S
|
||||
419,0,2,"Matthews, Mr. William John",male,30,0,0,28228,13,,S
|
||||
420,0,3,"Van Impe, Miss. Catharina",female,10,0,2,345773,24.15,,S
|
||||
421,0,3,"Gheorgheff, Mr. Stanio",male,,0,0,349254,7.8958,,C
|
||||
422,0,3,"Charters, Mr. David",male,21,0,0,A/5. 13032,7.7333,,Q
|
||||
423,0,3,"Zimmerman, Mr. Leo",male,29,0,0,315082,7.875,,S
|
||||
424,0,3,"Danbom, Mrs. Ernst Gilbert (Anna Sigrid Maria Brogren)",female,28,1,1,347080,14.4,,S
|
||||
425,0,3,"Rosblom, Mr. Viktor Richard",male,18,1,1,370129,20.2125,,S
|
||||
426,0,3,"Wiseman, Mr. Phillippe",male,,0,0,A/4. 34244,7.25,,S
|
||||
427,1,2,"Clarke, Mrs. Charles V (Ada Maria Winfield)",female,28,1,0,2003,26,,S
|
||||
428,1,2,"Phillips, Miss. Kate Florence (""Mrs Kate Louise Phillips Marshall"")",female,19,0,0,250655,26,,S
|
||||
429,0,3,"Flynn, Mr. James",male,,0,0,364851,7.75,,Q
|
||||
430,1,3,"Pickard, Mr. Berk (Berk Trembisky)",male,32,0,0,SOTON/O.Q. 392078,8.05,E10,S
|
||||
431,1,1,"Bjornstrom-Steffansson, Mr. Mauritz Hakan",male,28,0,0,110564,26.55,C52,S
|
||||
432,1,3,"Thorneycroft, Mrs. Percival (Florence Kate White)",female,,1,0,376564,16.1,,S
|
||||
433,1,2,"Louch, Mrs. Charles Alexander (Alice Adelaide Slow)",female,42,1,0,SC/AH 3085,26,,S
|
||||
434,0,3,"Kallio, Mr. Nikolai Erland",male,17,0,0,STON/O 2. 3101274,7.125,,S
|
||||
435,0,1,"Silvey, Mr. William Baird",male,50,1,0,13507,55.9,E44,S
|
||||
436,1,1,"Carter, Miss. Lucile Polk",female,14,1,2,113760,120,B96 B98,S
|
||||
437,0,3,"Ford, Miss. Doolina Margaret ""Daisy""",female,21,2,2,W./C. 6608,34.375,,S
|
||||
438,1,2,"Richards, Mrs. Sidney (Emily Hocking)",female,24,2,3,29106,18.75,,S
|
||||
439,0,1,"Fortune, Mr. Mark",male,64,1,4,19950,263,C23 C25 C27,S
|
||||
440,0,2,"Kvillner, Mr. Johan Henrik Johannesson",male,31,0,0,C.A. 18723,10.5,,S
|
||||
441,1,2,"Hart, Mrs. Benjamin (Esther Ada Bloomfield)",female,45,1,1,F.C.C. 13529,26.25,,S
|
||||
442,0,3,"Hampe, Mr. Leon",male,20,0,0,345769,9.5,,S
|
||||
443,0,3,"Petterson, Mr. Johan Emil",male,25,1,0,347076,7.775,,S
|
||||
444,1,2,"Reynaldo, Ms. Encarnacion",female,28,0,0,230434,13,,S
|
||||
445,1,3,"Johannesen-Bratthammer, Mr. Bernt",male,,0,0,65306,8.1125,,S
|
||||
446,1,1,"Dodge, Master. Washington",male,4,0,2,33638,81.8583,A34,S
|
||||
447,1,2,"Mellinger, Miss. Madeleine Violet",female,13,0,1,250644,19.5,,S
|
||||
448,1,1,"Seward, Mr. Frederic Kimber",male,34,0,0,113794,26.55,,S
|
||||
449,1,3,"Baclini, Miss. Marie Catherine",female,5,2,1,2666,19.2583,,C
|
||||
450,1,1,"Peuchen, Major. Arthur Godfrey",male,52,0,0,113786,30.5,C104,S
|
||||
451,0,2,"West, Mr. Edwy Arthur",male,36,1,2,C.A. 34651,27.75,,S
|
||||
452,0,3,"Hagland, Mr. Ingvald Olai Olsen",male,,1,0,65303,19.9667,,S
|
||||
453,0,1,"Foreman, Mr. Benjamin Laventall",male,30,0,0,113051,27.75,C111,C
|
||||
454,1,1,"Goldenberg, Mr. Samuel L",male,49,1,0,17453,89.1042,C92,C
|
||||
455,0,3,"Peduzzi, Mr. Joseph",male,,0,0,A/5 2817,8.05,,S
|
||||
456,1,3,"Jalsevac, Mr. Ivan",male,29,0,0,349240,7.8958,,C
|
||||
457,0,1,"Millet, Mr. Francis Davis",male,65,0,0,13509,26.55,E38,S
|
||||
458,1,1,"Kenyon, Mrs. Frederick R (Marion)",female,,1,0,17464,51.8625,D21,S
|
||||
459,1,2,"Toomey, Miss. Ellen",female,50,0,0,F.C.C. 13531,10.5,,S
|
||||
460,0,3,"O'Connor, Mr. Maurice",male,,0,0,371060,7.75,,Q
|
||||
461,1,1,"Anderson, Mr. Harry",male,48,0,0,19952,26.55,E12,S
|
||||
462,0,3,"Morley, Mr. William",male,34,0,0,364506,8.05,,S
|
||||
463,0,1,"Gee, Mr. Arthur H",male,47,0,0,111320,38.5,E63,S
|
||||
464,0,2,"Milling, Mr. Jacob Christian",male,48,0,0,234360,13,,S
|
||||
465,0,3,"Maisner, Mr. Simon",male,,0,0,A/S 2816,8.05,,S
|
||||
466,0,3,"Goncalves, Mr. Manuel Estanslas",male,38,0,0,SOTON/O.Q. 3101306,7.05,,S
|
||||
467,0,2,"Campbell, Mr. William",male,,0,0,239853,0,,S
|
||||
468,0,1,"Smart, Mr. John Montgomery",male,56,0,0,113792,26.55,,S
|
||||
469,0,3,"Scanlan, Mr. James",male,,0,0,36209,7.725,,Q
|
||||
470,1,3,"Baclini, Miss. Helene Barbara",female,0.75,2,1,2666,19.2583,,C
|
||||
471,0,3,"Keefe, Mr. Arthur",male,,0,0,323592,7.25,,S
|
||||
472,0,3,"Cacic, Mr. Luka",male,38,0,0,315089,8.6625,,S
|
||||
473,1,2,"West, Mrs. Edwy Arthur (Ada Mary Worth)",female,33,1,2,C.A. 34651,27.75,,S
|
||||
474,1,2,"Jerwan, Mrs. Amin S (Marie Marthe Thuillard)",female,23,0,0,SC/AH Basle 541,13.7917,D,C
|
||||
475,0,3,"Strandberg, Miss. Ida Sofia",female,22,0,0,7553,9.8375,,S
|
||||
476,0,1,"Clifford, Mr. George Quincy",male,,0,0,110465,52,A14,S
|
||||
477,0,2,"Renouf, Mr. Peter Henry",male,34,1,0,31027,21,,S
|
||||
478,0,3,"Braund, Mr. Lewis Richard",male,29,1,0,3460,7.0458,,S
|
||||
479,0,3,"Karlsson, Mr. Nils August",male,22,0,0,350060,7.5208,,S
|
||||
480,1,3,"Hirvonen, Miss. Hildur E",female,2,0,1,3101298,12.2875,,S
|
||||
481,0,3,"Goodwin, Master. Harold Victor",male,9,5,2,CA 2144,46.9,,S
|
||||
482,0,2,"Frost, Mr. Anthony Wood ""Archie""",male,,0,0,239854,0,,S
|
||||
483,0,3,"Rouse, Mr. Richard Henry",male,50,0,0,A/5 3594,8.05,,S
|
||||
484,1,3,"Turkula, Mrs. (Hedwig)",female,63,0,0,4134,9.5875,,S
|
||||
485,1,1,"Bishop, Mr. Dickinson H",male,25,1,0,11967,91.0792,B49,C
|
||||
486,0,3,"Lefebre, Miss. Jeannie",female,,3,1,4133,25.4667,,S
|
||||
487,1,1,"Hoyt, Mrs. Frederick Maxfield (Jane Anne Forby)",female,35,1,0,19943,90,C93,S
|
||||
488,0,1,"Kent, Mr. Edward Austin",male,58,0,0,11771,29.7,B37,C
|
||||
489,0,3,"Somerton, Mr. Francis William",male,30,0,0,A.5. 18509,8.05,,S
|
||||
490,1,3,"Coutts, Master. Eden Leslie ""Neville""",male,9,1,1,C.A. 37671,15.9,,S
|
||||
491,0,3,"Hagland, Mr. Konrad Mathias Reiersen",male,,1,0,65304,19.9667,,S
|
||||
492,0,3,"Windelov, Mr. Einar",male,21,0,0,SOTON/OQ 3101317,7.25,,S
|
||||
493,0,1,"Molson, Mr. Harry Markland",male,55,0,0,113787,30.5,C30,S
|
||||
494,0,1,"Artagaveytia, Mr. Ramon",male,71,0,0,PC 17609,49.5042,,C
|
||||
495,0,3,"Stanley, Mr. Edward Roland",male,21,0,0,A/4 45380,8.05,,S
|
||||
496,0,3,"Yousseff, Mr. Gerious",male,,0,0,2627,14.4583,,C
|
||||
497,1,1,"Eustis, Miss. Elizabeth Mussey",female,54,1,0,36947,78.2667,D20,C
|
||||
498,0,3,"Shellard, Mr. Frederick William",male,,0,0,C.A. 6212,15.1,,S
|
||||
499,0,1,"Allison, Mrs. Hudson J C (Bessie Waldo Daniels)",female,25,1,2,113781,151.55,C22 C26,S
|
||||
500,0,3,"Svensson, Mr. Olof",male,24,0,0,350035,7.7958,,S
|
||||
501,0,3,"Calic, Mr. Petar",male,17,0,0,315086,8.6625,,S
|
||||
502,0,3,"Canavan, Miss. Mary",female,21,0,0,364846,7.75,,Q
|
||||
503,0,3,"O'Sullivan, Miss. Bridget Mary",female,,0,0,330909,7.6292,,Q
|
||||
504,0,3,"Laitinen, Miss. Kristina Sofia",female,37,0,0,4135,9.5875,,S
|
||||
505,1,1,"Maioni, Miss. Roberta",female,16,0,0,110152,86.5,B79,S
|
||||
506,0,1,"Penasco y Castellana, Mr. Victor de Satode",male,18,1,0,PC 17758,108.9,C65,C
|
||||
507,1,2,"Quick, Mrs. Frederick Charles (Jane Richards)",female,33,0,2,26360,26,,S
|
||||
508,1,1,"Bradley, Mr. George (""George Arthur Brayton"")",male,,0,0,111427,26.55,,S
|
||||
509,0,3,"Olsen, Mr. Henry Margido",male,28,0,0,C 4001,22.525,,S
|
||||
510,1,3,"Lang, Mr. Fang",male,26,0,0,1601,56.4958,,S
|
||||
511,1,3,"Daly, Mr. Eugene Patrick",male,29,0,0,382651,7.75,,Q
|
||||
512,0,3,"Webber, Mr. James",male,,0,0,SOTON/OQ 3101316,8.05,,S
|
||||
513,1,1,"McGough, Mr. James Robert",male,36,0,0,PC 17473,26.2875,E25,S
|
||||
514,1,1,"Rothschild, Mrs. Martin (Elizabeth L. Barrett)",female,54,1,0,PC 17603,59.4,,C
|
||||
515,0,3,"Coleff, Mr. Satio",male,24,0,0,349209,7.4958,,S
|
||||
516,0,1,"Walker, Mr. William Anderson",male,47,0,0,36967,34.0208,D46,S
|
||||
517,1,2,"Lemore, Mrs. (Amelia Milley)",female,34,0,0,C.A. 34260,10.5,F33,S
|
||||
518,0,3,"Ryan, Mr. Patrick",male,,0,0,371110,24.15,,Q
|
||||
519,1,2,"Angle, Mrs. William A (Florence ""Mary"" Agnes Hughes)",female,36,1,0,226875,26,,S
|
||||
520,0,3,"Pavlovic, Mr. Stefo",male,32,0,0,349242,7.8958,,S
|
||||
521,1,1,"Perreault, Miss. Anne",female,30,0,0,12749,93.5,B73,S
|
||||
522,0,3,"Vovk, Mr. Janko",male,22,0,0,349252,7.8958,,S
|
||||
523,0,3,"Lahoud, Mr. Sarkis",male,,0,0,2624,7.225,,C
|
||||
524,1,1,"Hippach, Mrs. Louis Albert (Ida Sophia Fischer)",female,44,0,1,111361,57.9792,B18,C
|
||||
525,0,3,"Kassem, Mr. Fared",male,,0,0,2700,7.2292,,C
|
||||
526,0,3,"Farrell, Mr. James",male,40.5,0,0,367232,7.75,,Q
|
||||
527,1,2,"Ridsdale, Miss. Lucy",female,50,0,0,W./C. 14258,10.5,,S
|
||||
528,0,1,"Farthing, Mr. John",male,,0,0,PC 17483,221.7792,C95,S
|
||||
529,0,3,"Salonen, Mr. Johan Werner",male,39,0,0,3101296,7.925,,S
|
||||
530,0,2,"Hocking, Mr. Richard George",male,23,2,1,29104,11.5,,S
|
||||
531,1,2,"Quick, Miss. Phyllis May",female,2,1,1,26360,26,,S
|
||||
532,0,3,"Toufik, Mr. Nakli",male,,0,0,2641,7.2292,,C
|
||||
533,0,3,"Elias, Mr. Joseph Jr",male,17,1,1,2690,7.2292,,C
|
||||
534,1,3,"Peter, Mrs. Catherine (Catherine Rizk)",female,,0,2,2668,22.3583,,C
|
||||
535,0,3,"Cacic, Miss. Marija",female,30,0,0,315084,8.6625,,S
|
||||
536,1,2,"Hart, Miss. Eva Miriam",female,7,0,2,F.C.C. 13529,26.25,,S
|
||||
537,0,1,"Butt, Major. Archibald Willingham",male,45,0,0,113050,26.55,B38,S
|
||||
538,1,1,"LeRoy, Miss. Bertha",female,30,0,0,PC 17761,106.425,,C
|
||||
539,0,3,"Risien, Mr. Samuel Beard",male,,0,0,364498,14.5,,S
|
||||
540,1,1,"Frolicher, Miss. Hedwig Margaritha",female,22,0,2,13568,49.5,B39,C
|
||||
541,1,1,"Crosby, Miss. Harriet R",female,36,0,2,WE/P 5735,71,B22,S
|
||||
542,0,3,"Andersson, Miss. Ingeborg Constanzia",female,9,4,2,347082,31.275,,S
|
||||
543,0,3,"Andersson, Miss. Sigrid Elisabeth",female,11,4,2,347082,31.275,,S
|
||||
544,1,2,"Beane, Mr. Edward",male,32,1,0,2908,26,,S
|
||||
545,0,1,"Douglas, Mr. Walter Donald",male,50,1,0,PC 17761,106.425,C86,C
|
||||
546,0,1,"Nicholson, Mr. Arthur Ernest",male,64,0,0,693,26,,S
|
||||
547,1,2,"Beane, Mrs. Edward (Ethel Clarke)",female,19,1,0,2908,26,,S
|
||||
548,1,2,"Padro y Manent, Mr. Julian",male,,0,0,SC/PARIS 2146,13.8625,,C
|
||||
549,0,3,"Goldsmith, Mr. Frank John",male,33,1,1,363291,20.525,,S
|
||||
550,1,2,"Davies, Master. John Morgan Jr",male,8,1,1,C.A. 33112,36.75,,S
|
||||
551,1,1,"Thayer, Mr. John Borland Jr",male,17,0,2,17421,110.8833,C70,C
|
||||
552,0,2,"Sharp, Mr. Percival James R",male,27,0,0,244358,26,,S
|
||||
553,0,3,"O'Brien, Mr. Timothy",male,,0,0,330979,7.8292,,Q
|
||||
554,1,3,"Leeni, Mr. Fahim (""Philip Zenni"")",male,22,0,0,2620,7.225,,C
|
||||
555,1,3,"Ohman, Miss. Velin",female,22,0,0,347085,7.775,,S
|
||||
556,0,1,"Wright, Mr. George",male,62,0,0,113807,26.55,,S
|
||||
557,1,1,"Duff Gordon, Lady. (Lucille Christiana Sutherland) (""Mrs Morgan"")",female,48,1,0,11755,39.6,A16,C
|
||||
558,0,1,"Robbins, Mr. Victor",male,,0,0,PC 17757,227.525,,C
|
||||
559,1,1,"Taussig, Mrs. Emil (Tillie Mandelbaum)",female,39,1,1,110413,79.65,E67,S
|
||||
560,1,3,"de Messemaeker, Mrs. Guillaume Joseph (Emma)",female,36,1,0,345572,17.4,,S
|
||||
561,0,3,"Morrow, Mr. Thomas Rowan",male,,0,0,372622,7.75,,Q
|
||||
562,0,3,"Sivic, Mr. Husein",male,40,0,0,349251,7.8958,,S
|
||||
563,0,2,"Norman, Mr. Robert Douglas",male,28,0,0,218629,13.5,,S
|
||||
564,0,3,"Simmons, Mr. John",male,,0,0,SOTON/OQ 392082,8.05,,S
|
||||
565,0,3,"Meanwell, Miss. (Marion Ogden)",female,,0,0,SOTON/O.Q. 392087,8.05,,S
|
||||
566,0,3,"Davies, Mr. Alfred J",male,24,2,0,A/4 48871,24.15,,S
|
||||
567,0,3,"Stoytcheff, Mr. Ilia",male,19,0,0,349205,7.8958,,S
|
||||
568,0,3,"Palsson, Mrs. Nils (Alma Cornelia Berglund)",female,29,0,4,349909,21.075,,S
|
||||
569,0,3,"Doharr, Mr. Tannous",male,,0,0,2686,7.2292,,C
|
||||
570,1,3,"Jonsson, Mr. Carl",male,32,0,0,350417,7.8542,,S
|
||||
571,1,2,"Harris, Mr. George",male,62,0,0,S.W./PP 752,10.5,,S
|
||||
572,1,1,"Appleton, Mrs. Edward Dale (Charlotte Lamson)",female,53,2,0,11769,51.4792,C101,S
|
||||
573,1,1,"Flynn, Mr. John Irwin (""Irving"")",male,36,0,0,PC 17474,26.3875,E25,S
|
||||
574,1,3,"Kelly, Miss. Mary",female,,0,0,14312,7.75,,Q
|
||||
575,0,3,"Rush, Mr. Alfred George John",male,16,0,0,A/4. 20589,8.05,,S
|
||||
576,0,3,"Patchett, Mr. George",male,19,0,0,358585,14.5,,S
|
||||
577,1,2,"Garside, Miss. Ethel",female,34,0,0,243880,13,,S
|
||||
578,1,1,"Silvey, Mrs. William Baird (Alice Munger)",female,39,1,0,13507,55.9,E44,S
|
||||
579,0,3,"Caram, Mrs. Joseph (Maria Elias)",female,,1,0,2689,14.4583,,C
|
||||
580,1,3,"Jussila, Mr. Eiriik",male,32,0,0,STON/O 2. 3101286,7.925,,S
|
||||
581,1,2,"Christy, Miss. Julie Rachel",female,25,1,1,237789,30,,S
|
||||
582,1,1,"Thayer, Mrs. John Borland (Marian Longstreth Morris)",female,39,1,1,17421,110.8833,C68,C
|
||||
583,0,2,"Downton, Mr. William James",male,54,0,0,28403,26,,S
|
||||
584,0,1,"Ross, Mr. John Hugo",male,36,0,0,13049,40.125,A10,C
|
||||
585,0,3,"Paulner, Mr. Uscher",male,,0,0,3411,8.7125,,C
|
||||
586,1,1,"Taussig, Miss. Ruth",female,18,0,2,110413,79.65,E68,S
|
||||
587,0,2,"Jarvis, Mr. John Denzil",male,47,0,0,237565,15,,S
|
||||
588,1,1,"Frolicher-Stehli, Mr. Maxmillian",male,60,1,1,13567,79.2,B41,C
|
||||
589,0,3,"Gilinski, Mr. Eliezer",male,22,0,0,14973,8.05,,S
|
||||
590,0,3,"Murdlin, Mr. Joseph",male,,0,0,A./5. 3235,8.05,,S
|
||||
591,0,3,"Rintamaki, Mr. Matti",male,35,0,0,STON/O 2. 3101273,7.125,,S
|
||||
592,1,1,"Stephenson, Mrs. Walter Bertram (Martha Eustis)",female,52,1,0,36947,78.2667,D20,C
|
||||
593,0,3,"Elsbury, Mr. William James",male,47,0,0,A/5 3902,7.25,,S
|
||||
594,0,3,"Bourke, Miss. Mary",female,,0,2,364848,7.75,,Q
|
||||
595,0,2,"Chapman, Mr. John Henry",male,37,1,0,SC/AH 29037,26,,S
|
||||
596,0,3,"Van Impe, Mr. Jean Baptiste",male,36,1,1,345773,24.15,,S
|
||||
597,1,2,"Leitch, Miss. Jessie Wills",female,,0,0,248727,33,,S
|
||||
598,0,3,"Johnson, Mr. Alfred",male,49,0,0,LINE,0,,S
|
||||
599,0,3,"Boulos, Mr. Hanna",male,,0,0,2664,7.225,,C
|
||||
600,1,1,"Duff Gordon, Sir. Cosmo Edmund (""Mr Morgan"")",male,49,1,0,PC 17485,56.9292,A20,C
|
||||
601,1,2,"Jacobsohn, Mrs. Sidney Samuel (Amy Frances Christy)",female,24,2,1,243847,27,,S
|
||||
602,0,3,"Slabenoff, Mr. Petco",male,,0,0,349214,7.8958,,S
|
||||
603,0,1,"Harrington, Mr. Charles H",male,,0,0,113796,42.4,,S
|
||||
604,0,3,"Torber, Mr. Ernst William",male,44,0,0,364511,8.05,,S
|
||||
605,1,1,"Homer, Mr. Harry (""Mr E Haven"")",male,35,0,0,111426,26.55,,C
|
||||
606,0,3,"Lindell, Mr. Edvard Bengtsson",male,36,1,0,349910,15.55,,S
|
||||
607,0,3,"Karaic, Mr. Milan",male,30,0,0,349246,7.8958,,S
|
||||
608,1,1,"Daniel, Mr. Robert Williams",male,27,0,0,113804,30.5,,S
|
||||
609,1,2,"Laroche, Mrs. Joseph (Juliette Marie Louise Lafargue)",female,22,1,2,SC/Paris 2123,41.5792,,C
|
||||
610,1,1,"Shutes, Miss. Elizabeth W",female,40,0,0,PC 17582,153.4625,C125,S
|
||||
611,0,3,"Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren)",female,39,1,5,347082,31.275,,S
|
||||
612,0,3,"Jardin, Mr. Jose Neto",male,,0,0,SOTON/O.Q. 3101305,7.05,,S
|
||||
613,1,3,"Murphy, Miss. Margaret Jane",female,,1,0,367230,15.5,,Q
|
||||
614,0,3,"Horgan, Mr. John",male,,0,0,370377,7.75,,Q
|
||||
615,0,3,"Brocklebank, Mr. William Alfred",male,35,0,0,364512,8.05,,S
|
||||
616,1,2,"Herman, Miss. Alice",female,24,1,2,220845,65,,S
|
||||
617,0,3,"Danbom, Mr. Ernst Gilbert",male,34,1,1,347080,14.4,,S
|
||||
618,0,3,"Lobb, Mrs. William Arthur (Cordelia K Stanlick)",female,26,1,0,A/5. 3336,16.1,,S
|
||||
619,1,2,"Becker, Miss. Marion Louise",female,4,2,1,230136,39,F4,S
|
||||
620,0,2,"Gavey, Mr. Lawrence",male,26,0,0,31028,10.5,,S
|
||||
621,0,3,"Yasbeck, Mr. Antoni",male,27,1,0,2659,14.4542,,C
|
||||
622,1,1,"Kimball, Mr. Edwin Nelson Jr",male,42,1,0,11753,52.5542,D19,S
|
||||
623,1,3,"Nakid, Mr. Sahid",male,20,1,1,2653,15.7417,,C
|
||||
624,0,3,"Hansen, Mr. Henry Damsgaard",male,21,0,0,350029,7.8542,,S
|
||||
625,0,3,"Bowen, Mr. David John ""Dai""",male,21,0,0,54636,16.1,,S
|
||||
626,0,1,"Sutton, Mr. Frederick",male,61,0,0,36963,32.3208,D50,S
|
||||
627,0,2,"Kirkland, Rev. Charles Leonard",male,57,0,0,219533,12.35,,Q
|
||||
628,1,1,"Longley, Miss. Gretchen Fiske",female,21,0,0,13502,77.9583,D9,S
|
||||
629,0,3,"Bostandyeff, Mr. Guentcho",male,26,0,0,349224,7.8958,,S
|
||||
630,0,3,"O'Connell, Mr. Patrick D",male,,0,0,334912,7.7333,,Q
|
||||
631,1,1,"Barkworth, Mr. Algernon Henry Wilson",male,80,0,0,27042,30,A23,S
|
||||
632,0,3,"Lundahl, Mr. Johan Svensson",male,51,0,0,347743,7.0542,,S
|
||||
633,1,1,"Stahelin-Maeglin, Dr. Max",male,32,0,0,13214,30.5,B50,C
|
||||
634,0,1,"Parr, Mr. William Henry Marsh",male,,0,0,112052,0,,S
|
||||
635,0,3,"Skoog, Miss. Mabel",female,9,3,2,347088,27.9,,S
|
||||
636,1,2,"Davis, Miss. Mary",female,28,0,0,237668,13,,S
|
||||
637,0,3,"Leinonen, Mr. Antti Gustaf",male,32,0,0,STON/O 2. 3101292,7.925,,S
|
||||
638,0,2,"Collyer, Mr. Harvey",male,31,1,1,C.A. 31921,26.25,,S
|
||||
639,0,3,"Panula, Mrs. Juha (Maria Emilia Ojala)",female,41,0,5,3101295,39.6875,,S
|
||||
640,0,3,"Thorneycroft, Mr. Percival",male,,1,0,376564,16.1,,S
|
||||
641,0,3,"Jensen, Mr. Hans Peder",male,20,0,0,350050,7.8542,,S
|
||||
642,1,1,"Sagesser, Mlle. Emma",female,24,0,0,PC 17477,69.3,B35,C
|
||||
643,0,3,"Skoog, Miss. Margit Elizabeth",female,2,3,2,347088,27.9,,S
|
||||
644,1,3,"Foo, Mr. Choong",male,,0,0,1601,56.4958,,S
|
||||
645,1,3,"Baclini, Miss. Eugenie",female,0.75,2,1,2666,19.2583,,C
|
||||
646,1,1,"Harper, Mr. Henry Sleeper",male,48,1,0,PC 17572,76.7292,D33,C
|
||||
647,0,3,"Cor, Mr. Liudevit",male,19,0,0,349231,7.8958,,S
|
||||
648,1,1,"Simonius-Blumer, Col. Oberst Alfons",male,56,0,0,13213,35.5,A26,C
|
||||
649,0,3,"Willey, Mr. Edward",male,,0,0,S.O./P.P. 751,7.55,,S
|
||||
650,1,3,"Stanley, Miss. Amy Zillah Elsie",female,23,0,0,CA. 2314,7.55,,S
|
||||
651,0,3,"Mitkoff, Mr. Mito",male,,0,0,349221,7.8958,,S
|
||||
652,1,2,"Doling, Miss. Elsie",female,18,0,1,231919,23,,S
|
||||
653,0,3,"Kalvik, Mr. Johannes Halvorsen",male,21,0,0,8475,8.4333,,S
|
||||
654,1,3,"O'Leary, Miss. Hanora ""Norah""",female,,0,0,330919,7.8292,,Q
|
||||
655,0,3,"Hegarty, Miss. Hanora ""Nora""",female,18,0,0,365226,6.75,,Q
|
||||
656,0,2,"Hickman, Mr. Leonard Mark",male,24,2,0,S.O.C. 14879,73.5,,S
|
||||
657,0,3,"Radeff, Mr. Alexander",male,,0,0,349223,7.8958,,S
|
||||
658,0,3,"Bourke, Mrs. John (Catherine)",female,32,1,1,364849,15.5,,Q
|
||||
659,0,2,"Eitemiller, Mr. George Floyd",male,23,0,0,29751,13,,S
|
||||
660,0,1,"Newell, Mr. Arthur Webster",male,58,0,2,35273,113.275,D48,C
|
||||
661,1,1,"Frauenthal, Dr. Henry William",male,50,2,0,PC 17611,133.65,,S
|
||||
662,0,3,"Badt, Mr. Mohamed",male,40,0,0,2623,7.225,,C
|
||||
663,0,1,"Colley, Mr. Edward Pomeroy",male,47,0,0,5727,25.5875,E58,S
|
||||
664,0,3,"Coleff, Mr. Peju",male,36,0,0,349210,7.4958,,S
|
||||
665,1,3,"Lindqvist, Mr. Eino William",male,20,1,0,STON/O 2. 3101285,7.925,,S
|
||||
666,0,2,"Hickman, Mr. Lewis",male,32,2,0,S.O.C. 14879,73.5,,S
|
||||
667,0,2,"Butler, Mr. Reginald Fenton",male,25,0,0,234686,13,,S
|
||||
668,0,3,"Rommetvedt, Mr. Knud Paust",male,,0,0,312993,7.775,,S
|
||||
669,0,3,"Cook, Mr. Jacob",male,43,0,0,A/5 3536,8.05,,S
|
||||
670,1,1,"Taylor, Mrs. Elmer Zebley (Juliet Cummins Wright)",female,,1,0,19996,52,C126,S
|
||||
671,1,2,"Brown, Mrs. Thomas William Solomon (Elizabeth Catherine Ford)",female,40,1,1,29750,39,,S
|
||||
672,0,1,"Davidson, Mr. Thornton",male,31,1,0,F.C. 12750,52,B71,S
|
||||
673,0,2,"Mitchell, Mr. Henry Michael",male,70,0,0,C.A. 24580,10.5,,S
|
||||
674,1,2,"Wilhelms, Mr. Charles",male,31,0,0,244270,13,,S
|
||||
675,0,2,"Watson, Mr. Ennis Hastings",male,,0,0,239856,0,,S
|
||||
676,0,3,"Edvardsson, Mr. Gustaf Hjalmar",male,18,0,0,349912,7.775,,S
|
||||
677,0,3,"Sawyer, Mr. Frederick Charles",male,24.5,0,0,342826,8.05,,S
|
||||
678,1,3,"Turja, Miss. Anna Sofia",female,18,0,0,4138,9.8417,,S
|
||||
679,0,3,"Goodwin, Mrs. Frederick (Augusta Tyler)",female,43,1,6,CA 2144,46.9,,S
|
||||
680,1,1,"Cardeza, Mr. Thomas Drake Martinez",male,36,0,1,PC 17755,512.3292,B51 B53 B55,C
|
||||
681,0,3,"Peters, Miss. Katie",female,,0,0,330935,8.1375,,Q
|
||||
682,1,1,"Hassab, Mr. Hammad",male,27,0,0,PC 17572,76.7292,D49,C
|
||||
683,0,3,"Olsvigen, Mr. Thor Anderson",male,20,0,0,6563,9.225,,S
|
||||
684,0,3,"Goodwin, Mr. Charles Edward",male,14,5,2,CA 2144,46.9,,S
|
||||
685,0,2,"Brown, Mr. Thomas William Solomon",male,60,1,1,29750,39,,S
|
||||
686,0,2,"Laroche, Mr. Joseph Philippe Lemercier",male,25,1,2,SC/Paris 2123,41.5792,,C
|
||||
687,0,3,"Panula, Mr. Jaako Arnold",male,14,4,1,3101295,39.6875,,S
|
||||
688,0,3,"Dakic, Mr. Branko",male,19,0,0,349228,10.1708,,S
|
||||
689,0,3,"Fischer, Mr. Eberhard Thelander",male,18,0,0,350036,7.7958,,S
|
||||
690,1,1,"Madill, Miss. Georgette Alexandra",female,15,0,1,24160,211.3375,B5,S
|
||||
691,1,1,"Dick, Mr. Albert Adrian",male,31,1,0,17474,57,B20,S
|
||||
692,1,3,"Karun, Miss. Manca",female,4,0,1,349256,13.4167,,C
|
||||
693,1,3,"Lam, Mr. Ali",male,,0,0,1601,56.4958,,S
|
||||
694,0,3,"Saad, Mr. Khalil",male,25,0,0,2672,7.225,,C
|
||||
695,0,1,"Weir, Col. John",male,60,0,0,113800,26.55,,S
|
||||
696,0,2,"Chapman, Mr. Charles Henry",male,52,0,0,248731,13.5,,S
|
||||
697,0,3,"Kelly, Mr. James",male,44,0,0,363592,8.05,,S
|
||||
698,1,3,"Mullens, Miss. Katherine ""Katie""",female,,0,0,35852,7.7333,,Q
|
||||
699,0,1,"Thayer, Mr. John Borland",male,49,1,1,17421,110.8833,C68,C
|
||||
700,0,3,"Humblen, Mr. Adolf Mathias Nicolai Olsen",male,42,0,0,348121,7.65,F G63,S
|
||||
701,1,1,"Astor, Mrs. John Jacob (Madeleine Talmadge Force)",female,18,1,0,PC 17757,227.525,C62 C64,C
|
||||
702,1,1,"Silverthorne, Mr. Spencer Victor",male,35,0,0,PC 17475,26.2875,E24,S
|
||||
703,0,3,"Barbara, Miss. Saiide",female,18,0,1,2691,14.4542,,C
|
||||
704,0,3,"Gallagher, Mr. Martin",male,25,0,0,36864,7.7417,,Q
|
||||
705,0,3,"Hansen, Mr. Henrik Juul",male,26,1,0,350025,7.8542,,S
|
||||
706,0,2,"Morley, Mr. Henry Samuel (""Mr Henry Marshall"")",male,39,0,0,250655,26,,S
|
||||
707,1,2,"Kelly, Mrs. Florence ""Fannie""",female,45,0,0,223596,13.5,,S
|
||||
708,1,1,"Calderhead, Mr. Edward Pennington",male,42,0,0,PC 17476,26.2875,E24,S
|
||||
709,1,1,"Cleaver, Miss. Alice",female,22,0,0,113781,151.55,,S
|
||||
710,1,3,"Moubarek, Master. Halim Gonios (""William George"")",male,,1,1,2661,15.2458,,C
|
||||
711,1,1,"Mayne, Mlle. Berthe Antonine (""Mrs de Villiers"")",female,24,0,0,PC 17482,49.5042,C90,C
|
||||
712,0,1,"Klaber, Mr. Herman",male,,0,0,113028,26.55,C124,S
|
||||
713,1,1,"Taylor, Mr. Elmer Zebley",male,48,1,0,19996,52,C126,S
|
||||
714,0,3,"Larsson, Mr. August Viktor",male,29,0,0,7545,9.4833,,S
|
||||
715,0,2,"Greenberg, Mr. Samuel",male,52,0,0,250647,13,,S
|
||||
716,0,3,"Soholt, Mr. Peter Andreas Lauritz Andersen",male,19,0,0,348124,7.65,F G73,S
|
||||
717,1,1,"Endres, Miss. Caroline Louise",female,38,0,0,PC 17757,227.525,C45,C
|
||||
718,1,2,"Troutt, Miss. Edwina Celia ""Winnie""",female,27,0,0,34218,10.5,E101,S
|
||||
719,0,3,"McEvoy, Mr. Michael",male,,0,0,36568,15.5,,Q
|
||||
720,0,3,"Johnson, Mr. Malkolm Joackim",male,33,0,0,347062,7.775,,S
|
||||
721,1,2,"Harper, Miss. Annie Jessie ""Nina""",female,6,0,1,248727,33,,S
|
||||
722,0,3,"Jensen, Mr. Svend Lauritz",male,17,1,0,350048,7.0542,,S
|
||||
723,0,2,"Gillespie, Mr. William Henry",male,34,0,0,12233,13,,S
|
||||
724,0,2,"Hodges, Mr. Henry Price",male,50,0,0,250643,13,,S
|
||||
725,1,1,"Chambers, Mr. Norman Campbell",male,27,1,0,113806,53.1,E8,S
|
||||
726,0,3,"Oreskovic, Mr. Luka",male,20,0,0,315094,8.6625,,S
|
||||
727,1,2,"Renouf, Mrs. Peter Henry (Lillian Jefferys)",female,30,3,0,31027,21,,S
|
||||
728,1,3,"Mannion, Miss. Margareth",female,,0,0,36866,7.7375,,Q
|
||||
729,0,2,"Bryhl, Mr. Kurt Arnold Gottfrid",male,25,1,0,236853,26,,S
|
||||
730,0,3,"Ilmakangas, Miss. Pieta Sofia",female,25,1,0,STON/O2. 3101271,7.925,,S
|
||||
731,1,1,"Allen, Miss. Elisabeth Walton",female,29,0,0,24160,211.3375,B5,S
|
||||
732,0,3,"Hassan, Mr. Houssein G N",male,11,0,0,2699,18.7875,,C
|
||||
733,0,2,"Knight, Mr. Robert J",male,,0,0,239855,0,,S
|
||||
734,0,2,"Berriman, Mr. William John",male,23,0,0,28425,13,,S
|
||||
735,0,2,"Troupiansky, Mr. Moses Aaron",male,23,0,0,233639,13,,S
|
||||
736,0,3,"Williams, Mr. Leslie",male,28.5,0,0,54636,16.1,,S
|
||||
737,0,3,"Ford, Mrs. Edward (Margaret Ann Watson)",female,48,1,3,W./C. 6608,34.375,,S
|
||||
738,1,1,"Lesurer, Mr. Gustave J",male,35,0,0,PC 17755,512.3292,B101,C
|
||||
739,0,3,"Ivanoff, Mr. Kanio",male,,0,0,349201,7.8958,,S
|
||||
740,0,3,"Nankoff, Mr. Minko",male,,0,0,349218,7.8958,,S
|
||||
741,1,1,"Hawksford, Mr. Walter James",male,,0,0,16988,30,D45,S
|
||||
742,0,1,"Cavendish, Mr. Tyrell William",male,36,1,0,19877,78.85,C46,S
|
||||
743,1,1,"Ryerson, Miss. Susan Parker ""Suzette""",female,21,2,2,PC 17608,262.375,B57 B59 B63 B66,C
|
||||
744,0,3,"McNamee, Mr. Neal",male,24,1,0,376566,16.1,,S
|
||||
745,1,3,"Stranden, Mr. Juho",male,31,0,0,STON/O 2. 3101288,7.925,,S
|
||||
746,0,1,"Crosby, Capt. Edward Gifford",male,70,1,1,WE/P 5735,71,B22,S
|
||||
747,0,3,"Abbott, Mr. Rossmore Edward",male,16,1,1,C.A. 2673,20.25,,S
|
||||
748,1,2,"Sinkkonen, Miss. Anna",female,30,0,0,250648,13,,S
|
||||
749,0,1,"Marvin, Mr. Daniel Warner",male,19,1,0,113773,53.1,D30,S
|
||||
750,0,3,"Connaghton, Mr. Michael",male,31,0,0,335097,7.75,,Q
|
||||
751,1,2,"Wells, Miss. Joan",female,4,1,1,29103,23,,S
|
||||
752,1,3,"Moor, Master. Meier",male,6,0,1,392096,12.475,E121,S
|
||||
753,0,3,"Vande Velde, Mr. Johannes Joseph",male,33,0,0,345780,9.5,,S
|
||||
754,0,3,"Jonkoff, Mr. Lalio",male,23,0,0,349204,7.8958,,S
|
||||
755,1,2,"Herman, Mrs. Samuel (Jane Laver)",female,48,1,2,220845,65,,S
|
||||
756,1,2,"Hamalainen, Master. Viljo",male,0.67,1,1,250649,14.5,,S
|
||||
757,0,3,"Carlsson, Mr. August Sigfrid",male,28,0,0,350042,7.7958,,S
|
||||
758,0,2,"Bailey, Mr. Percy Andrew",male,18,0,0,29108,11.5,,S
|
||||
759,0,3,"Theobald, Mr. Thomas Leonard",male,34,0,0,363294,8.05,,S
|
||||
760,1,1,"Rothes, the Countess. of (Lucy Noel Martha Dyer-Edwards)",female,33,0,0,110152,86.5,B77,S
|
||||
761,0,3,"Garfirth, Mr. John",male,,0,0,358585,14.5,,S
|
||||
762,0,3,"Nirva, Mr. Iisakki Antino Aijo",male,41,0,0,SOTON/O2 3101272,7.125,,S
|
||||
763,1,3,"Barah, Mr. Hanna Assi",male,20,0,0,2663,7.2292,,C
|
||||
764,1,1,"Carter, Mrs. William Ernest (Lucile Polk)",female,36,1,2,113760,120,B96 B98,S
|
||||
765,0,3,"Eklund, Mr. Hans Linus",male,16,0,0,347074,7.775,,S
|
||||
766,1,1,"Hogeboom, Mrs. John C (Anna Andrews)",female,51,1,0,13502,77.9583,D11,S
|
||||
767,0,1,"Brewe, Dr. Arthur Jackson",male,,0,0,112379,39.6,,C
|
||||
768,0,3,"Mangan, Miss. Mary",female,30.5,0,0,364850,7.75,,Q
|
||||
769,0,3,"Moran, Mr. Daniel J",male,,1,0,371110,24.15,,Q
|
||||
770,0,3,"Gronnestad, Mr. Daniel Danielsen",male,32,0,0,8471,8.3625,,S
|
||||
771,0,3,"Lievens, Mr. Rene Aime",male,24,0,0,345781,9.5,,S
|
||||
772,0,3,"Jensen, Mr. Niels Peder",male,48,0,0,350047,7.8542,,S
|
||||
773,0,2,"Mack, Mrs. (Mary)",female,57,0,0,S.O./P.P. 3,10.5,E77,S
|
||||
774,0,3,"Elias, Mr. Dibo",male,,0,0,2674,7.225,,C
|
||||
775,1,2,"Hocking, Mrs. Elizabeth (Eliza Needs)",female,54,1,3,29105,23,,S
|
||||
776,0,3,"Myhrman, Mr. Pehr Fabian Oliver Malkolm",male,18,0,0,347078,7.75,,S
|
||||
777,0,3,"Tobin, Mr. Roger",male,,0,0,383121,7.75,F38,Q
|
||||
778,1,3,"Emanuel, Miss. Virginia Ethel",female,5,0,0,364516,12.475,,S
|
||||
779,0,3,"Kilgannon, Mr. Thomas J",male,,0,0,36865,7.7375,,Q
|
||||
780,1,1,"Robert, Mrs. Edward Scott (Elisabeth Walton McMillan)",female,43,0,1,24160,211.3375,B3,S
|
||||
781,1,3,"Ayoub, Miss. Banoura",female,13,0,0,2687,7.2292,,C
|
||||
782,1,1,"Dick, Mrs. Albert Adrian (Vera Gillespie)",female,17,1,0,17474,57,B20,S
|
||||
783,0,1,"Long, Mr. Milton Clyde",male,29,0,0,113501,30,D6,S
|
||||
784,0,3,"Johnston, Mr. Andrew G",male,,1,2,W./C. 6607,23.45,,S
|
||||
785,0,3,"Ali, Mr. William",male,25,0,0,SOTON/O.Q. 3101312,7.05,,S
|
||||
786,0,3,"Harmer, Mr. Abraham (David Lishin)",male,25,0,0,374887,7.25,,S
|
||||
787,1,3,"Sjoblom, Miss. Anna Sofia",female,18,0,0,3101265,7.4958,,S
|
||||
788,0,3,"Rice, Master. George Hugh",male,8,4,1,382652,29.125,,Q
|
||||
789,1,3,"Dean, Master. Bertram Vere",male,1,1,2,C.A. 2315,20.575,,S
|
||||
790,0,1,"Guggenheim, Mr. Benjamin",male,46,0,0,PC 17593,79.2,B82 B84,C
|
||||
791,0,3,"Keane, Mr. Andrew ""Andy""",male,,0,0,12460,7.75,,Q
|
||||
792,0,2,"Gaskell, Mr. Alfred",male,16,0,0,239865,26,,S
|
||||
793,0,3,"Sage, Miss. Stella Anna",female,,8,2,CA. 2343,69.55,,S
|
||||
794,0,1,"Hoyt, Mr. William Fisher",male,,0,0,PC 17600,30.6958,,C
|
||||
795,0,3,"Dantcheff, Mr. Ristiu",male,25,0,0,349203,7.8958,,S
|
||||
796,0,2,"Otter, Mr. Richard",male,39,0,0,28213,13,,S
|
||||
797,1,1,"Leader, Dr. Alice (Farnham)",female,49,0,0,17465,25.9292,D17,S
|
||||
798,1,3,"Osman, Mrs. Mara",female,31,0,0,349244,8.6833,,S
|
||||
799,0,3,"Ibrahim Shawah, Mr. Yousseff",male,30,0,0,2685,7.2292,,C
|
||||
800,0,3,"Van Impe, Mrs. Jean Baptiste (Rosalie Paula Govaert)",female,30,1,1,345773,24.15,,S
|
||||
801,0,2,"Ponesell, Mr. Martin",male,34,0,0,250647,13,,S
|
||||
802,1,2,"Collyer, Mrs. Harvey (Charlotte Annie Tate)",female,31,1,1,C.A. 31921,26.25,,S
|
||||
803,1,1,"Carter, Master. William Thornton II",male,11,1,2,113760,120,B96 B98,S
|
||||
804,1,3,"Thomas, Master. Assad Alexander",male,0.42,0,1,2625,8.5167,,C
|
||||
805,1,3,"Hedman, Mr. Oskar Arvid",male,27,0,0,347089,6.975,,S
|
||||
806,0,3,"Johansson, Mr. Karl Johan",male,31,0,0,347063,7.775,,S
|
||||
807,0,1,"Andrews, Mr. Thomas Jr",male,39,0,0,112050,0,A36,S
|
||||
808,0,3,"Pettersson, Miss. Ellen Natalia",female,18,0,0,347087,7.775,,S
|
||||
809,0,2,"Meyer, Mr. August",male,39,0,0,248723,13,,S
|
||||
810,1,1,"Chambers, Mrs. Norman Campbell (Bertha Griggs)",female,33,1,0,113806,53.1,E8,S
|
||||
811,0,3,"Alexander, Mr. William",male,26,0,0,3474,7.8875,,S
|
||||
812,0,3,"Lester, Mr. James",male,39,0,0,A/4 48871,24.15,,S
|
||||
813,0,2,"Slemen, Mr. Richard James",male,35,0,0,28206,10.5,,S
|
||||
814,0,3,"Andersson, Miss. Ebba Iris Alfrida",female,6,4,2,347082,31.275,,S
|
||||
815,0,3,"Tomlin, Mr. Ernest Portage",male,30.5,0,0,364499,8.05,,S
|
||||
816,0,1,"Fry, Mr. Richard",male,,0,0,112058,0,B102,S
|
||||
817,0,3,"Heininen, Miss. Wendla Maria",female,23,0,0,STON/O2. 3101290,7.925,,S
|
||||
818,0,2,"Mallet, Mr. Albert",male,31,1,1,S.C./PARIS 2079,37.0042,,C
|
||||
819,0,3,"Holm, Mr. John Fredrik Alexander",male,43,0,0,C 7075,6.45,,S
|
||||
820,0,3,"Skoog, Master. Karl Thorsten",male,10,3,2,347088,27.9,,S
|
||||
821,1,1,"Hays, Mrs. Charles Melville (Clara Jennings Gregg)",female,52,1,1,12749,93.5,B69,S
|
||||
822,1,3,"Lulic, Mr. Nikola",male,27,0,0,315098,8.6625,,S
|
||||
823,0,1,"Reuchlin, Jonkheer. John George",male,38,0,0,19972,0,,S
|
||||
824,1,3,"Moor, Mrs. (Beila)",female,27,0,1,392096,12.475,E121,S
|
||||
825,0,3,"Panula, Master. Urho Abraham",male,2,4,1,3101295,39.6875,,S
|
||||
826,0,3,"Flynn, Mr. John",male,,0,0,368323,6.95,,Q
|
||||
827,0,3,"Lam, Mr. Len",male,,0,0,1601,56.4958,,S
|
||||
828,1,2,"Mallet, Master. Andre",male,1,0,2,S.C./PARIS 2079,37.0042,,C
|
||||
829,1,3,"McCormack, Mr. Thomas Joseph",male,,0,0,367228,7.75,,Q
|
||||
830,1,1,"Stone, Mrs. George Nelson (Martha Evelyn)",female,62,0,0,113572,80,B28,
|
||||
831,1,3,"Yasbeck, Mrs. Antoni (Selini Alexander)",female,15,1,0,2659,14.4542,,C
|
||||
832,1,2,"Richards, Master. George Sibley",male,0.83,1,1,29106,18.75,,S
|
||||
833,0,3,"Saad, Mr. Amin",male,,0,0,2671,7.2292,,C
|
||||
834,0,3,"Augustsson, Mr. Albert",male,23,0,0,347468,7.8542,,S
|
||||
835,0,3,"Allum, Mr. Owen George",male,18,0,0,2223,8.3,,S
|
||||
836,1,1,"Compton, Miss. Sara Rebecca",female,39,1,1,PC 17756,83.1583,E49,C
|
||||
837,0,3,"Pasic, Mr. Jakob",male,21,0,0,315097,8.6625,,S
|
||||
838,0,3,"Sirota, Mr. Maurice",male,,0,0,392092,8.05,,S
|
||||
839,1,3,"Chip, Mr. Chang",male,32,0,0,1601,56.4958,,S
|
||||
840,1,1,"Marechal, Mr. Pierre",male,,0,0,11774,29.7,C47,C
|
||||
841,0,3,"Alhomaki, Mr. Ilmari Rudolf",male,20,0,0,SOTON/O2 3101287,7.925,,S
|
||||
842,0,2,"Mudd, Mr. Thomas Charles",male,16,0,0,S.O./P.P. 3,10.5,,S
|
||||
843,1,1,"Serepeca, Miss. Augusta",female,30,0,0,113798,31,,C
|
||||
844,0,3,"Lemberopolous, Mr. Peter L",male,34.5,0,0,2683,6.4375,,C
|
||||
845,0,3,"Culumovic, Mr. Jeso",male,17,0,0,315090,8.6625,,S
|
||||
846,0,3,"Abbing, Mr. Anthony",male,42,0,0,C.A. 5547,7.55,,S
|
||||
847,0,3,"Sage, Mr. Douglas Bullen",male,,8,2,CA. 2343,69.55,,S
|
||||
848,0,3,"Markoff, Mr. Marin",male,35,0,0,349213,7.8958,,C
|
||||
849,0,2,"Harper, Rev. John",male,28,0,1,248727,33,,S
|
||||
850,1,1,"Goldenberg, Mrs. Samuel L (Edwiga Grabowska)",female,,1,0,17453,89.1042,C92,C
|
||||
851,0,3,"Andersson, Master. Sigvard Harald Elias",male,4,4,2,347082,31.275,,S
|
||||
852,0,3,"Svensson, Mr. Johan",male,74,0,0,347060,7.775,,S
|
||||
853,0,3,"Boulos, Miss. Nourelain",female,9,1,1,2678,15.2458,,C
|
||||
854,1,1,"Lines, Miss. Mary Conover",female,16,0,1,PC 17592,39.4,D28,S
|
||||
855,0,2,"Carter, Mrs. Ernest Courtenay (Lilian Hughes)",female,44,1,0,244252,26,,S
|
||||
856,1,3,"Aks, Mrs. Sam (Leah Rosen)",female,18,0,1,392091,9.35,,S
|
||||
857,1,1,"Wick, Mrs. George Dennick (Mary Hitchcock)",female,45,1,1,36928,164.8667,,S
|
||||
858,1,1,"Daly, Mr. Peter Denis ",male,51,0,0,113055,26.55,E17,S
|
||||
859,1,3,"Baclini, Mrs. Solomon (Latifa Qurban)",female,24,0,3,2666,19.2583,,C
|
||||
860,0,3,"Razi, Mr. Raihed",male,,0,0,2629,7.2292,,C
|
||||
861,0,3,"Hansen, Mr. Claus Peter",male,41,2,0,350026,14.1083,,S
|
||||
862,0,2,"Giles, Mr. Frederick Edward",male,21,1,0,28134,11.5,,S
|
||||
863,1,1,"Swift, Mrs. Frederick Joel (Margaret Welles Barron)",female,48,0,0,17466,25.9292,D17,S
|
||||
864,0,3,"Sage, Miss. Dorothy Edith ""Dolly""",female,,8,2,CA. 2343,69.55,,S
|
||||
865,0,2,"Gill, Mr. John William",male,24,0,0,233866,13,,S
|
||||
866,1,2,"Bystrom, Mrs. (Karolina)",female,42,0,0,236852,13,,S
|
||||
867,1,2,"Duran y More, Miss. Asuncion",female,27,1,0,SC/PARIS 2149,13.8583,,C
|
||||
868,0,1,"Roebling, Mr. Washington Augustus II",male,31,0,0,PC 17590,50.4958,A24,S
|
||||
869,0,3,"van Melkebeke, Mr. Philemon",male,,0,0,345777,9.5,,S
|
||||
870,1,3,"Johnson, Master. Harold Theodor",male,4,1,1,347742,11.1333,,S
|
||||
871,0,3,"Balkic, Mr. Cerin",male,26,0,0,349248,7.8958,,S
|
||||
872,1,1,"Beckwith, Mrs. Richard Leonard (Sallie Monypeny)",female,47,1,1,11751,52.5542,D35,S
|
||||
873,0,1,"Carlsson, Mr. Frans Olof",male,33,0,0,695,5,B51 B53 B55,S
|
||||
874,0,3,"Vander Cruyssen, Mr. Victor",male,47,0,0,345765,9,,S
|
||||
875,1,2,"Abelson, Mrs. Samuel (Hannah Wizosky)",female,28,1,0,P/PP 3381,24,,C
|
||||
876,1,3,"Najib, Miss. Adele Kiamie ""Jane""",female,15,0,0,2667,7.225,,C
|
||||
877,0,3,"Gustafsson, Mr. Alfred Ossian",male,20,0,0,7534,9.8458,,S
|
||||
878,0,3,"Petroff, Mr. Nedelio",male,19,0,0,349212,7.8958,,S
|
||||
879,0,3,"Laleff, Mr. Kristo",male,,0,0,349217,7.8958,,S
|
||||
880,1,1,"Potter, Mrs. Thomas Jr (Lily Alexenia Wilson)",female,56,0,1,11767,83.1583,C50,C
|
||||
881,1,2,"Shelley, Mrs. William (Imanita Parrish Hall)",female,25,0,1,230433,26,,S
|
||||
882,0,3,"Markun, Mr. Johann",male,33,0,0,349257,7.8958,,S
|
||||
883,0,3,"Dahlberg, Miss. Gerda Ulrika",female,22,0,0,7552,10.5167,,S
|
||||
884,0,2,"Banfield, Mr. Frederick James",male,28,0,0,C.A./SOTON 34068,10.5,,S
|
||||
885,0,3,"Sutehall, Mr. Henry Jr",male,25,0,0,SOTON/OQ 392076,7.05,,S
|
||||
886,0,3,"Rice, Mrs. William (Margaret Norton)",female,39,0,5,382652,29.125,,Q
|
||||
887,0,2,"Montvila, Rev. Juozas",male,27,0,0,211536,13,,S
|
||||
888,1,1,"Graham, Miss. Margaret Edith",female,19,0,0,112053,30,B42,S
|
||||
889,0,3,"Johnston, Miss. Catherine Helen ""Carrie""",female,,1,2,W./C. 6607,23.45,,S
|
||||
890,1,1,"Behr, Mr. Karl Howell",male,26,0,0,111369,30,C148,C
|
||||
891,0,3,"Dooley, Mr. Patrick",male,32,0,0,370376,7.75,,Q
|
||||
|
|
After Width: | Height: | Size: 517 KiB |
|
After Width: | Height: | Size: 500 KiB |
|
After Width: | Height: | Size: 604 KiB |
|
After Width: | Height: | Size: 709 KiB |
@@ -0,0 +1,354 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Pride and Prejudice | Jane Austen</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation -->
|
||||
<nav class="nav">
|
||||
<div class="nav-brand">P&P</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#characters">Characters</a></li>
|
||||
<li><a href="#themes">Themes</a></li>
|
||||
<li><a href="#quotes">Quotes</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero">
|
||||
<div class="hero-bg">
|
||||
<div class="hero-pattern"></div>
|
||||
</div>
|
||||
<div class="hero-content">
|
||||
<p class="hero-subtitle">A Novel by</p>
|
||||
<h1 class="hero-title">
|
||||
<span class="title-line">Pride</span>
|
||||
<span class="title-ampersand">&</span>
|
||||
<span class="title-line">Prejudice</span>
|
||||
</h1>
|
||||
<p class="hero-author">Jane Austen</p>
|
||||
<p class="hero-year">1813</p>
|
||||
<div class="hero-divider">
|
||||
<span class="divider-line"></span>
|
||||
<span class="divider-ornament">❦</span>
|
||||
<span class="divider-line"></span>
|
||||
</div>
|
||||
<p class="hero-tagline">"It is a truth universally acknowledged..."</p>
|
||||
<a href="#about" class="hero-cta">
|
||||
<span>Discover the Story</span>
|
||||
<svg
|
||||
class="cta-arrow"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path d="M12 5v14M5 12l7 7 7-7" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="hero-scroll-indicator">
|
||||
<div class="scroll-line"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- About Section -->
|
||||
<section id="about" class="about">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-number">01</span>
|
||||
<h2 class="section-title">The Novel</h2>
|
||||
</div>
|
||||
<div class="about-content">
|
||||
<div class="about-text">
|
||||
<p class="about-lead">
|
||||
Set in rural England in the early 19th century,
|
||||
<em>Pride and Prejudice</em> tells the story of the Bennet family
|
||||
and their five unmarried daughters.
|
||||
</p>
|
||||
<p>
|
||||
When the wealthy and eligible Mr. Bingley rents a nearby estate,
|
||||
Mrs. Bennet sees an opportunity to marry off her eldest daughter,
|
||||
Jane. At a ball, Jane forms an attachment to Mr. Bingley, while
|
||||
her sister Elizabeth meets his friend, the proud Mr. Darcy.
|
||||
</p>
|
||||
<p>
|
||||
What follows is a masterful exploration of manners, morality,
|
||||
education, and marriage in the society of the landed gentry of
|
||||
early 19th-century England.
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-number">61</span>
|
||||
<span class="stat-label">Chapters</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-number">122K</span>
|
||||
<span class="stat-label">Words</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-number">20M+</span>
|
||||
<span class="stat-label">Copies Sold</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Characters Section -->
|
||||
<section id="characters" class="characters">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-number">02</span>
|
||||
<h2 class="section-title">The Characters</h2>
|
||||
</div>
|
||||
<div class="characters-grid">
|
||||
<div class="character-card featured">
|
||||
<div class="character-portrait elizabeth"></div>
|
||||
<div class="character-info">
|
||||
<h3>Elizabeth Bennet</h3>
|
||||
<p class="character-role">The Protagonist</p>
|
||||
<p class="character-desc">
|
||||
Intelligent, witty, and independent, Elizabeth navigates
|
||||
society's expectations while staying true to her principles.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="character-card featured">
|
||||
<div class="character-portrait darcy"></div>
|
||||
<div class="character-info">
|
||||
<h3>Fitzwilliam Darcy</h3>
|
||||
<p class="character-role">The Romantic Lead</p>
|
||||
<p class="character-desc">
|
||||
Wealthy, reserved, and initially perceived as arrogant, Darcy's
|
||||
true character is revealed through his actions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="character-card">
|
||||
<div class="character-portrait jane"></div>
|
||||
<div class="character-info">
|
||||
<h3>Jane Bennet</h3>
|
||||
<p class="character-role">The Eldest Sister</p>
|
||||
<p class="character-desc">
|
||||
Beautiful, gentle, and always sees the best in people.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="character-card">
|
||||
<div class="character-portrait bingley"></div>
|
||||
<div class="character-info">
|
||||
<h3>Charles Bingley</h3>
|
||||
<p class="character-role">The Amiable Gentleman</p>
|
||||
<p class="character-desc">
|
||||
Wealthy, good-natured, and easily influenced by his friends.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="character-card">
|
||||
<div class="character-portrait lydia"></div>
|
||||
<div class="character-info">
|
||||
<h3>Lydia Bennet</h3>
|
||||
<p class="character-role">The Youngest Sister</p>
|
||||
<p class="character-desc">
|
||||
Frivolous, flirtatious, and impulsive, causing family scandal.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="character-card">
|
||||
<div class="character-portrait wickham"></div>
|
||||
<div class="character-info">
|
||||
<h3>George Wickham</h3>
|
||||
<p class="character-role">The Antagonist</p>
|
||||
<p class="character-desc">
|
||||
Charming on the surface but deceitful and manipulative.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Themes Section -->
|
||||
<section id="themes" class="themes">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-number">03</span>
|
||||
<h2 class="section-title">Themes</h2>
|
||||
</div>
|
||||
<div class="themes-content">
|
||||
<div class="theme-item">
|
||||
<div class="theme-icon">
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path
|
||||
d="M24 44c11.046 0 20-8.954 20-20S35.046 4 24 4 4 12.954 4 24s8.954 20 20 20z"
|
||||
/>
|
||||
<path d="M24 12v20M16 24h16" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Pride</h3>
|
||||
<p>
|
||||
Darcy's pride in his social position initially prevents him from
|
||||
acknowledging his feelings for Elizabeth, while Elizabeth's pride
|
||||
in her discernment blinds her to Darcy's true character.
|
||||
</p>
|
||||
</div>
|
||||
<div class="theme-item">
|
||||
<div class="theme-icon">
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path d="M24 4l6 12 13 2-9 9 2 13-12-6-12 6 2-13-9-9 13-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Prejudice</h3>
|
||||
<p>
|
||||
Elizabeth's prejudice against Darcy, formed from their first
|
||||
meeting and Wickham's lies, nearly costs her happiness. The novel
|
||||
shows how first impressions can be misleading.
|
||||
</p>
|
||||
</div>
|
||||
<div class="theme-item">
|
||||
<div class="theme-icon">
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path
|
||||
d="M24 44c11.046 0 20-8.954 20-20S35.046 4 24 4 4 12.954 4 24s8.954 20 20 20z"
|
||||
/>
|
||||
<path
|
||||
d="M14 24c0-5.523 4.477-10 10-10s10 4.477 10 10-4.477 10-10 10"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Marriage</h3>
|
||||
<p>
|
||||
The novel examines marriage from multiple perspectives: for love,
|
||||
for security, for social advancement, and the rare ideal of
|
||||
marrying for both love and compatibility.
|
||||
</p>
|
||||
</div>
|
||||
<div class="theme-item">
|
||||
<div class="theme-icon">
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path d="M12 12h24v24H12z" />
|
||||
<path d="M12 12l24 24M36 12L12 36" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Class</h3>
|
||||
<p>
|
||||
The rigid class structure of Regency England shapes every
|
||||
interaction, from who may marry whom to how characters are judged
|
||||
by their connections and fortune.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Famous Quotes Section -->
|
||||
<section id="quotes" class="quotes">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-number">04</span>
|
||||
<h2 class="section-title">Memorable Quotes</h2>
|
||||
</div>
|
||||
<div class="quotes-slider">
|
||||
<div class="quote-card active">
|
||||
<span class="quote-mark">"</span>
|
||||
<blockquote>
|
||||
It is a truth universally acknowledged, that a single man in
|
||||
possession of a good fortune, must be in want of a wife.
|
||||
</blockquote>
|
||||
<cite>— Opening Line</cite>
|
||||
</div>
|
||||
<div class="quote-card">
|
||||
<span class="quote-mark">"</span>
|
||||
<blockquote>
|
||||
I could easily forgive his pride, if he had not mortified mine.
|
||||
</blockquote>
|
||||
<cite>— Elizabeth Bennet</cite>
|
||||
</div>
|
||||
<div class="quote-card">
|
||||
<span class="quote-mark">"</span>
|
||||
<blockquote>
|
||||
You have bewitched me, body and soul, and I love, I love, I love
|
||||
you.
|
||||
</blockquote>
|
||||
<cite>— Mr. Darcy</cite>
|
||||
</div>
|
||||
<div class="quote-card">
|
||||
<span class="quote-mark">"</span>
|
||||
<blockquote>Till this moment I never knew myself.</blockquote>
|
||||
<cite>— Elizabeth Bennet</cite>
|
||||
</div>
|
||||
<div class="quote-card">
|
||||
<span class="quote-mark">"</span>
|
||||
<blockquote>My good opinion once lost, is lost forever.</blockquote>
|
||||
<cite>— Mr. Darcy</cite>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quotes-nav">
|
||||
<button class="quote-dot active" data-index="0"></button>
|
||||
<button class="quote-dot" data-index="1"></button>
|
||||
<button class="quote-dot" data-index="2"></button>
|
||||
<button class="quote-dot" data-index="3"></button>
|
||||
<button class="quote-dot" data-index="4"></button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-content">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">P&P</span>
|
||||
<p>A timeless masterpiece of English literature</p>
|
||||
</div>
|
||||
<div class="footer-divider">
|
||||
<span class="divider-ornament">❦</span>
|
||||
</div>
|
||||
<p class="footer-credit">Based on the 1813 novel by Jane Austen</p>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="https://deerflow.tech"
|
||||
target="_blank"
|
||||
class="deerflow-signature"
|
||||
>
|
||||
<span class="signature-text">Created By Deerflow</span>
|
||||
<span class="signature-icon">✦</span>
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,180 @@
|
||||
// Pride and Prejudice - Interactive Features
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Navigation scroll effect
|
||||
initNavigation();
|
||||
|
||||
// Quotes slider
|
||||
initQuotesSlider();
|
||||
|
||||
// Scroll reveal animations
|
||||
initScrollReveal();
|
||||
|
||||
// Smooth scroll for anchor links
|
||||
initSmoothScroll();
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// NAVIGATION SCROLL EFFECT
|
||||
// ============================================
|
||||
function initNavigation() {
|
||||
const nav = document.querySelector(".nav");
|
||||
let lastScroll = 0;
|
||||
|
||||
window.addEventListener("scroll", () => {
|
||||
const currentScroll = window.pageYOffset;
|
||||
|
||||
// Add/remove scrolled class
|
||||
if (currentScroll > 100) {
|
||||
nav.classList.add("scrolled");
|
||||
} else {
|
||||
nav.classList.remove("scrolled");
|
||||
}
|
||||
|
||||
lastScroll = currentScroll;
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// QUOTES SLIDER
|
||||
// ============================================
|
||||
function initQuotesSlider() {
|
||||
const quotes = document.querySelectorAll(".quote-card");
|
||||
const dots = document.querySelectorAll(".quote-dot");
|
||||
let currentIndex = 0;
|
||||
let autoSlideInterval;
|
||||
|
||||
function showQuote(index) {
|
||||
// Remove active class from all quotes and dots
|
||||
quotes.forEach((quote) => quote.classList.remove("active"));
|
||||
dots.forEach((dot) => dot.classList.remove("active"));
|
||||
|
||||
// Add active class to current quote and dot
|
||||
quotes[index].classList.add("active");
|
||||
dots[index].classList.add("active");
|
||||
|
||||
currentIndex = index;
|
||||
}
|
||||
|
||||
function nextQuote() {
|
||||
const nextIndex = (currentIndex + 1) % quotes.length;
|
||||
showQuote(nextIndex);
|
||||
}
|
||||
|
||||
// Dot click handlers
|
||||
dots.forEach((dot, index) => {
|
||||
dot.addEventListener("click", () => {
|
||||
showQuote(index);
|
||||
resetAutoSlide();
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-slide functionality
|
||||
function startAutoSlide() {
|
||||
autoSlideInterval = setInterval(nextQuote, 6000);
|
||||
}
|
||||
|
||||
function resetAutoSlide() {
|
||||
clearInterval(autoSlideInterval);
|
||||
startAutoSlide();
|
||||
}
|
||||
|
||||
// Start auto-slide
|
||||
startAutoSlide();
|
||||
|
||||
// Pause on hover
|
||||
const slider = document.querySelector(".quotes-slider");
|
||||
slider.addEventListener("mouseenter", () => clearInterval(autoSlideInterval));
|
||||
slider.addEventListener("mouseleave", startAutoSlide);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SCROLL REVEAL ANIMATIONS
|
||||
// ============================================
|
||||
function initScrollReveal() {
|
||||
const revealElements = document.querySelectorAll(
|
||||
".about-content, .character-card, .theme-item, .section-header",
|
||||
);
|
||||
|
||||
const revealOptions = {
|
||||
threshold: 0.15,
|
||||
rootMargin: "0px 0px -50px 0px",
|
||||
};
|
||||
|
||||
const revealObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, index) => {
|
||||
if (entry.isIntersecting) {
|
||||
// Add staggered delay for grid items
|
||||
const delay =
|
||||
entry.target.classList.contains("character-card") ||
|
||||
entry.target.classList.contains("theme-item")
|
||||
? index * 100
|
||||
: 0;
|
||||
|
||||
setTimeout(() => {
|
||||
entry.target.classList.add("reveal");
|
||||
entry.target.style.opacity = "1";
|
||||
entry.target.style.transform = "translateY(0)";
|
||||
}, delay);
|
||||
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, revealOptions);
|
||||
|
||||
revealElements.forEach((el) => {
|
||||
el.style.opacity = "0";
|
||||
el.style.transform = "translateY(30px)";
|
||||
el.style.transition =
|
||||
"opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1)";
|
||||
revealObserver.observe(el);
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SMOOTH SCROLL FOR ANCHOR LINKS
|
||||
// ============================================
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute("href"));
|
||||
|
||||
if (target) {
|
||||
const navHeight = document.querySelector(".nav").offsetHeight;
|
||||
const targetPosition =
|
||||
target.getBoundingClientRect().top + window.pageYOffset - navHeight;
|
||||
|
||||
window.scrollTo({
|
||||
top: targetPosition,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// PARALLAX EFFECT FOR HERO
|
||||
// ============================================
|
||||
window.addEventListener("scroll", () => {
|
||||
const scrolled = window.pageYOffset;
|
||||
const heroPattern = document.querySelector(".hero-pattern");
|
||||
|
||||
if (heroPattern && scrolled < window.innerHeight) {
|
||||
heroPattern.style.transform = `translateY(${scrolled * 0.3}px) rotate(${scrolled * 0.02}deg)`;
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// CHARACTER CARD HOVER EFFECT
|
||||
// ============================================
|
||||
document.querySelectorAll(".character-card").forEach((card) => {
|
||||
card.addEventListener("mouseenter", function () {
|
||||
this.style.zIndex = "10";
|
||||
});
|
||||
|
||||
card.addEventListener("mouseleave", function () {
|
||||
this.style.zIndex = "1";
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,966 @@
|
||||
/* ============================================
|
||||
PRIDE AND PREJUDICE - Regency Era Aesthetic
|
||||
============================================ */
|
||||
|
||||
/* CSS Variables */
|
||||
:root {
|
||||
/* Colors - Regency Era Palette */
|
||||
--color-cream: #faf7f2;
|
||||
--color-ivory: #f5f0e8;
|
||||
--color-parchment: #ede6d6;
|
||||
--color-gold: #c9a962;
|
||||
--color-gold-light: #d4bc7e;
|
||||
--color-burgundy: #722f37;
|
||||
--color-burgundy-dark: #5a252c;
|
||||
--color-charcoal: #2c2c2c;
|
||||
--color-charcoal-light: #4a4a4a;
|
||||
--color-sage: #7d8471;
|
||||
--color-rose: #c4a4a4;
|
||||
|
||||
/* Typography */
|
||||
--font-display: "Playfair Display", Georgia, serif;
|
||||
--font-body: "Cormorant Garamond", Georgia, serif;
|
||||
|
||||
/* Spacing */
|
||||
--section-padding: 8rem;
|
||||
--container-max: 1200px;
|
||||
|
||||
/* Transitions */
|
||||
--transition-smooth: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--transition-quick: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Reset & Base */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.7;
|
||||
color: var(--color-charcoal);
|
||||
background-color: var(--color-cream);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--container-max);
|
||||
margin: 0 auto;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
NAVIGATION
|
||||
============================================ */
|
||||
.nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.5rem 3rem;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(250, 247, 242, 0.95),
|
||||
transparent
|
||||
);
|
||||
transition: var(--transition-quick);
|
||||
}
|
||||
|
||||
.nav.scrolled {
|
||||
background: rgba(250, 247, 242, 0.98);
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 1px 20px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.nav-brand {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-burgundy);
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
gap: 2.5rem;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
color: var(--color-charcoal);
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.05em;
|
||||
position: relative;
|
||||
padding-bottom: 0.25rem;
|
||||
transition: var(--transition-quick);
|
||||
}
|
||||
|
||||
.nav-links a::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 1px;
|
||||
background: var(--color-gold);
|
||||
transition: var(--transition-quick);
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--color-burgundy);
|
||||
}
|
||||
|
||||
.nav-links a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
HERO SECTION
|
||||
============================================ */
|
||||
.hero {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
var(--color-cream) 0%,
|
||||
var(--color-ivory) 50%,
|
||||
var(--color-parchment) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.hero-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-pattern {
|
||||
position: absolute;
|
||||
inset: -50%;
|
||||
background-image:
|
||||
radial-gradient(
|
||||
circle at 20% 30%,
|
||||
rgba(201, 169, 98, 0.08) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 80% 70%,
|
||||
rgba(114, 47, 55, 0.05) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 50% 50%,
|
||||
rgba(125, 132, 113, 0.03) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
animation: patternFloat 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes patternFloat {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: translate(2%, 2%) rotate(2deg);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
padding: 2rem;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.3em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-sage);
|
||||
margin-bottom: 1.5rem;
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 0.3s;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
display: block;
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(3rem, 10vw, 7rem);
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
color: var(--color-charcoal);
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 0.5s;
|
||||
}
|
||||
|
||||
.title-line:first-child {
|
||||
font-style: italic;
|
||||
color: var(--color-burgundy);
|
||||
}
|
||||
|
||||
.title-ampersand {
|
||||
display: block;
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(2rem, 5vw, 3.5rem);
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
color: var(--color-gold);
|
||||
margin: 0.5rem 0;
|
||||
opacity: 0;
|
||||
animation: fadeInScale 1s ease forwards 0.7s;
|
||||
}
|
||||
|
||||
@keyframes fadeInScale {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-author {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(1.25rem, 3vw, 1.75rem);
|
||||
font-weight: 400;
|
||||
color: var(--color-charcoal-light);
|
||||
letter-spacing: 0.15em;
|
||||
margin-bottom: 0.5rem;
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 0.9s;
|
||||
}
|
||||
|
||||
.hero-year {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
color: var(--color-sage);
|
||||
letter-spacing: 0.2em;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 1s;
|
||||
}
|
||||
|
||||
.hero-divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 1.1s;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
width: 60px;
|
||||
height: 1px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
var(--color-gold),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.divider-ornament {
|
||||
color: var(--color-gold);
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.hero-tagline {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1.25rem;
|
||||
font-style: italic;
|
||||
color: var(--color-charcoal-light);
|
||||
margin-bottom: 3rem;
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 1.2s;
|
||||
}
|
||||
|
||||
.hero-cta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-burgundy);
|
||||
text-decoration: none;
|
||||
padding: 1rem 2rem;
|
||||
border: 1px solid var(--color-burgundy);
|
||||
transition: var(--transition-smooth);
|
||||
opacity: 0;
|
||||
animation: fadeInUp 1s ease forwards 1.3s;
|
||||
}
|
||||
|
||||
.hero-cta:hover {
|
||||
background: var(--color-burgundy);
|
||||
color: var(--color-cream);
|
||||
}
|
||||
|
||||
.hero-cta:hover .cta-arrow {
|
||||
transform: translateY(4px);
|
||||
}
|
||||
|
||||
.cta-arrow {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transition: var(--transition-quick);
|
||||
}
|
||||
|
||||
.hero-scroll-indicator {
|
||||
position: absolute;
|
||||
bottom: 3rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
opacity: 0;
|
||||
animation: fadeIn 1s ease forwards 1.5s;
|
||||
}
|
||||
|
||||
.scroll-line {
|
||||
width: 1px;
|
||||
height: 60px;
|
||||
background: linear-gradient(to bottom, var(--color-gold), transparent);
|
||||
animation: scrollPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes scrollPulse {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
SECTION HEADERS
|
||||
============================================ */
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 4rem;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid rgba(201, 169, 98, 0.3);
|
||||
}
|
||||
|
||||
.section-number {
|
||||
font-family: var(--font-display);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
color: var(--color-gold);
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 400;
|
||||
color: var(--color-charcoal);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
ABOUT SECTION
|
||||
============================================ */
|
||||
.about {
|
||||
padding: var(--section-padding) 0;
|
||||
background: var(--color-cream);
|
||||
}
|
||||
|
||||
.about-content {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 4rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.about-text {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.about-lead {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: var(--color-burgundy);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.about-text p {
|
||||
margin-bottom: 1.25rem;
|
||||
color: var(--color-charcoal-light);
|
||||
}
|
||||
|
||||
.about-text em {
|
||||
font-style: italic;
|
||||
color: var(--color-charcoal);
|
||||
}
|
||||
|
||||
.about-stats {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
padding: 2rem;
|
||||
background: var(--color-ivory);
|
||||
border-left: 3px solid var(--color-gold);
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-family: var(--font-display);
|
||||
font-size: 2.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-burgundy);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-sage);
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
CHARACTERS SECTION
|
||||
============================================ */
|
||||
.characters {
|
||||
padding: var(--section-padding) 0;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--color-ivory),
|
||||
var(--color-cream)
|
||||
);
|
||||
}
|
||||
|
||||
.characters-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.character-card {
|
||||
background: var(--color-cream);
|
||||
border: 1px solid rgba(201, 169, 98, 0.2);
|
||||
overflow: hidden;
|
||||
transition: var(--transition-smooth);
|
||||
}
|
||||
|
||||
.character-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
|
||||
border-color: var(--color-gold);
|
||||
}
|
||||
|
||||
.character-card.featured {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
.character-portrait {
|
||||
height: 200px;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
var(--color-parchment) 0%,
|
||||
var(--color-ivory) 100%
|
||||
);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.character-portrait::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(
|
||||
circle at 30% 30%,
|
||||
rgba(201, 169, 98, 0.15) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
}
|
||||
|
||||
.character-portrait.elizabeth::after {
|
||||
content: "👒";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 4rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.character-portrait.darcy::after {
|
||||
content: "🎩";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 4rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.character-portrait.jane::after {
|
||||
content: "🌸";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.character-portrait.bingley::after {
|
||||
content: "🎭";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.character-portrait.lydia::after {
|
||||
content: "💃";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.character-portrait.wickham::after {
|
||||
content: "🎪";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.character-info {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.character-info h3 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 500;
|
||||
color: var(--color-charcoal);
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.character-role {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
color: var(--color-gold);
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.character-desc {
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-charcoal-light);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
THEMES SECTION
|
||||
============================================ */
|
||||
.themes {
|
||||
padding: var(--section-padding) 0;
|
||||
background: var(--color-charcoal);
|
||||
color: var(--color-cream);
|
||||
}
|
||||
|
||||
.themes .section-title {
|
||||
color: var(--color-cream);
|
||||
}
|
||||
|
||||
.themes .section-header {
|
||||
border-bottom-color: rgba(201, 169, 98, 0.2);
|
||||
}
|
||||
|
||||
.themes-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.theme-item {
|
||||
padding: 2.5rem;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid rgba(201, 169, 98, 0.15);
|
||||
transition: var(--transition-smooth);
|
||||
}
|
||||
|
||||
.theme-item:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: var(--color-gold);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.theme-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--color-gold);
|
||||
}
|
||||
|
||||
.theme-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.theme-item h3 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
color: var(--color-cream);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.theme-item p {
|
||||
font-size: 1rem;
|
||||
color: rgba(250, 247, 242, 0.7);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
QUOTES SECTION
|
||||
============================================ */
|
||||
.quotes {
|
||||
padding: var(--section-padding) 0;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
var(--color-parchment) 0%,
|
||||
var(--color-ivory) 100%
|
||||
);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.quotes::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23c9a962' fill-opacity='0.05'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.quotes-slider {
|
||||
position: relative;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.quote-card {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
opacity: 0;
|
||||
transform: translateX(50px);
|
||||
transition: var(--transition-smooth);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.quote-card.active {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.quote-mark {
|
||||
font-family: var(--font-display);
|
||||
font-size: 6rem;
|
||||
color: var(--color-gold);
|
||||
opacity: 0.3;
|
||||
line-height: 1;
|
||||
display: block;
|
||||
margin-bottom: -2rem;
|
||||
}
|
||||
|
||||
.quote-card blockquote {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(1.5rem, 4vw, 2.25rem);
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
color: var(--color-charcoal);
|
||||
line-height: 1.5;
|
||||
max-width: 800px;
|
||||
margin: 0 auto 1.5rem;
|
||||
}
|
||||
|
||||
.quote-card cite {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-style: normal;
|
||||
color: var(--color-sage);
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.quotes-nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.quote-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--color-gold);
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: var(--transition-quick);
|
||||
}
|
||||
|
||||
.quote-dot.active {
|
||||
background: var(--color-gold);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.quote-dot:hover {
|
||||
background: var(--color-gold-light);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
FOOTER
|
||||
============================================ */
|
||||
.footer {
|
||||
padding: 4rem 0;
|
||||
background: var(--color-charcoal);
|
||||
color: var(--color-cream);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
font-family: var(--font-display);
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-gold);
|
||||
letter-spacing: 0.15em;
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.footer-brand p {
|
||||
font-size: 1rem;
|
||||
color: rgba(250, 247, 242, 0.6);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.footer-divider {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.footer-divider .divider-ornament {
|
||||
color: var(--color-gold);
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.footer-credit {
|
||||
font-size: 0.875rem;
|
||||
color: rgba(250, 247, 242, 0.5);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Deerflow Signature */
|
||||
.deerflow-signature {
|
||||
position: fixed;
|
||||
bottom: 1.5rem;
|
||||
right: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-sage);
|
||||
text-decoration: none;
|
||||
padding: 0.5rem 1rem;
|
||||
background: rgba(250, 247, 242, 0.9);
|
||||
border: 1px solid rgba(201, 169, 98, 0.3);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
transition: var(--transition-quick);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.deerflow-signature:hover {
|
||||
color: var(--color-burgundy);
|
||||
border-color: var(--color-gold);
|
||||
box-shadow: 0 4px 15px rgba(201, 169, 98, 0.2);
|
||||
}
|
||||
|
||||
.signature-icon {
|
||||
color: var(--color-gold);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RESPONSIVE DESIGN
|
||||
============================================ */
|
||||
@media (max-width: 1024px) {
|
||||
.characters-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.about-content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.about-stats {
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
border-left: none;
|
||||
border-top: 3px solid var(--color-gold);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--section-padding: 5rem;
|
||||
}
|
||||
|
||||
.nav {
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.characters-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.themes-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.deerflow-signature {
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
padding: 0.4rem 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.container {
|
||||
padding: 0 1.25rem;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.about-stats {
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.theme-item {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
SCROLL REVEAL ANIMATIONS
|
||||
============================================ */
|
||||
.reveal {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
transition: var(--transition-smooth);
|
||||
}
|
||||
|
||||
.reveal.active {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
# Diana Hu: Technical Startup Founder Advice - Comprehensive Research
|
||||
|
||||
## Video Overview
|
||||
|
||||
**Title:** Tips For Technical Startup Founders | Startup School
|
||||
**Speaker:** Diana Hu, Y Combinator Group Partner
|
||||
**Date:** April 21, 2023
|
||||
**Length:** 28 minutes
|
||||
**YouTube URL:** https://www.youtube.com/watch?v=rP7bpYsfa6Q
|
||||
|
||||
## Speaker Background
|
||||
|
||||
### Education
|
||||
|
||||
- **BS and MS in Electrical and Computer Engineering** from Carnegie Mellon University
|
||||
- Focus on **computer vision and machine learning**
|
||||
- Originally from Chile
|
||||
|
||||
### Career Path
|
||||
|
||||
1. **Co-founder & CTO of Escher Reality** (YC S17)
|
||||
- Startup building augmented reality SDK for game developers
|
||||
- Company acquired by Niantic (makers of Pokémon Go) in February 2018
|
||||
|
||||
2. **Director of Engineering at Niantic**
|
||||
- Headed AR platform after acquisition
|
||||
- Responsible for scaling AR infrastructure to millions of users
|
||||
|
||||
3. **Group Partner at Y Combinator** (Current)
|
||||
- Has conducted **over 1,700 office hours** across 5 batches
|
||||
- Advises top YC alumni companies
|
||||
- Specializes in technical founder guidance
|
||||
|
||||
### Key Achievements
|
||||
|
||||
- Successfully built and sold AR startup to Niantic
|
||||
- Scaled systems from prototype to millions of users
|
||||
- Extensive experience mentoring technical founders
|
||||
|
||||
## Escher Reality Acquisition
|
||||
|
||||
- **Founded:** 2016
|
||||
- **Y Combinator Batch:** Summer 2017 (S17)
|
||||
- **Product:** Augmented Reality backend/SDK for cross-platform mobile AR
|
||||
- **Acquisition:** February 1, 2018 by Niantic
|
||||
- **Terms:** Undisclosed, but both co-founders (Ross Finman and Diana Hu) joined Niantic
|
||||
- **Technology:** Persistent, cross-platform, multi-user AR experiences
|
||||
- **Impact:** Accelerated Niantic's work on planet-scale AR platform
|
||||
|
||||
## Video Content Analysis
|
||||
|
||||
### Three Stages of Technical Founder Journey
|
||||
|
||||
#### Stage 1: Ideating (0:00-8:30)
|
||||
|
||||
**Goal:** Build a prototype as soon as possible (matter of days)
|
||||
|
||||
**Key Principles:**
|
||||
|
||||
- Build something to show/demo to users
|
||||
- Doesn't have to work fully
|
||||
- CEO co-founder should be finding users to show prototype
|
||||
|
||||
**Examples:**
|
||||
|
||||
1. **Optimizely** (YC W10)
|
||||
- Built prototype in couple of days
|
||||
- JavaScript file on S3 for A/B testing
|
||||
- Manual execution via Chrome console
|
||||
|
||||
2. **Escher Reality** (Diana's company)
|
||||
- Computer vision algorithms on phones
|
||||
- Demo completed in few weeks
|
||||
- Visual demo easier than explaining
|
||||
|
||||
3. **Remora** (YC W21)
|
||||
- Carbon capture for semi-trucks
|
||||
- Used 3D renderings to show promise
|
||||
- Enough to get users excited despite hard tech
|
||||
|
||||
**Common Mistakes:**
|
||||
|
||||
- Overbuilding at this stage
|
||||
- Not talking/listening to users soon enough
|
||||
- Getting too attached to initial ideas
|
||||
|
||||
#### Stage 2: Building MVP (8:30-19:43)
|
||||
|
||||
**Goal:** Build to launch quickly (weeks, not months)
|
||||
|
||||
**Key Principles:**
|
||||
|
||||
1. **Do Things That Don't Scale** (Paul Graham)
|
||||
- Manual onboarding (editing database directly)
|
||||
- Founders processing requests manually
|
||||
- Example: Stripe founders filling bank forms manually
|
||||
|
||||
2. **Create 90/10 Solution** (Paul Buchheit)
|
||||
- Get 90% of value with 10% of effort
|
||||
- Restrict product to limited dimensions
|
||||
- Push features to post-launch
|
||||
|
||||
3. **Choose Tech for Iteration Speed**
|
||||
- Balance product needs with personal expertise
|
||||
- Use third-party frameworks and APIs
|
||||
- Don't build from scratch
|
||||
|
||||
**Examples:**
|
||||
|
||||
1. **DoorDash** (originally Palo Alto Delivery)
|
||||
- Static HTML with PDF menus
|
||||
- Google Forms for orders
|
||||
- "Find My Friends" to track deliveries
|
||||
- Built in one afternoon
|
||||
- Focused only on Palo Alto initially
|
||||
|
||||
2. **WayUp** (YC 2015)
|
||||
- CTO JJ chose Django/Python over Ruby/Rails
|
||||
- Prioritized iteration speed over popular choice
|
||||
- Simple stack: Postgres, Python, Heroku
|
||||
|
||||
3. **Justin TV/Twitch**
|
||||
- Four founders (three technical)
|
||||
- Each tackled different parts: video streaming, database, web
|
||||
- Hired "misfits" overlooked by Google
|
||||
|
||||
**Tech Stack Philosophy:**
|
||||
|
||||
- "If you build a company and it works, tech choices don't matter as much"
|
||||
- Facebook: PHP → HipHop transpiler
|
||||
- JavaScript: V8 engine optimization
|
||||
- Choose what you're dangerous enough with
|
||||
|
||||
#### Stage 3: Launch Stage (19:43-26:51)
|
||||
|
||||
**Goal:** Iterate towards product-market fit
|
||||
|
||||
**Key Principles:**
|
||||
|
||||
1. **Quickly Iterate with Hard and Soft Data**
|
||||
- Set up simple analytics dashboard (Google Analytics, Amplitude, Mixpanel)
|
||||
- Keep talking to users
|
||||
- Marry data with user insights
|
||||
|
||||
2. **Continuously Launch**
|
||||
- Example: Segment launched 5 times in one month
|
||||
- Each launch added features based on user feedback
|
||||
- Weekly launches to maintain momentum
|
||||
|
||||
3. **Balance Building vs Fixing**
|
||||
- Tech debt is totally fine early on
|
||||
- "Feel the heat of your tech burning"
|
||||
- Fix only what prevents product-market fit
|
||||
|
||||
**Examples:**
|
||||
|
||||
1. **WePay** (YC company)
|
||||
- Started as B2C payments (Venmo-like)
|
||||
- Analytics showed features unused
|
||||
- User interviews revealed GoFundMe needed API
|
||||
- Pivoted to API product
|
||||
|
||||
2. **Pokémon Go Launch**
|
||||
- Massive scaling issues on day 1
|
||||
- Load balancer problems caused DDoS-like situation
|
||||
- Didn't kill the company (made $1B+ revenue)
|
||||
- "Breaking because of too much demand is a good thing"
|
||||
|
||||
3. **Segment**
|
||||
- December 2012: First launch on Hacker News
|
||||
- Weekly launches adding features
|
||||
- Started with Google Analytics, Mixpanel, Intercom support
|
||||
- Added Node, PHP, WordPress support based on feedback
|
||||
|
||||
### Role Evolution Post Product-Market Fit
|
||||
|
||||
- **2-5 engineers:** 70% coding time
|
||||
- **5-10 engineers:** <50% coding time
|
||||
- **Beyond 10 engineers:** Little to no coding time
|
||||
- Decision point: Architect role vs People/VP role
|
||||
|
||||
## Key Concepts Deep Dive
|
||||
|
||||
### 90/10 Solution (Paul Buchheit)
|
||||
|
||||
- Find ways to get 90% of the value with 10% of the effort
|
||||
- Available 90% solution now is better than 100% solution later
|
||||
- Restrict product dimensions: geography, user type, data type, functionality
|
||||
|
||||
### Technical Debt in Startups
|
||||
|
||||
- **Early stage:** Embrace technical debt
|
||||
- **Post product-market fit:** Address scaling issues
|
||||
- **Philosophy:** "Tech debt is totally fine - feel the heat of your tech burning"
|
||||
- Only fix what prevents reaching product-market fit
|
||||
|
||||
### MVP Principles
|
||||
|
||||
1. **Speed over perfection:** Launch in weeks, not months
|
||||
2. **Manual processes:** Founders do unscalable work
|
||||
3. **Limited scope:** Constrain to prove core value
|
||||
4. **Iterative validation:** Launch, learn, iterate
|
||||
|
||||
## Companies Mentioned (with Context)
|
||||
|
||||
### Optimizely (YC W10)
|
||||
|
||||
- A/B testing platform
|
||||
- Prototype: JavaScript file on S3, manual execution
|
||||
- Founders: Pete Koomen and Dan Siroker
|
||||
- Dan previously headed analytics for Obama campaign
|
||||
|
||||
### Remora (YC W21)
|
||||
|
||||
- Carbon capture device for semi-trucks
|
||||
- Prototype: 3D renderings to demonstrate concept
|
||||
- Captures 80%+ of truck emissions
|
||||
- Can make trucks carbon-negative with biofuels
|
||||
|
||||
### Justin TV/Twitch
|
||||
|
||||
- Live streaming platform → gaming focus
|
||||
- Founders: Justin Kan, Emmett Shear, Michael Seibel, Kyle Vogt
|
||||
- MVP built by 4 founders (3 technical)
|
||||
- Hired overlooked engineers from Google
|
||||
|
||||
### Stripe
|
||||
|
||||
- Payment processing API
|
||||
- Early days: Founders manually processed payments
|
||||
- Filled bank forms manually for each transaction
|
||||
- Classic "do things that don't scale" example
|
||||
|
||||
### DoorDash
|
||||
|
||||
- Originally "Palo Alto Delivery"
|
||||
- Static HTML with PDF menus
|
||||
- Google Forms for orders
|
||||
- "Find My Friends" for delivery tracking
|
||||
- Focused on suburbs vs metro areas (competitive advantage)
|
||||
|
||||
### WayUp (YC 2015)
|
||||
|
||||
- Job board for college students
|
||||
- CTO JJ chose Django/Python over Ruby/Rails
|
||||
- Prioritized iteration speed over popular choice
|
||||
- Simple, effective tech stack
|
||||
|
||||
### WePay (YC company)
|
||||
|
||||
- Started as B2C payments (Venmo competitor)
|
||||
- Pivoted to API after user discovery
|
||||
- GoFundMe became key customer
|
||||
- Example of data + user interviews driving pivot
|
||||
|
||||
### Segment
|
||||
|
||||
- Analytics infrastructure
|
||||
- Multiple launches in short timeframe
|
||||
- Started with limited integrations
|
||||
- Added features based on user requests
|
||||
- Acquired by Twilio for $3.2B
|
||||
|
||||
### Algolia
|
||||
|
||||
- Search API mentioned as YC success
|
||||
- Part of Diana's network of advised companies
|
||||
|
||||
## Actionable Advice for Technical Founders
|
||||
|
||||
### Immediate Actions (Week 1)
|
||||
|
||||
1. **Build clickable prototype** (Figma, InVision) in 1-3 days
|
||||
2. **Find 10 potential users** to show prototype
|
||||
3. **Use existing tools** rather than building from scratch
|
||||
4. **Embrace ugly code** - it's temporary
|
||||
|
||||
### Tech Stack Selection
|
||||
|
||||
1. **Choose familiarity over trendiness**
|
||||
2. **Use third-party services** for non-core functions
|
||||
3. **Keep infrastructure simple** (Heroku, Firebase, AWS)
|
||||
4. **Only build what's unique** to your value proposition
|
||||
|
||||
### Hiring Strategy
|
||||
|
||||
1. **Don't hire too early** (slows you down)
|
||||
2. **Founders must build** to gain product insights
|
||||
3. **Look for "misfits"** - overlooked talent
|
||||
4. **Post product-market fit:** Scale team strategically
|
||||
|
||||
### Launch Strategy
|
||||
|
||||
1. **Launch multiple times** (weekly iterations)
|
||||
2. **Combine analytics with user interviews**
|
||||
3. **Balance feature development with bug fixes**
|
||||
4. **Accept technical debt** until product-market fit
|
||||
|
||||
### Mindset Shifts
|
||||
|
||||
1. **From perfectionist to pragmatist**
|
||||
2. **From specialist to generalist** (do whatever it takes)
|
||||
3. **From employee to owner** (no task beneath you)
|
||||
4. **From certainty to comfort with ambiguity**
|
||||
|
||||
## Diana's Personal Insights
|
||||
|
||||
### From Her Experience
|
||||
|
||||
- "Technical founder is committed to the success of your company"
|
||||
- "Do whatever it takes to get it to work"
|
||||
- "Your product will evolve - if someone else builds it, you miss key learnings"
|
||||
- "The only tech choices that matter are tied to customer promises"
|
||||
|
||||
### Common Traps to Avoid
|
||||
|
||||
1. **"What would Google do?"** - Building like a big company too early
|
||||
2. **Hiring to move faster** - Actually slows you down initially
|
||||
3. **Over-fixing vs building** - Focus on product-market fit first
|
||||
4. **Building features without user insights** - Keep talking to users
|
||||
|
||||
## Resources & References
|
||||
|
||||
### YC Resources
|
||||
|
||||
- Y Combinator Library: "Tips for technical startup founders"
|
||||
- Paul Graham Essay: "Do Things That Don't Scale"
|
||||
- Paul Buchheit Concept: "90/10 Solution"
|
||||
- Startup School: Technical founder track
|
||||
|
||||
### Tools Mentioned
|
||||
|
||||
- **Prototyping:** Figma, InVision
|
||||
- **Analytics:** Google Analytics, Amplitude, Mixpanel
|
||||
- **Infrastructure:** Heroku, Firebase, AWS, GCP
|
||||
- **Authentication:** Auth0
|
||||
- **Payments:** Stripe
|
||||
- **Landing Pages:** Webflow
|
||||
|
||||
### Further Reading
|
||||
|
||||
1. Paul Graham essays (paulgraham.com)
|
||||
2. Y Combinator Startup School materials
|
||||
3. Case studies: Stripe, DoorDash, Segment early days
|
||||
4. Technical debt management in startups
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
### For Technical Founders
|
||||
|
||||
1. **Speed is your superpower** - Move faster than established companies
|
||||
2. **Embrace imperfection** - Good enough beats perfect when speed matters
|
||||
3. **Stay close to users** - Insights come from conversations, not just data
|
||||
4. **Tech debt is a feature, not a bug** - Early stage startups should accumulate it
|
||||
|
||||
### For Startup Strategy
|
||||
|
||||
1. **Constrained focus** leads to better unit economics (DoorDash example)
|
||||
2. **Manual processes** create customer intimacy and learning
|
||||
3. **Continuous launching** builds momentum and feedback loops
|
||||
4. **Break things at scale** is a good problem to have
|
||||
|
||||
### For Team Building
|
||||
|
||||
1. **Founders build first** - Critical for product insights
|
||||
2. **Hire for adaptability** over pedigree
|
||||
3. **Evolve role with growth** - Coding time decreases with team size
|
||||
4. **Culture emerges** from early team composition
|
||||
|
||||
---
|
||||
|
||||
_Research compiled from YouTube transcript, web searches, and Y Combinator resources. Last updated: January 25, 2026_
|
||||
@@ -0,0 +1,261 @@
|
||||
# DeerFlow Deep Research Report
|
||||
|
||||
- **Research Date:** 2026-02-01
|
||||
- **Timestamp:** 2026-02-01, Sunday
|
||||
- **Confidence Level:** High (90%+)
|
||||
- **Subject:** ByteDance's Open-Source Multi-Agent Deep Research Framework
|
||||
|
||||
---
|
||||
|
||||
## Repository Information
|
||||
|
||||
- **Name:** bytedance/deer-flow
|
||||
- **Description:** DeerFlow is a community-driven Deep Research framework, combining language models with tools like web search, crawling, and Python execution, while contributing back to the open-source community [DeerFlow GitHub Repository](https://github.com/bytedance/deer-flow)
|
||||
- **URL:** https://github.com/bytedance/deer-flow
|
||||
- **Stars:** 19,531
|
||||
- **Forks:** 2,452
|
||||
- **Open Issues:** 196
|
||||
- **Language(s):** Python (1,292,574 bytes), TypeScript (503,143 bytes), CSS (15,128 bytes), JavaScript (7,906 bytes), Dockerfile (2,197 bytes), Makefile (1,352 bytes), Shell (1,152 bytes), Batchfile (497 bytes)
|
||||
- **License:** MIT
|
||||
- **Created At:** 2025-05-07T02:50:19Z
|
||||
- **Updated At:** 2026-02-01T01:07:38Z
|
||||
- **Pushed At:** 2026-01-30T00:47:23Z
|
||||
- **Topics:** agent, agentic, agentic-framework, agentic-workflow, ai, ai-agents, bytedance, deep-research, langchain, langgraph, langmanus, llm, multi-agent, nodejs, podcast, python, typescript
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
DeerFlow (Deep Exploration and Efficient Research Flow) is an open-source multi-agent research automation framework developed by ByteDance and released under the MIT license in May 2025 [Create Your Own Deep Research Agent with DeerFlow](https://thesequence.substack.com/p/the-sequence-engineering-661-create). The framework implements a graph-based orchestration of specialized agents that automate research pipelines end-to-end, combining language models with tools like web search engines, crawlers, and Python execution. With 19,531 stars and 2,452 forks on GitHub, DeerFlow has established itself as a significant player in the deep research automation space, offering both console and web UI options with support for local LLM deployment and extensive tool integrations [DeerFlow: A Game-Changer for Automated Research and Content Creation](https://medium.com/@mingyang.heaven/deerflow-a-game-changer-for-automated-research-and-content-creation-83612f683e7a).
|
||||
|
||||
---
|
||||
|
||||
## Complete Chronological Timeline
|
||||
|
||||
### PHASE 1: Project Inception and Initial Development
|
||||
|
||||
#### May 2025 - July 2025
|
||||
|
||||
DeerFlow was created by ByteDance and open-sourced on May 7, 2025, with the initial commit establishing the core multi-agent architecture built on LangGraph and LangChain frameworks [DeerFlow GitHub Repository](https://github.com/bytedance/deer-flow). The project quickly gained traction in the AI community due to its comprehensive approach to research automation, combining web search, crawling, and code execution capabilities. Early development focused on establishing the modular agent system with specialized roles including Coordinator, Planner, Researcher, Coder, and Reporter components.
|
||||
|
||||
### PHASE 2: Feature Expansion and Community Growth
|
||||
|
||||
#### August 2025 - December 2025
|
||||
|
||||
During this period, DeerFlow underwent significant feature expansion including MCP (Model Context Protocol) integration, text-to-speech capabilities, podcast generation, and support for multiple search engines (Tavily, InfoQuest, Brave Search, DuckDuckGo, Arxiv) [DeerFlow: Multi-Agent AI For Research Automation 2025](https://firexcore.com/blog/what-is-deerflow/). The framework gained attention for its human-in-the-loop collaboration features, allowing users to review and edit research plans before execution. Community contributions grew substantially, with 88 contributors participating in the project by early 2026, and the framework was integrated into the FaaS Application Center of Volcengine for cloud deployment.
|
||||
|
||||
### PHASE 3: Maturity and DeerFlow 2.0 Transition
|
||||
|
||||
#### January 2026 - Present
|
||||
|
||||
As of February 2026, DeerFlow has entered a transition phase to DeerFlow 2.0, with active development continuing on the main branch [DeerFlow Official Website](https://deerflow.tech/). Recent commits show ongoing improvements to JSON repair handling, MCP tool integration, and fallback report generation mechanisms. The framework now supports private knowledgebases including RAGFlow, Qdrant, Milvus, and VikingDB, along with Docker and Docker Compose deployment options for production environments.
|
||||
|
||||
---
|
||||
|
||||
## Key Analysis
|
||||
|
||||
### Technical Architecture and Design Philosophy
|
||||
|
||||
DeerFlow implements a modular multi-agent system architecture designed for automated research and code analysis [DeerFlow: A Game-Changer for Automated Research and Content Creation](https://medium.com/@mingyang.heaven/deerflow-a-game-changer-for-automated-research-and-content-creation-83612f683e7a). The system is built on LangGraph, enabling a flexible state-based workflow where components communicate through a well-defined message passing system. The architecture employs a streamlined workflow with specialized agents:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Coordinator] --> B[Planner]
|
||||
B --> C{Enough Context?}
|
||||
C -->|No| D[Research Team]
|
||||
D --> E[Researcher<br/>Web Search & Crawling]
|
||||
D --> F[Coder<br/>Python Execution]
|
||||
E --> C
|
||||
F --> C
|
||||
C -->|Yes| G[Reporter]
|
||||
G --> H[Final Report]
|
||||
```
|
||||
|
||||
The Coordinator serves as the entry point managing workflow lifecycle, initiating research processes based on user input and delegating tasks to the Planner when appropriate. The Planner analyzes research objectives and creates structured execution plans, determining if sufficient context is available or if more research is needed. The Research Team consists of specialized agents including a Researcher for web searches and information gathering, and a Coder for handling technical tasks using Python REPL tools. Finally, the Reporter aggregates findings and generates comprehensive research reports [Create Your Own Deep Research Agent with DeerFlow](https://thesequence.substack.com/p/the-sequence-engineering-661-create).
|
||||
|
||||
### Core Features and Capabilities
|
||||
|
||||
DeerFlow offers extensive capabilities for deep research automation:
|
||||
|
||||
1. **Multi-Engine Search Integration**: Supports Tavily (default), InfoQuest (BytePlus's AI-optimized search), Brave Search, DuckDuckGo, and Arxiv for scientific papers [DeerFlow: Multi-Agent AI For Research Automation 2025](https://firexcore.com/blog/what-is-deerflow/).
|
||||
|
||||
2. **Advanced Crawling Tools**: Includes Jina (default) and InfoQuest crawlers with configurable parameters, timeout settings, and powerful content extraction capabilities.
|
||||
|
||||
3. **MCP (Model Context Protocol) Integration**: Enables seamless integration with diverse research tools and methodologies for private domain access, knowledge graphs, and web browsing.
|
||||
|
||||
4. **Private Knowledgebase Support**: Integrates with RAGFlow, Qdrant, Milvus, VikingDB, MOI, and Dify for research on users' private documents.
|
||||
|
||||
5. **Human-in-the-Loop Collaboration**: Features intelligent clarification mechanisms, plan review and editing capabilities, and auto-acceptance options for streamlined workflows.
|
||||
|
||||
6. **Content Creation Tools**: Includes podcast generation with text-to-speech synthesis, PowerPoint presentation creation, and Notion-style block editing for report refinement.
|
||||
|
||||
7. **Multi-Language Support**: Provides README documentation in English, Simplified Chinese, Japanese, German, Spanish, Russian, and Portuguese.
|
||||
|
||||
### Development and Community Ecosystem
|
||||
|
||||
The project demonstrates strong community engagement with 88 contributors and 19,531 GitHub stars as of February 2026 [DeerFlow GitHub Repository](https://github.com/bytedance/deer-flow). Key contributors include Henry Li (203 contributions), Willem Jiang (130 contributions), and Daniel Walnut (25 contributions), representing a mix of ByteDance employees and open-source community members. The framework maintains comprehensive documentation including configuration guides, API documentation, FAQ sections, and multiple example research reports covering topics from quantum computing to AI adoption in healthcare.
|
||||
|
||||
---
|
||||
|
||||
## Metrics & Impact Analysis
|
||||
|
||||
### Growth Trajectory
|
||||
|
||||
```
|
||||
Timeline: May 2025 - February 2026
|
||||
Stars: 0 → 19,531 (exponential growth)
|
||||
Forks: 0 → 2,452 (strong community adoption)
|
||||
Contributors: 0 → 88 (active development ecosystem)
|
||||
Open Issues: 196 (ongoing maintenance and feature development)
|
||||
```
|
||||
|
||||
### Key Metrics
|
||||
|
||||
| Metric | Value | Assessment |
|
||||
| ------------------ | ------------------ | --------------------------------------------------- |
|
||||
| GitHub Stars | 19,531 | Exceptional popularity for research framework |
|
||||
| Forks | 2,452 | Strong community adoption and potential derivatives |
|
||||
| Contributors | 88 | Healthy open-source development ecosystem |
|
||||
| Open Issues | 196 | Active maintenance and feature development |
|
||||
| Primary Language | Python (1.29MB) | Main development language with extensive libraries |
|
||||
| Secondary Language | TypeScript (503KB) | Modern web UI implementation |
|
||||
| Repository Age | ~9 months | Rapid development and feature expansion |
|
||||
| License | MIT | Permissive open-source licensing |
|
||||
|
||||
---
|
||||
|
||||
## Comparative Analysis
|
||||
|
||||
### Feature Comparison
|
||||
|
||||
| Feature | DeerFlow | OpenAI Deep Research | LangChain OpenDeepResearch |
|
||||
| ------------------------ | --------------- | -------------------- | -------------------------- |
|
||||
| Multi-Agent Architecture | ✅ | ❌ | ✅ |
|
||||
| Local LLM Support | ✅ | ❌ | ✅ |
|
||||
| MCP Integration | ✅ | ❌ | ❌ |
|
||||
| Web Search Engines | Multiple (5+) | Limited | Limited |
|
||||
| Code Execution | ✅ Python REPL | Limited | ✅ |
|
||||
| Podcast Generation | ✅ | ❌ | ❌ |
|
||||
| Presentation Creation | ✅ | ❌ | ❌ |
|
||||
| Private Knowledgebase | ✅ (6+ options) | Limited | Limited |
|
||||
| Human-in-the-Loop | ✅ | Limited | ✅ |
|
||||
| Open Source | ✅ MIT | ❌ | ✅ Apache 2.0 |
|
||||
|
||||
### Market Positioning
|
||||
|
||||
DeerFlow occupies a unique position in the deep research framework landscape by combining enterprise-grade multi-agent orchestration with extensive tool integrations and open-source accessibility [Navigating the Landscape of Deep Research Frameworks](https://www.oreateai.com/blog/navigating-the-landscape-of-deep-research-frameworks-a-comprehensive-comparison/0dc13e48eb8c756650112842c8d1a184]. While proprietary solutions like OpenAI's Deep Research offer polished user experiences, DeerFlow provides greater flexibility through local deployment options, custom tool integration, and community-driven development. The framework particularly excels in scenarios requiring specialized research workflows, integration with private data sources, or deployment in regulated environments where cloud-based solutions may not be feasible.
|
||||
|
||||
---
|
||||
|
||||
## Strengths & Weaknesses
|
||||
|
||||
### Strengths
|
||||
|
||||
1. **Comprehensive Multi-Agent Architecture**: DeerFlow's sophisticated agent orchestration enables complex research workflows beyond single-agent systems [Create Your Own Deep Research Agent with DeerFlow](https://thesequence.substack.com/p/the-sequence-engineering-661-create).
|
||||
|
||||
2. **Extensive Tool Integration**: Support for multiple search engines, crawling tools, MCP services, and private knowledgebases provides unmatched flexibility.
|
||||
|
||||
3. **Local Deployment Capabilities**: Unlike many proprietary solutions, DeerFlow supports local LLM deployment, offering privacy, cost control, and customization options.
|
||||
|
||||
4. **Human Collaboration Features**: Intelligent clarification mechanisms and plan editing capabilities bridge the gap between automated research and human oversight.
|
||||
|
||||
5. **Active Community Development**: With 88 contributors and regular updates, the project benefits from diverse perspectives and rapid feature evolution.
|
||||
|
||||
6. **Production-Ready Deployment**: Docker support, cloud integration (Volcengine), and comprehensive documentation facilitate enterprise adoption.
|
||||
|
||||
### Areas for Improvement
|
||||
|
||||
1. **Learning Curve**: The extensive feature set and configuration options may present challenges for new users compared to simpler single-purpose tools.
|
||||
|
||||
2. **Resource Requirements**: Local deployment with multiple agents and tools may demand significant computational resources.
|
||||
|
||||
3. **Documentation Complexity**: While comprehensive, the documentation spans multiple languages and may benefit from more streamlined onboarding guides.
|
||||
|
||||
4. **Integration Complexity**: Advanced features like MCP integration and custom tool development require technical expertise beyond basic usage.
|
||||
|
||||
5. **Version Transition**: The ongoing move to DeerFlow 2.0 may create temporary instability or compatibility concerns for existing deployments.
|
||||
|
||||
---
|
||||
|
||||
## Key Success Factors
|
||||
|
||||
1. **ByteDance Backing**: Corporate sponsorship provides resources, expertise, and credibility while maintaining open-source accessibility [DeerFlow: A Game-Changer for Automated Research and Content Creation](https://medium.com/@mingyang.heaven/deerflow-a-game-changer-for-automated-research-and-content-creation-83612f683e7a).
|
||||
|
||||
2. **Modern Technical Foundation**: Built on LangGraph and LangChain, DeerFlow leverages established frameworks while adding significant value through multi-agent orchestration.
|
||||
|
||||
3. **Community-Driven Development**: Active contributor community ensures diverse use cases, rapid bug fixes, and feature evolution aligned with real-world needs.
|
||||
|
||||
4. **Comprehensive Feature Set**: Unlike narrowly focused tools, DeerFlow addresses the complete research workflow from information gathering to content creation.
|
||||
|
||||
5. **Production Deployment Options**: Cloud integration, Docker support, and enterprise features facilitate adoption beyond experimental use cases.
|
||||
|
||||
6. **Multi-Language Accessibility**: Documentation and interface support for multiple languages expands global reach and adoption potential.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
### Primary Sources
|
||||
|
||||
1. **DeerFlow GitHub Repository**: Official source code, documentation, and development history [DeerFlow GitHub Repository](https://github.com/bytedance/deer-flow)
|
||||
2. **DeerFlow Official Website**: Platform showcasing features, case studies, and deployment options [DeerFlow Official Website](https://deerflow.tech/)
|
||||
3. **GitHub API Data**: Repository metrics, contributor statistics, and commit history
|
||||
|
||||
### Media Coverage
|
||||
|
||||
1. **The Sequence Engineering**: Technical analysis of DeerFlow architecture and capabilities [Create Your Own Deep Research Agent with DeerFlow](https://thesequence.substack.com/p/the-sequence-engineering-661-create)
|
||||
2. **Medium Articles**: Community perspectives on DeerFlow implementation and use cases [DeerFlow: A Game-Changer for Automated Research and Content Creation](https://medium.com/@mingyang.heaven/deerflow-a-game-changer-for-automated-research-and-content-creation-83612f683e7a)
|
||||
3. **YouTube Demonstrations**: Video walkthroughs of DeerFlow functionality and local deployment [ByteDance DeerFlow - (Deep Research Agents with a LOCAL LLM!)](https://www.youtube.com/watch?v=Ui0ovCVDYGs)
|
||||
|
||||
### Technical Sources
|
||||
|
||||
1. **FireXCore Analysis**: Feature overview and technical assessment [DeerFlow: Multi-Agent AI For Research Automation 2025](https://firexcore.com/blog/what-is-deerflow/)
|
||||
2. **Oreate AI Comparison**: Framework benchmarking and market positioning analysis [Navigating the Landscape of Deep Research Frameworks](https://www.oreateai.com/blog/navigating-the-landscape-of-deep-research-frameworks-a-comprehensive-comparison/0dc13e48eb8c756650112842c8d1a184)
|
||||
|
||||
---
|
||||
|
||||
## Confidence Assessment
|
||||
|
||||
**High Confidence (90%+) Claims:**
|
||||
|
||||
- DeerFlow was created by ByteDance and open-sourced under MIT license in May 2025
|
||||
- The framework implements multi-agent architecture using LangGraph and LangChain
|
||||
- Current GitHub metrics: 19,531 stars, 2,452 forks, 88 contributors, 196 open issues
|
||||
- Supports multiple search engines including Tavily, InfoQuest, Brave Search
|
||||
- Includes features for podcast generation, presentation creation, and human collaboration
|
||||
|
||||
**Medium Confidence (70-89%) Claims:**
|
||||
|
||||
- Specific performance benchmarks compared to proprietary alternatives
|
||||
- Detailed breakdown of enterprise adoption rates and use cases
|
||||
- Exact resource requirements for various deployment scenarios
|
||||
|
||||
**Lower Confidence (50-69%) Claims:**
|
||||
|
||||
- Future development roadmap beyond DeerFlow 2.0 transition
|
||||
- Specific enterprise customer implementations and case studies
|
||||
- Detailed comparison with emerging competitors not yet widely documented
|
||||
|
||||
---
|
||||
|
||||
## Research Methodology
|
||||
|
||||
This report was compiled using:
|
||||
|
||||
1. **Multi-source web search** - Broad discovery and targeted queries across technical publications, media coverage, and community discussions
|
||||
2. **GitHub repository analysis** - Direct API queries for commits, issues, PRs, contributor activity, and repository metrics
|
||||
3. **Content extraction** - Official documentation, technical articles, video demonstrations, and community resources
|
||||
4. **Cross-referencing** - Verification across independent sources including technical analysis, media coverage, and community feedback
|
||||
5. **Chronological reconstruction** - Timeline development from timestamped commit history and release documentation
|
||||
6. **Confidence scoring** - Claims weighted by source reliability, corroboration across multiple sources, and recency of information
|
||||
|
||||
**Research Depth:** Comprehensive technical and market analysis
|
||||
**Time Scope:** May 2025 - February 2026 (9-month development period)
|
||||
**Geographic Scope:** Global open-source community with ByteDance corporate backing
|
||||
|
||||
---
|
||||
|
||||
**Report Prepared By:** Github Deep Research by DeerFlow
|
||||
**Date:** 2026-02-01
|
||||
**Report Version:** 1.0
|
||||
**Status:** Complete
|
||||
BIN
deer-flow/frontend/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 801 KiB |
|
After Width: | Height: | Size: 699 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 612 KiB |
6
deer-flow/frontend/public/images/deer.svg
Normal file
|
After Width: | Height: | Size: 19 KiB |
61
deer-flow/frontend/scripts/save-demo.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { config } from "dotenv";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { env } from "process";
|
||||
|
||||
export async function main() {
|
||||
const url = new URL(process.argv[2]);
|
||||
const threadId = url.pathname.split("/").pop();
|
||||
const host = url.host;
|
||||
const apiURL = new URL(
|
||||
`/api/langgraph/threads/${threadId}/history`,
|
||||
`${url.protocol}//${host}`,
|
||||
);
|
||||
const response = await fetch(apiURL, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
limit: 10,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = (await response.json())[0];
|
||||
if (!data) {
|
||||
console.error("No data found");
|
||||
return;
|
||||
}
|
||||
|
||||
const title = data.values.title;
|
||||
|
||||
const rootPath = path.resolve(process.cwd(), "public/demo/threads", threadId);
|
||||
if (fs.existsSync(rootPath)) {
|
||||
fs.rmSync(rootPath, { recursive: true });
|
||||
}
|
||||
fs.mkdirSync(rootPath, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.resolve(rootPath, "thread.json"),
|
||||
JSON.stringify(data, null, 2),
|
||||
);
|
||||
const backendRootPath = path.resolve(
|
||||
process.cwd(),
|
||||
"../backend/.deer-flow/threads",
|
||||
threadId,
|
||||
);
|
||||
copyFolder("user-data/outputs", rootPath, backendRootPath);
|
||||
copyFolder("user-data/uploads", rootPath, backendRootPath);
|
||||
console.info(`Saved demo "${title}" to ${rootPath}`);
|
||||
}
|
||||
|
||||
function copyFolder(relPath, rootPath, backendRootPath) {
|
||||
const outputsPath = path.resolve(backendRootPath, relPath);
|
||||
if (fs.existsSync(outputsPath)) {
|
||||
fs.cpSync(outputsPath, path.resolve(rootPath, relPath), {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
config();
|
||||
main();
|
||||
@@ -0,0 +1,29 @@
|
||||
import { generateStaticParamsFor, importPage } from "nextra/pages";
|
||||
|
||||
import { useMDXComponents as getMDXComponents } from "../../../../mdx-components";
|
||||
|
||||
export const generateStaticParams = generateStaticParamsFor("mdxPath");
|
||||
|
||||
export async function generateMetadata(props) {
|
||||
const params = await props.params;
|
||||
const { metadata } = await importPage(params.mdxPath, params.lang);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const Wrapper = getMDXComponents().wrapper;
|
||||
|
||||
export default async function Page(props) {
|
||||
const params = await props.params;
|
||||
const {
|
||||
default: MDXContent,
|
||||
toc,
|
||||
metadata,
|
||||
sourceCode,
|
||||
} = await importPage(params.mdxPath, params.lang);
|
||||
return (
|
||||
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
|
||||
<MDXContent {...props} params={params} />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
51
deer-flow/frontend/src/app/[lang]/docs/layout.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { PageMapItem } from "nextra";
|
||||
import { getPageMap } from "nextra/page-map";
|
||||
import { Layout } from "nextra-theme-docs";
|
||||
|
||||
import { Footer } from "@/components/landing/footer";
|
||||
import { Header } from "@/components/landing/header";
|
||||
import { getLocaleByLang } from "@/core/i18n/locale";
|
||||
import "nextra-theme-docs/style.css";
|
||||
|
||||
const i18n = [
|
||||
{ locale: "en", name: "English" },
|
||||
{ locale: "zh", name: "中文" },
|
||||
];
|
||||
|
||||
function formatPageRoute(base: string, items: PageMapItem[]): PageMapItem[] {
|
||||
return items.map((item) => {
|
||||
if ("route" in item && !item.route.startsWith(base)) {
|
||||
item.route = `${base}${item.route}`;
|
||||
}
|
||||
if ("children" in item && item.children) {
|
||||
item.children = formatPageRoute(base, item.children);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
export default async function DocLayout({ children, params }) {
|
||||
const { lang } = await params;
|
||||
const locale = getLocaleByLang(lang);
|
||||
const pages = await getPageMap(`/${lang}`);
|
||||
const pageMap = formatPageRoute(`/${lang}/docs`, pages);
|
||||
|
||||
return (
|
||||
<Layout
|
||||
navbar={
|
||||
<Header
|
||||
className="relative max-w-full px-10"
|
||||
homeURL="/"
|
||||
locale={locale}
|
||||
/>
|
||||
}
|
||||
pageMap={pageMap}
|
||||
docsRepositoryBase="https://github.com/bytedance/deerflow/tree/main/frontend/src/content"
|
||||
footer={<Footer />}
|
||||
i18n={i18n}
|
||||
// ... Your additional layout options
|
||||
>
|
||||
{children}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
5
deer-flow/frontend/src/app/api/auth/[...all]/route.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { toNextJsHandler } from "better-auth/next-js";
|
||||
|
||||
import { auth } from "@/server/better-auth";
|
||||
|
||||
export const { GET, POST } = toNextJsHandler(auth.handler);
|
||||
55
deer-flow/frontend/src/app/api/memory/[...path]/route.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
const BACKEND_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_BACKEND_BASE_URL ?? "http://127.0.0.1:8001";
|
||||
|
||||
function buildBackendUrl(pathname: string) {
|
||||
return new URL(pathname, BACKEND_BASE_URL);
|
||||
}
|
||||
|
||||
async function proxyRequest(request: NextRequest, pathname: string) {
|
||||
const headers = new Headers(request.headers);
|
||||
headers.delete("host");
|
||||
headers.delete("connection");
|
||||
headers.delete("content-length");
|
||||
|
||||
const hasBody = !["GET", "HEAD"].includes(request.method);
|
||||
const response = await fetch(buildBackendUrl(pathname), {
|
||||
method: request.method,
|
||||
headers,
|
||||
body: hasBody ? await request.arrayBuffer() : undefined,
|
||||
});
|
||||
|
||||
return new Response(await response.arrayBuffer(), {
|
||||
status: response.status,
|
||||
headers: response.headers,
|
||||
});
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> },
|
||||
) {
|
||||
return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`);
|
||||
}
|
||||
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> },
|
||||
) {
|
||||
return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`);
|
||||
}
|
||||
|
||||
export async function DELETE(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> },
|
||||
) {
|
||||
return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`);
|
||||
}
|
||||
|
||||
export async function PATCH(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> },
|
||||
) {
|
||||
return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`);
|
||||
}
|
||||
35
deer-flow/frontend/src/app/api/memory/route.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
const BACKEND_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_BACKEND_BASE_URL ?? "http://127.0.0.1:8001";
|
||||
|
||||
function buildBackendUrl(pathname: string) {
|
||||
return new URL(pathname, BACKEND_BASE_URL);
|
||||
}
|
||||
|
||||
async function proxyRequest(request: NextRequest, pathname: string) {
|
||||
const headers = new Headers(request.headers);
|
||||
headers.delete("host");
|
||||
headers.delete("connection");
|
||||
headers.delete("content-length");
|
||||
|
||||
const hasBody = !["GET", "HEAD"].includes(request.method);
|
||||
const response = await fetch(buildBackendUrl(pathname), {
|
||||
method: request.method,
|
||||
headers,
|
||||
body: hasBody ? await request.arrayBuffer() : undefined,
|
||||
});
|
||||
|
||||
return new Response(await response.arrayBuffer(), {
|
||||
status: response.status,
|
||||
headers: response.headers,
|
||||
});
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
return proxyRequest(request, "/api/memory");
|
||||
}
|
||||
|
||||
export async function DELETE(request: NextRequest) {
|
||||
return proxyRequest(request, "/api/memory");
|
||||
}
|
||||
178
deer-flow/frontend/src/app/blog/[[...mdxPath]]/page.tsx
Normal file
@@ -0,0 +1,178 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { importPage } from "nextra/pages";
|
||||
import { cache } from "react";
|
||||
|
||||
import { PostList, PostMeta } from "@/components/landing/post-list";
|
||||
import {
|
||||
BLOG_LANGS,
|
||||
type BlogLang,
|
||||
formatTagName,
|
||||
getAllPosts,
|
||||
getBlogIndexData,
|
||||
getPreferredBlogLang,
|
||||
} from "@/core/blog";
|
||||
import { getI18n } from "@/core/i18n/server";
|
||||
|
||||
import { useMDXComponents as getMDXComponents } from "../../../mdx-components";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const Wrapper = getMDXComponents().wrapper;
|
||||
|
||||
function isBlogLang(value: string): value is BlogLang {
|
||||
return BLOG_LANGS.includes(value as BlogLang);
|
||||
}
|
||||
|
||||
const loadBlogPage = cache(async function loadBlogPage(
|
||||
mdxPath: string[] | undefined,
|
||||
preferredLang?: (typeof BLOG_LANGS)[number],
|
||||
) {
|
||||
const slug = mdxPath ?? [];
|
||||
const matches = await Promise.all(
|
||||
BLOG_LANGS.map(async (lang) => {
|
||||
try {
|
||||
// Try every localized source for the same public /blog slug,
|
||||
// then pick the best match for the current locale.
|
||||
const page = await importPage([...slug], lang);
|
||||
return { lang, page };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const availableMatches = matches.filter(
|
||||
(match): match is NonNullable<(typeof matches)[number]> => match !== null,
|
||||
);
|
||||
|
||||
if (availableMatches.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const selected =
|
||||
(preferredLang
|
||||
? availableMatches.find(({ lang }) => lang === preferredLang)
|
||||
: undefined) ?? availableMatches[0];
|
||||
|
||||
if (!selected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
...selected.page,
|
||||
lang: selected.lang,
|
||||
metadata: {
|
||||
...selected.page.metadata,
|
||||
languages: availableMatches.map(({ lang }) => lang),
|
||||
},
|
||||
slug,
|
||||
};
|
||||
});
|
||||
|
||||
export async function generateMetadata(props) {
|
||||
const params = await props.params;
|
||||
const mdxPath = params.mdxPath ?? [];
|
||||
const { locale } = await getI18n();
|
||||
const preferredLang = getPreferredBlogLang(locale);
|
||||
|
||||
if (mdxPath.length === 0) {
|
||||
return {
|
||||
title: "Blog",
|
||||
};
|
||||
}
|
||||
|
||||
if (mdxPath[0] === "tags" && mdxPath[1]) {
|
||||
return {
|
||||
title: formatTagName(mdxPath[1]),
|
||||
};
|
||||
}
|
||||
|
||||
const page = await loadBlogPage(mdxPath, preferredLang);
|
||||
|
||||
if (!page) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return page.metadata;
|
||||
}
|
||||
|
||||
export default async function Page(props) {
|
||||
const params = await props.params;
|
||||
const searchParams = await props.searchParams;
|
||||
const mdxPath = params.mdxPath ?? [];
|
||||
const { locale } = await getI18n();
|
||||
const localePreferredLang = getPreferredBlogLang(locale);
|
||||
const queryLang = searchParams?.lang;
|
||||
const preferredLang =
|
||||
typeof queryLang === "string" && isBlogLang(queryLang)
|
||||
? queryLang
|
||||
: localePreferredLang;
|
||||
|
||||
if (mdxPath.length === 0) {
|
||||
const posts = await getAllPosts(preferredLang);
|
||||
return (
|
||||
<Wrapper
|
||||
toc={[]}
|
||||
metadata={{ title: "All Posts", filePath: "blog/index.mdx" }}
|
||||
sourceCode=""
|
||||
>
|
||||
<PostList title="All Posts" posts={posts} />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
if (mdxPath[0] === "tags" && mdxPath[1]) {
|
||||
let tag: string;
|
||||
try {
|
||||
tag = decodeURIComponent(mdxPath[1]);
|
||||
} catch {
|
||||
notFound();
|
||||
}
|
||||
const title = formatTagName(tag);
|
||||
const { posts } = await getBlogIndexData(preferredLang, { tag });
|
||||
|
||||
if (posts.length === 0) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
toc={[]}
|
||||
metadata={{ title, filePath: "blog/index.mdx" }}
|
||||
sourceCode=""
|
||||
>
|
||||
<PostList
|
||||
title={title}
|
||||
description={`${posts.length} posts with the tag “${title}”`}
|
||||
posts={posts}
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const page = await loadBlogPage(mdxPath, preferredLang);
|
||||
|
||||
if (!page) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const { default: MDXContent, toc, metadata, sourceCode, lang, slug } = page;
|
||||
const postMetaData = metadata as {
|
||||
date?: string;
|
||||
languages?: string[];
|
||||
tags?: unknown;
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
|
||||
<PostMeta
|
||||
currentLang={lang}
|
||||
date={
|
||||
typeof postMetaData.date === "string" ? postMetaData.date : undefined
|
||||
}
|
||||
languages={postMetaData.languages}
|
||||
pathname={slug.length === 0 ? "/blog" : `/blog/${slug.join("/")}`}
|
||||
/>
|
||||
<MDXContent {...props} params={{ ...params, lang, mdxPath: slug }} />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
22
deer-flow/frontend/src/app/blog/layout.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Layout } from "nextra-theme-docs";
|
||||
|
||||
import { Footer } from "@/components/landing/footer";
|
||||
import { Header } from "@/components/landing/header";
|
||||
import { getBlogIndexData } from "@/core/blog";
|
||||
import "nextra-theme-docs/style.css";
|
||||
|
||||
export default async function BlogLayout({ children }) {
|
||||
const { pageMap } = await getBlogIndexData();
|
||||
|
||||
return (
|
||||
<Layout
|
||||
navbar={<Header className="relative max-w-full px-10" homeURL="/" />}
|
||||
pageMap={pageMap}
|
||||
sidebar={{ defaultOpen: true }}
|
||||
docsRepositoryBase="https://github.com/bytedance/deerflow/tree/main/frontend/src/content"
|
||||
footer={<Footer />}
|
||||
>
|
||||
{children}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
24
deer-flow/frontend/src/app/blog/posts/page.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { PostList } from "@/components/landing/post-list";
|
||||
import { getAllPosts, getPreferredBlogLang } from "@/core/blog";
|
||||
import { getI18n } from "@/core/i18n/server";
|
||||
|
||||
import { useMDXComponents as getMDXComponents } from "../../../mdx-components";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const Wrapper = getMDXComponents().wrapper;
|
||||
|
||||
export const metadata = {
|
||||
title: "All Posts",
|
||||
filePath: "blog/index.mdx",
|
||||
};
|
||||
|
||||
export default async function PostsPage() {
|
||||
const { locale } = await getI18n();
|
||||
const posts = await getAllPosts(getPreferredBlogLang(locale));
|
||||
|
||||
return (
|
||||
<Wrapper toc={[]} metadata={metadata} sourceCode="">
|
||||
<PostList title={metadata.title} posts={posts} />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
51
deer-flow/frontend/src/app/blog/tags/[tag]/page.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { PostList } from "@/components/landing/post-list";
|
||||
import {
|
||||
formatTagName,
|
||||
getBlogIndexData,
|
||||
getPreferredBlogLang,
|
||||
} from "@/core/blog";
|
||||
import { getI18n } from "@/core/i18n/server";
|
||||
|
||||
import { useMDXComponents as getMDXComponents } from "../../../../mdx-components";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const Wrapper = getMDXComponents().wrapper;
|
||||
|
||||
export async function generateMetadata(props) {
|
||||
const params = await props.params;
|
||||
return {
|
||||
title: formatTagName(params.tag),
|
||||
filePath: "blog/index.mdx",
|
||||
};
|
||||
}
|
||||
|
||||
export default async function TagPage(props) {
|
||||
const params = await props.params;
|
||||
const tag = params.tag;
|
||||
const { locale } = await getI18n();
|
||||
const { posts } = await getBlogIndexData(getPreferredBlogLang(locale), {
|
||||
tag,
|
||||
});
|
||||
|
||||
if (posts.length === 0) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const title = formatTagName(tag);
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
toc={[]}
|
||||
metadata={{ title, filePath: "blog/index.mdx" }}
|
||||
sourceCode=""
|
||||
>
|
||||
<PostList
|
||||
title={title}
|
||||
description={`${posts.length} posts with the tag “${title}”`}
|
||||
posts={posts}
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
28
deer-flow/frontend/src/app/layout.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import "@/styles/globals.css";
|
||||
import "katex/dist/katex.min.css";
|
||||
|
||||
import { type Metadata } from "next";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
import { I18nProvider } from "@/core/i18n/context";
|
||||
import { detectLocaleServer } from "@/core/i18n/server";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "DeerFlow",
|
||||
description: "A LangChain-based framework for building super agents.",
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{ children: React.ReactNode }>) {
|
||||
const locale = await detectLocaleServer();
|
||||
return (
|
||||
<html lang={locale} suppressContentEditableWarning suppressHydrationWarning>
|
||||
<body>
|
||||
<ThemeProvider attribute="class" enableSystem disableTransitionOnChange>
|
||||
<I18nProvider initialLocale={locale}>{children}</I18nProvider>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
26
deer-flow/frontend/src/app/mock/api/mcp/config/route.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export function GET() {
|
||||
return Response.json({
|
||||
mcp_servers: {
|
||||
"mcp-github-trending": {
|
||||
enabled: true,
|
||||
type: "stdio",
|
||||
command: "uvx",
|
||||
args: ["mcp-github-trending"],
|
||||
env: {},
|
||||
url: null,
|
||||
headers: {},
|
||||
description:
|
||||
"A MCP server that provides access to GitHub trending repositories and developers data",
|
||||
},
|
||||
"context-7": {
|
||||
enabled: true,
|
||||
description:
|
||||
"Get the latest documentation and code into Cursor, Claude, or other LLMs",
|
||||
},
|
||||
"feishu-importer": {
|
||||
enabled: true,
|
||||
description: "Import Feishu documents",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
34
deer-flow/frontend/src/app/mock/api/models/route.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
export function GET() {
|
||||
return Response.json({
|
||||
models: [
|
||||
{
|
||||
id: "doubao-seed-1.8",
|
||||
name: "doubao-seed-1.8",
|
||||
model: "doubao-seed-1-8",
|
||||
display_name: "Doubao Seed 1.8",
|
||||
supports_thinking: true,
|
||||
},
|
||||
{
|
||||
id: "deepseek-v3.2",
|
||||
name: "deepseek-v3.2",
|
||||
model: "deepseek-chat",
|
||||
display_name: "DeepSeek v3.2",
|
||||
supports_thinking: true,
|
||||
},
|
||||
{
|
||||
id: "gpt-5",
|
||||
name: "gpt-5",
|
||||
model: "gpt-5",
|
||||
display_name: "GPT-5",
|
||||
supports_thinking: true,
|
||||
},
|
||||
{
|
||||
id: "gemini-3-pro",
|
||||
name: "gemini-3-pro",
|
||||
model: "gemini-3-pro",
|
||||
display_name: "Gemini 3 Pro",
|
||||
supports_thinking: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
86
deer-flow/frontend/src/app/mock/api/skills/route.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
export function GET() {
|
||||
return Response.json({
|
||||
skills: [
|
||||
{
|
||||
name: "deep-research",
|
||||
description:
|
||||
"Use this skill BEFORE any content generation task (PPT, design, articles, images, videos, reports). Provides a systematic methodology for conducting thorough, multi-angle web research to gather comprehensive information.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "frontend-design",
|
||||
description:
|
||||
"Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.",
|
||||
license: "Complete terms in LICENSE.txt",
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "github-deep-research",
|
||||
description:
|
||||
"Conduct multi-round deep research on any GitHub Repo. Use when users request comprehensive analysis, timeline reconstruction, competitive analysis, or in-depth investigation of GitHub. Produces structured markdown reports with executive summaries, chronological timelines, metrics analysis, and Mermaid diagrams. Triggers on Github repository URL or open source projects.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "image-generation",
|
||||
description:
|
||||
"Use this skill when the user requests to generate, create, imagine, or visualize images including characters, scenes, products, or any visual content. Supports structured prompts and reference images for guided generation.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "podcast-generation",
|
||||
description:
|
||||
"Use this skill when the user requests to generate, create, or produce podcasts from text content. Converts written content into a two-host conversational podcast audio format with natural dialogue.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "ppt-generation",
|
||||
description:
|
||||
"Use this skill when the user requests to generate, create, or make presentations (PPT/PPTX). Creates visually rich slides by generating images for each slide and composing them into a PowerPoint file.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "skill-creator",
|
||||
description:
|
||||
"Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.",
|
||||
license: "Complete terms in LICENSE.txt",
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "vercel-deploy",
|
||||
description:
|
||||
'Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as "Deploy my app", "Deploy this to production", "Create a preview deployment", "Deploy and give me the link", or "Push this live". No authentication required - returns preview URL and claimable deployment link.',
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "video-generation",
|
||||
description:
|
||||
"Use this skill when the user requests to generate, create, or imagine videos. Supports structured prompts and reference image for guided generation.",
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: "web-design-guidelines",
|
||||
description:
|
||||
'Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".',
|
||||
license: null,
|
||||
category: "public",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{
|
||||
thread_id: string;
|
||||
artifact_path?: string[] | undefined;
|
||||
}>;
|
||||
},
|
||||
) {
|
||||
const threadId = (await params).thread_id;
|
||||
let artifactPath = (await params).artifact_path?.join("/") ?? "";
|
||||
if (artifactPath.startsWith("mnt/")) {
|
||||
artifactPath = path.resolve(
|
||||
process.cwd(),
|
||||
artifactPath.replace("mnt/", `public/demo/threads/${threadId}/`),
|
||||
);
|
||||
if (fs.existsSync(artifactPath)) {
|
||||
if (request.nextUrl.searchParams.get("download") === "true") {
|
||||
// Attach the file to the response
|
||||
const headers = new Headers();
|
||||
headers.set(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="${artifactPath}"`,
|
||||
);
|
||||
return new Response(fs.readFileSync(artifactPath), {
|
||||
status: 200,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
if (artifactPath.endsWith(".mp4")) {
|
||||
return new Response(fs.readFileSync(artifactPath), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "video/mp4",
|
||||
},
|
||||
});
|
||||
}
|
||||
return new Response(fs.readFileSync(artifactPath), { status: 200 });
|
||||
}
|
||||
}
|
||||
return new Response("File not found", { status: 404 });
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ thread_id: string }> },
|
||||
) {
|
||||
const threadId = (await params).thread_id;
|
||||
const jsonString = fs.readFileSync(
|
||||
path.resolve(process.cwd(), `public/demo/threads/${threadId}/thread.json`),
|
||||
"utf8",
|
||||
);
|
||||
const json = JSON.parse(jsonString);
|
||||
if (Array.isArray(json.history)) {
|
||||
return Response.json(json);
|
||||
}
|
||||
return Response.json([json]);
|
||||
}
|
||||
85
deer-flow/frontend/src/app/mock/api/threads/search/route.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
type ThreadSearchRequest = {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
sortBy?: "updated_at" | "created_at";
|
||||
sortOrder?: "asc" | "desc";
|
||||
};
|
||||
|
||||
type MockThreadSearchResult = Record<string, unknown> & {
|
||||
thread_id: string;
|
||||
updated_at: string | undefined;
|
||||
};
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const body = ((await request.json().catch(() => ({}))) ??
|
||||
{}) as ThreadSearchRequest;
|
||||
|
||||
const rawLimit = body.limit;
|
||||
let limit = 50;
|
||||
if (typeof rawLimit === "number") {
|
||||
const normalizedLimit = Math.max(0, Math.floor(rawLimit));
|
||||
if (!Number.isNaN(normalizedLimit)) {
|
||||
limit = normalizedLimit;
|
||||
}
|
||||
}
|
||||
|
||||
const rawOffset = body.offset;
|
||||
let offset = 0;
|
||||
if (typeof rawOffset === "number") {
|
||||
const normalizedOffset = Math.max(0, Math.floor(rawOffset));
|
||||
if (!Number.isNaN(normalizedOffset)) {
|
||||
offset = normalizedOffset;
|
||||
}
|
||||
}
|
||||
const sortBy = body.sortBy ?? "updated_at";
|
||||
const sortOrder = body.sortOrder ?? "desc";
|
||||
|
||||
const threadsDir = fs.readdirSync(
|
||||
path.resolve(process.cwd(), "public/demo/threads"),
|
||||
{
|
||||
withFileTypes: true,
|
||||
},
|
||||
);
|
||||
|
||||
const threadData = threadsDir
|
||||
.map<MockThreadSearchResult | null>((threadId) => {
|
||||
if (threadId.isDirectory() && !threadId.name.startsWith(".")) {
|
||||
const threadData = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.resolve(`public/demo/threads/${threadId.name}/thread.json`),
|
||||
"utf8",
|
||||
),
|
||||
) as Record<string, unknown>;
|
||||
|
||||
return {
|
||||
...threadData,
|
||||
thread_id: threadId.name,
|
||||
updated_at:
|
||||
typeof threadData.updated_at === "string"
|
||||
? threadData.updated_at
|
||||
: typeof threadData.created_at === "string"
|
||||
? threadData.created_at
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((thread): thread is MockThreadSearchResult => thread !== null)
|
||||
.sort((a, b) => {
|
||||
const aTimestamp = a[sortBy];
|
||||
const bTimestamp = b[sortBy];
|
||||
const aParsed =
|
||||
typeof aTimestamp === "string" ? Date.parse(aTimestamp) : 0;
|
||||
const bParsed =
|
||||
typeof bTimestamp === "string" ? Date.parse(bTimestamp) : 0;
|
||||
const aValue = Number.isNaN(aParsed) ? 0 : aParsed;
|
||||
const bValue = Number.isNaN(bParsed) ? 0 : bParsed;
|
||||
return sortOrder === "asc" ? aValue - bValue : bValue - aValue;
|
||||
});
|
||||
|
||||
const pagedThreads = threadData.slice(offset, offset + limit);
|
||||
return Response.json(pagedThreads);
|
||||
}
|
||||
25
deer-flow/frontend/src/app/page.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Footer } from "@/components/landing/footer";
|
||||
import { Header } from "@/components/landing/header";
|
||||
import { Hero } from "@/components/landing/hero";
|
||||
import { CaseStudySection } from "@/components/landing/sections/case-study-section";
|
||||
import { CommunitySection } from "@/components/landing/sections/community-section";
|
||||
import { SandboxSection } from "@/components/landing/sections/sandbox-section";
|
||||
import { SkillsSection } from "@/components/landing/sections/skills-section";
|
||||
import { WhatsNewSection } from "@/components/landing/sections/whats-new-section";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="min-h-screen w-full bg-[#0a0a0a]">
|
||||
<Header />
|
||||
<main className="flex w-full flex-col">
|
||||
<Hero />
|
||||
<CaseStudySection />
|
||||
<SkillsSection />
|
||||
<SandboxSection />
|
||||
<WhatsNewSection />
|
||||
<CommunitySection />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { PromptInputProvider } from "@/components/ai-elements/prompt-input";
|
||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||
import { SubtasksProvider } from "@/core/tasks/context";
|
||||
|
||||
export default function AgentChatLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<SubtasksProvider>
|
||||
<ArtifactsProvider>
|
||||
<PromptInputProvider>{children}</PromptInputProvider>
|
||||
</ArtifactsProvider>
|
||||
</SubtasksProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
"use client";
|
||||
|
||||
import { BotIcon, PlusSquare } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
import type { PromptInputMessage } from "@/components/ai-elements/prompt-input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { AgentWelcome } from "@/components/workspace/agent-welcome";
|
||||
import { ArtifactTrigger } from "@/components/workspace/artifacts";
|
||||
import { ChatBox, useThreadChat } from "@/components/workspace/chats";
|
||||
import { ExportTrigger } from "@/components/workspace/export-trigger";
|
||||
import { InputBox } from "@/components/workspace/input-box";
|
||||
import {
|
||||
MessageList,
|
||||
MESSAGE_LIST_DEFAULT_PADDING_BOTTOM,
|
||||
MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM,
|
||||
} from "@/components/workspace/messages";
|
||||
import { ThreadContext } from "@/components/workspace/messages/context";
|
||||
import { ThreadTitle } from "@/components/workspace/thread-title";
|
||||
import { TodoList } from "@/components/workspace/todo-list";
|
||||
import { TokenUsageIndicator } from "@/components/workspace/token-usage-indicator";
|
||||
import { Tooltip } from "@/components/workspace/tooltip";
|
||||
import { useAgent } from "@/core/agents";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import { useNotification } from "@/core/notification/hooks";
|
||||
import { useThreadSettings } from "@/core/settings";
|
||||
import { useThreadStream } from "@/core/threads/hooks";
|
||||
import { textOfMessage } from "@/core/threads/utils";
|
||||
import { env } from "@/env";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export default function AgentChatPage() {
|
||||
const { t } = useI18n();
|
||||
const [showFollowups, setShowFollowups] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
const { agent_name } = useParams<{
|
||||
agent_name: string;
|
||||
}>();
|
||||
|
||||
const { agent } = useAgent(agent_name);
|
||||
|
||||
const { threadId, setThreadId, isNewThread, setIsNewThread } =
|
||||
useThreadChat();
|
||||
const [settings, setSettings] = useThreadSettings(threadId);
|
||||
|
||||
const { showNotification } = useNotification();
|
||||
const [thread, sendMessage] = useThreadStream({
|
||||
threadId: isNewThread ? undefined : threadId,
|
||||
context: { ...settings.context, agent_name: agent_name },
|
||||
onStart: (createdThreadId) => {
|
||||
setThreadId(createdThreadId);
|
||||
setIsNewThread(false);
|
||||
// ! Important: Never use next.js router for navigation in this case, otherwise it will cause the thread to re-mount and lose all states. Use native history API instead.
|
||||
history.replaceState(
|
||||
null,
|
||||
"",
|
||||
`/workspace/agents/${agent_name}/chats/${createdThreadId}`,
|
||||
);
|
||||
},
|
||||
onFinish: (state) => {
|
||||
if (document.hidden || !document.hasFocus()) {
|
||||
let body = "Conversation finished";
|
||||
const lastMessage = state.messages[state.messages.length - 1];
|
||||
if (lastMessage) {
|
||||
const textContent = textOfMessage(lastMessage);
|
||||
if (textContent) {
|
||||
body =
|
||||
textContent.length > 200
|
||||
? textContent.substring(0, 200) + "..."
|
||||
: textContent;
|
||||
}
|
||||
}
|
||||
showNotification(state.title, { body });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(message: PromptInputMessage) => {
|
||||
void sendMessage(threadId, message, { agent_name });
|
||||
},
|
||||
[sendMessage, threadId, agent_name],
|
||||
);
|
||||
|
||||
const handleStop = useCallback(async () => {
|
||||
await thread.stop();
|
||||
}, [thread]);
|
||||
|
||||
const messageListPaddingBottom = showFollowups
|
||||
? MESSAGE_LIST_DEFAULT_PADDING_BOTTOM +
|
||||
MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<ThreadContext.Provider value={{ thread }}>
|
||||
<ChatBox threadId={threadId}>
|
||||
<div className="relative flex size-full min-h-0 justify-between">
|
||||
<header
|
||||
className={cn(
|
||||
"absolute top-0 right-0 left-0 z-30 flex h-12 shrink-0 items-center gap-2 px-4",
|
||||
isNewThread
|
||||
? "bg-background/0 backdrop-blur-none"
|
||||
: "bg-background/80 shadow-xs backdrop-blur",
|
||||
)}
|
||||
>
|
||||
{/* Agent badge */}
|
||||
<div className="flex shrink-0 items-center gap-1.5 rounded-md border px-2 py-1">
|
||||
<BotIcon className="text-primary h-3.5 w-3.5" />
|
||||
<span className="text-xs font-medium">
|
||||
{agent?.name ?? agent_name}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex w-full items-center text-sm font-medium">
|
||||
<ThreadTitle threadId={threadId} thread={thread} />
|
||||
</div>
|
||||
<div className="mr-4 flex items-center">
|
||||
<Tooltip content={t.agents.newChat}>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
router.push(`/workspace/agents/${agent_name}/chats/new`);
|
||||
}}
|
||||
>
|
||||
<PlusSquare /> {t.agents.newChat}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<TokenUsageIndicator messages={thread.messages} />
|
||||
<ExportTrigger threadId={threadId} />
|
||||
<ArtifactTrigger />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex min-h-0 max-w-full grow flex-col">
|
||||
<div className="flex size-full justify-center">
|
||||
<MessageList
|
||||
className={cn("size-full", !isNewThread && "pt-10")}
|
||||
threadId={threadId}
|
||||
thread={thread}
|
||||
paddingBottom={messageListPaddingBottom}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="absolute right-0 bottom-0 left-0 z-30 flex justify-center px-4">
|
||||
<div
|
||||
className={cn(
|
||||
"relative w-full",
|
||||
isNewThread && "-translate-y-[calc(50vh-96px)]",
|
||||
isNewThread
|
||||
? "max-w-(--container-width-sm)"
|
||||
: "max-w-(--container-width-md)",
|
||||
)}
|
||||
>
|
||||
<div className="absolute -top-4 right-0 left-0 z-0">
|
||||
<div className="absolute right-0 bottom-0 left-0">
|
||||
<TodoList
|
||||
className="bg-background/5"
|
||||
todos={thread.values.todos ?? []}
|
||||
hidden={
|
||||
!thread.values.todos || thread.values.todos.length === 0
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InputBox
|
||||
className={cn("bg-background/5 w-full -translate-y-4")}
|
||||
isNewThread={isNewThread}
|
||||
threadId={threadId}
|
||||
autoFocus={isNewThread}
|
||||
status={
|
||||
thread.error
|
||||
? "error"
|
||||
: thread.isLoading
|
||||
? "streaming"
|
||||
: "ready"
|
||||
}
|
||||
context={settings.context}
|
||||
extraHeader={
|
||||
isNewThread && (
|
||||
<AgentWelcome agent={agent} agentName={agent_name} />
|
||||
)
|
||||
}
|
||||
disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"}
|
||||
onContextChange={(context) => setSettings("context", context)}
|
||||
onFollowupsVisibilityChange={setShowFollowups}
|
||||
onSubmit={handleSubmit}
|
||||
onStop={handleStop}
|
||||
/>
|
||||
{env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" && (
|
||||
<div className="text-muted-foreground/67 w-full translate-y-12 text-center text-xs">
|
||||
{t.common.notAvailableInDemoMode}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</ChatBox>
|
||||
</ThreadContext.Provider>
|
||||
);
|
||||
}
|
||||
422
deer-flow/frontend/src/app/workspace/agents/new/page.tsx
Normal file
@@ -0,0 +1,422 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
ArrowLeftIcon,
|
||||
BotIcon,
|
||||
CheckCircleIcon,
|
||||
InfoIcon,
|
||||
MoreHorizontalIcon,
|
||||
SaveIcon,
|
||||
} from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import {
|
||||
PromptInput,
|
||||
PromptInputFooter,
|
||||
PromptInputSubmit,
|
||||
PromptInputTextarea,
|
||||
} from "@/components/ai-elements/prompt-input";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||
import { MessageList } from "@/components/workspace/messages";
|
||||
import { ThreadContext } from "@/components/workspace/messages/context";
|
||||
import type { Agent } from "@/core/agents";
|
||||
import {
|
||||
AgentNameCheckError,
|
||||
checkAgentName,
|
||||
createAgent,
|
||||
getAgent,
|
||||
} from "@/core/agents/api";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import { useThreadStream } from "@/core/threads/hooks";
|
||||
import { uuid } from "@/core/utils/uuid";
|
||||
import { isIMEComposing } from "@/lib/ime";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type Step = "name" | "chat";
|
||||
type SetupAgentStatus = "idle" | "requested" | "completed";
|
||||
|
||||
const NAME_RE = /^[A-Za-z0-9-]+$/;
|
||||
const SAVE_HINT_STORAGE_KEY = "deerflow.agent-create.save-hint-seen";
|
||||
const AGENT_READ_RETRY_DELAYS_MS = [200, 500, 1_000, 2_000];
|
||||
|
||||
function wait(ms: number) {
|
||||
return new Promise((resolve) => window.setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function getAgentWithRetry(agentName: string) {
|
||||
for (const delay of [0, ...AGENT_READ_RETRY_DELAYS_MS]) {
|
||||
if (delay > 0) {
|
||||
await wait(delay);
|
||||
}
|
||||
|
||||
try {
|
||||
return await getAgent(agentName);
|
||||
} catch {
|
||||
// Retry until the write settles or the attempts are exhausted.
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getCreateAgentErrorMessage(
|
||||
error: unknown,
|
||||
networkErrorMessage: string,
|
||||
fallbackMessage: string,
|
||||
) {
|
||||
if (error instanceof TypeError && error.message === "Failed to fetch") {
|
||||
return networkErrorMessage;
|
||||
}
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
}
|
||||
return fallbackMessage;
|
||||
}
|
||||
|
||||
export default function NewAgentPage() {
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
|
||||
const [step, setStep] = useState<Step>("name");
|
||||
const [nameInput, setNameInput] = useState("");
|
||||
const [nameError, setNameError] = useState("");
|
||||
const [isCheckingName, setIsCheckingName] = useState(false);
|
||||
const [isCreatingAgent, setIsCreatingAgent] = useState(false);
|
||||
const [agentName, setAgentName] = useState("");
|
||||
const [agent, setAgent] = useState<Agent | null>(null);
|
||||
const [showSaveHint, setShowSaveHint] = useState(false);
|
||||
const [setupAgentStatus, setSetupAgentStatus] =
|
||||
useState<SetupAgentStatus>("idle");
|
||||
|
||||
const threadId = useMemo(() => uuid(), []);
|
||||
|
||||
const [thread, sendMessage] = useThreadStream({
|
||||
threadId: step === "chat" ? threadId : undefined,
|
||||
context: {
|
||||
mode: "flash",
|
||||
is_bootstrap: true,
|
||||
},
|
||||
onFinish() {
|
||||
if (!agent && setupAgentStatus === "requested") {
|
||||
setSetupAgentStatus("idle");
|
||||
}
|
||||
},
|
||||
onToolEnd({ name }) {
|
||||
if (name !== "setup_agent" || !agentName) return;
|
||||
setSetupAgentStatus("completed");
|
||||
void getAgentWithRetry(agentName).then((fetched) => {
|
||||
if (fetched) {
|
||||
setAgent(fetched);
|
||||
return;
|
||||
}
|
||||
|
||||
toast.error(t.agents.agentCreatedPendingRefresh);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined" || step !== "chat") {
|
||||
return;
|
||||
}
|
||||
if (window.localStorage.getItem(SAVE_HINT_STORAGE_KEY) === "1") {
|
||||
return;
|
||||
}
|
||||
setShowSaveHint(true);
|
||||
window.localStorage.setItem(SAVE_HINT_STORAGE_KEY, "1");
|
||||
}, [step]);
|
||||
|
||||
const handleConfirmName = useCallback(async () => {
|
||||
const trimmed = nameInput.trim();
|
||||
if (!trimmed) return;
|
||||
if (!NAME_RE.test(trimmed)) {
|
||||
setNameError(t.agents.nameStepInvalidError);
|
||||
return;
|
||||
}
|
||||
|
||||
setNameError("");
|
||||
setIsCheckingName(true);
|
||||
try {
|
||||
const result = await checkAgentName(trimmed);
|
||||
if (!result.available) {
|
||||
setNameError(t.agents.nameStepAlreadyExistsError);
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof AgentNameCheckError &&
|
||||
err.reason === "backend_unreachable"
|
||||
) {
|
||||
setNameError(t.agents.nameStepNetworkError);
|
||||
} else {
|
||||
setNameError(t.agents.nameStepCheckError);
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
setIsCheckingName(false);
|
||||
}
|
||||
|
||||
setIsCreatingAgent(true);
|
||||
try {
|
||||
await createAgent({
|
||||
name: trimmed,
|
||||
description: "",
|
||||
soul: "",
|
||||
});
|
||||
} catch (err) {
|
||||
setNameError(
|
||||
getCreateAgentErrorMessage(
|
||||
err,
|
||||
t.agents.nameStepNetworkError,
|
||||
t.agents.nameStepCheckError,
|
||||
),
|
||||
);
|
||||
return;
|
||||
} finally {
|
||||
setIsCreatingAgent(false);
|
||||
}
|
||||
|
||||
setAgentName(trimmed);
|
||||
setStep("chat");
|
||||
await sendMessage(threadId, {
|
||||
text: t.agents.nameStepBootstrapMessage.replace("{name}", trimmed),
|
||||
files: [],
|
||||
});
|
||||
}, [
|
||||
nameInput,
|
||||
sendMessage,
|
||||
t.agents.nameStepAlreadyExistsError,
|
||||
t.agents.nameStepNetworkError,
|
||||
t.agents.nameStepBootstrapMessage,
|
||||
t.agents.nameStepCheckError,
|
||||
t.agents.nameStepInvalidError,
|
||||
threadId,
|
||||
]);
|
||||
|
||||
const handleNameKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "Enter" && !isIMEComposing(e)) {
|
||||
e.preventDefault();
|
||||
void handleConfirmName();
|
||||
}
|
||||
};
|
||||
|
||||
const handleChatSubmit = useCallback(
|
||||
async (text: string) => {
|
||||
const trimmed = text.trim();
|
||||
if (!trimmed || thread.isLoading) return;
|
||||
await sendMessage(
|
||||
threadId,
|
||||
{ text: trimmed, files: [] },
|
||||
{ agent_name: agentName },
|
||||
);
|
||||
},
|
||||
[agentName, sendMessage, thread.isLoading, threadId],
|
||||
);
|
||||
|
||||
const handleSaveAgent = useCallback(async () => {
|
||||
if (
|
||||
!agentName ||
|
||||
agent ||
|
||||
thread.isLoading ||
|
||||
setupAgentStatus !== "idle"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSetupAgentStatus("requested");
|
||||
setShowSaveHint(false);
|
||||
try {
|
||||
await sendMessage(
|
||||
threadId,
|
||||
{ text: t.agents.saveCommandMessage, files: [] },
|
||||
{ agent_name: agentName },
|
||||
{ additionalKwargs: { hide_from_ui: true } },
|
||||
);
|
||||
toast.success(t.agents.saveRequested);
|
||||
} catch (error) {
|
||||
setSetupAgentStatus("idle");
|
||||
toast.error(error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
}, [
|
||||
agent,
|
||||
agentName,
|
||||
sendMessage,
|
||||
setupAgentStatus,
|
||||
t.agents.saveCommandMessage,
|
||||
t.agents.saveRequested,
|
||||
thread.isLoading,
|
||||
threadId,
|
||||
]);
|
||||
|
||||
const header = (
|
||||
<header className="flex shrink-0 items-center justify-between gap-3 border-b px-4 py-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => router.push("/workspace/agents")}
|
||||
>
|
||||
<ArrowLeftIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
<h1 className="text-sm font-semibold">{t.agents.createPageTitle}</h1>
|
||||
</div>
|
||||
|
||||
{step === "chat" ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon-sm" aria-label={t.agents.more}>
|
||||
<MoreHorizontalIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem
|
||||
onSelect={() => void handleSaveAgent()}
|
||||
disabled={
|
||||
!!agent || thread.isLoading || setupAgentStatus !== "idle"
|
||||
}
|
||||
>
|
||||
<SaveIcon className="h-4 w-4" />
|
||||
{setupAgentStatus === "requested"
|
||||
? t.agents.saving
|
||||
: t.agents.save}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : null}
|
||||
</header>
|
||||
);
|
||||
|
||||
if (step === "name") {
|
||||
return (
|
||||
<div className="flex size-full flex-col">
|
||||
{header}
|
||||
<main className="flex flex-1 flex-col items-center justify-center px-4">
|
||||
<div className="w-full max-w-sm space-y-8">
|
||||
<div className="space-y-3 text-center">
|
||||
<div className="bg-primary/10 mx-auto flex h-14 w-14 items-center justify-center rounded-full">
|
||||
<BotIcon className="text-primary h-7 w-7" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<h2 className="text-xl font-semibold">
|
||||
{t.agents.nameStepTitle}
|
||||
</h2>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
{t.agents.nameStepHint}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<Input
|
||||
autoFocus
|
||||
placeholder={t.agents.nameStepPlaceholder}
|
||||
value={nameInput}
|
||||
onChange={(e) => {
|
||||
setNameInput(e.target.value);
|
||||
setNameError("");
|
||||
}}
|
||||
onKeyDown={handleNameKeyDown}
|
||||
className={cn(nameError && "border-destructive")}
|
||||
/>
|
||||
{nameError ? (
|
||||
<p className="text-destructive text-sm">{nameError}</p>
|
||||
) : null}
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => void handleConfirmName()}
|
||||
disabled={
|
||||
!nameInput.trim() || isCheckingName || isCreatingAgent
|
||||
}
|
||||
>
|
||||
{t.agents.nameStepContinue}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThreadContext.Provider value={{ thread }}>
|
||||
<ArtifactsProvider>
|
||||
<div className="flex size-full flex-col">
|
||||
{header}
|
||||
|
||||
<main className="flex min-h-0 flex-1 flex-col">
|
||||
{showSaveHint ? (
|
||||
<div className="px-4 pt-4">
|
||||
<div className="mx-auto w-full max-w-(--container-width-md)">
|
||||
<Alert>
|
||||
<InfoIcon className="h-4 w-4" />
|
||||
<AlertDescription>{t.agents.saveHint}</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="flex min-h-0 flex-1 justify-center">
|
||||
<MessageList
|
||||
className={cn("size-full", showSaveHint ? "pt-4" : "pt-10")}
|
||||
threadId={threadId}
|
||||
thread={thread}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="bg-background flex shrink-0 justify-center border-t px-4 py-4">
|
||||
<div className="w-full max-w-(--container-width-md)">
|
||||
{agent ? (
|
||||
<div className="flex flex-col items-center gap-4 rounded-2xl border py-8 text-center">
|
||||
<CheckCircleIcon className="text-primary h-10 w-10" />
|
||||
<p className="font-semibold">{t.agents.agentCreated}</p>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/workspace/agents/${agentName}/chats/new`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{t.agents.startChatting}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => router.push("/workspace/agents")}
|
||||
>
|
||||
{t.agents.backToGallery}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<PromptInput
|
||||
onSubmit={({ text }) => void handleChatSubmit(text)}
|
||||
>
|
||||
<PromptInputTextarea
|
||||
autoFocus
|
||||
placeholder={t.agents.createPageSubtitle}
|
||||
disabled={thread.isLoading}
|
||||
/>
|
||||
<PromptInputFooter className="justify-end">
|
||||
<PromptInputSubmit disabled={thread.isLoading} />
|
||||
</PromptInputFooter>
|
||||
</PromptInput>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</ArtifactsProvider>
|
||||
</ThreadContext.Provider>
|
||||
);
|
||||
}
|
||||
5
deer-flow/frontend/src/app/workspace/agents/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { AgentGallery } from "@/components/workspace/agents/agent-gallery";
|
||||
|
||||
export default function AgentsPage() {
|
||||
return <AgentGallery />;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { PromptInputProvider } from "@/components/ai-elements/prompt-input";
|
||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||
import { SubtasksProvider } from "@/core/tasks/context";
|
||||
|
||||
export default function ChatLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<SubtasksProvider>
|
||||
<ArtifactsProvider>
|
||||
<PromptInputProvider>{children}</PromptInputProvider>
|
||||
</ArtifactsProvider>
|
||||
</SubtasksProvider>
|
||||
);
|
||||
}
|
||||