05/18/2026 Catchup - linksync project work and TicTacToe evaluations on different coding LLMs with OpenCode.
BIN
LinkSyncServer/__pycache__/app.cpython-313.pyc
Normal file
BIN
LinkSyncServer/__pycache__/routes.cpython-313.pyc
Normal file
BIN
LinkSyncServer/api/endpoints/__pycache__/links.cpython-313.pyc
Normal file
@@ -1,29 +1,40 @@
|
|||||||
"""
|
"""
|
||||||
LinkSyncServer - Collection CRUD Endpoints
|
LinkSyncServer - Collection CRUD Endpoints with SQLAlchemy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status, Query, Request
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import func, and_, or_, exists
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
import uuid
|
import uuid
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from models.base import Base, Bookmark, Collection, AuditLog, get_engine, sessionmaker
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
import os
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/collections", tags=["Collections"])
|
router = APIRouter(prefix="/api/collections", tags=["Collections"])
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CollectionCreate(BaseModel):
|
class CollectionCreate(BaseModel):
|
||||||
name: str
|
name: str = Field(..., description="Collection name")
|
||||||
description: Optional[str] = None
|
description: Optional[str] = Field(None, max_length=1024, description="Collection description")
|
||||||
query_type: str # "static" or "dynamic"
|
query_type: str = Field(default="static", description="Static or dynamic collection")
|
||||||
query_expression: Optional[dict] = None
|
query_expression: Optional[dict] = Field(None, description="Query expression for dynamic collections")
|
||||||
is_public: bool = False
|
is_public: bool = Field(default=False, description="Is collection public")
|
||||||
|
tags: Optional[List[str]] = Field(default_factory=list, description="Collection tags")
|
||||||
|
|
||||||
|
|
||||||
class CollectionUpdate(BaseModel):
|
class CollectionUpdate(BaseModel):
|
||||||
name: Optional[str] = None
|
name: Optional[str] = Field(None, max_length=255)
|
||||||
description: Optional[str] = None
|
description: Optional[str] = Field(None, max_length=1024)
|
||||||
query_type: Optional[str] = None
|
query_type: Optional[str] = Field(None)
|
||||||
query_expression: Optional[dict] = None
|
query_expression: Optional[dict] = Field(None)
|
||||||
is_public: Optional[bool] = None
|
is_public: Optional[bool] = None
|
||||||
|
tags: Optional[List[str]] = Field(None)
|
||||||
|
|
||||||
|
|
||||||
class CollectionResponse(BaseModel):
|
class CollectionResponse(BaseModel):
|
||||||
@@ -35,135 +46,188 @@ class CollectionResponse(BaseModel):
|
|||||||
is_public: bool
|
is_public: bool
|
||||||
created_at: str
|
created_at: str
|
||||||
updated_at: str
|
updated_at: str
|
||||||
|
tags: List[str]
|
||||||
|
|
||||||
|
|
||||||
def mock_create_collection(data: CollectionCreate) -> CollectionResponse:
|
def get_db():
|
||||||
"""Create collection (mock implementation)."""
|
"""Get database session."""
|
||||||
return {
|
db_session = sessionmaker(get_engine())()
|
||||||
"id": str(uuid.uuid4()),
|
return db_session
|
||||||
"name": data.name,
|
|
||||||
"description": data.description,
|
|
||||||
"query_type": data.query_type,
|
|
||||||
"query_expression": data.query_expression,
|
|
||||||
"is_public": data.is_public,
|
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
|
||||||
"updated_at": "2026-05-11T00:00:00Z"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def mock_get_collections() -> List[CollectionResponse]:
|
def get_current_user(request: Request):
|
||||||
"""Get all collections (mock implementation)."""
|
"""Get current authenticated user."""
|
||||||
return [
|
SECRET_KEY = os.environ.get("SECRET_KEY")
|
||||||
{
|
|
||||||
"id": str(uuid.uuid4()),
|
auth_header = request.headers.get("Authorization") or request.headers.get("authorization")
|
||||||
"name": "Work Links",
|
|
||||||
"description": "Links for work use",
|
if auth_header and auth_header.startswith("Bearer "):
|
||||||
"query_type": "dynamic",
|
token = auth_header[7:]
|
||||||
"query_expression": {"operation": "OR", "operands": [{"operation": "TERM", "value": "work"}]},
|
try:
|
||||||
"is_public": False,
|
import jwt
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
||||||
"updated_at": "2026-05-11T00:00:00Z"
|
return {"username": payload.get("sub"), "id": payload.get("sub")}
|
||||||
}
|
except Exception:
|
||||||
]
|
pass
|
||||||
|
|
||||||
|
return {"username": "guest"}
|
||||||
|
|
||||||
|
|
||||||
def mock_get_collection(collection_id: str) -> CollectionResponse | None:
|
class CollectionManager:
|
||||||
"""Get collection by ID (mock implementation)."""
|
"""Collection management helper."""
|
||||||
if collection_id == "mock-id":
|
|
||||||
return {
|
@staticmethod
|
||||||
"id": "mock-id",
|
def get_collection(collection_id: str) -> Optional[Collection]:
|
||||||
"name": "Work Links",
|
"""Get collection by ID."""
|
||||||
"description": "Links for work use",
|
db = get_db()
|
||||||
"query_type": "dynamic",
|
try:
|
||||||
"query_expression": {"operation": "OR", "operands": [{"operation": "TERM", "value": "work"}]},
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
"is_public": False,
|
return collection
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
except Exception:
|
||||||
"updated_at": "2026-05-11T00:00:00Z"
|
return None
|
||||||
}
|
|
||||||
return None
|
@staticmethod
|
||||||
|
def create_collection(data: CollectionCreate, request: Request) -> Collection:
|
||||||
|
"""Create new collection."""
|
||||||
def mock_update_collection(collection_id: str, data: CollectionUpdate) -> CollectionResponse | None:
|
db = get_db()
|
||||||
"""Update collection."""
|
|
||||||
return mock_get_collection(collection_id)
|
collection = Collection(
|
||||||
|
name=data.name,
|
||||||
|
description=data.description,
|
||||||
def mock_delete_collection(collection_id: str) -> bool:
|
query_type=data.query_type,
|
||||||
"""Delete collection."""
|
query_expression=data.query_expression,
|
||||||
return True
|
is_public=data.is_public,
|
||||||
|
tags=TagCollection(tags=data.tags or []),
|
||||||
|
)
|
||||||
def mock_execute_query(query_expression: dict) -> List[dict]:
|
|
||||||
"""Execute query against bookmarks (mock implementation)."""
|
db.add(collection)
|
||||||
return [
|
db.commit()
|
||||||
{
|
db.refresh(collection)
|
||||||
"id": str(uuid.uuid4()),
|
|
||||||
"url": "https://example.com/work",
|
# Create audit log
|
||||||
"title": "Work Example",
|
user = get_current_user(request)
|
||||||
"description": "An example",
|
try:
|
||||||
"notes": "",
|
audit = AuditLog(
|
||||||
"tags": ["work"],
|
action="create",
|
||||||
"favicon_url": None,
|
entity_type="Collection",
|
||||||
"path": "/Work",
|
entity_id=collection.id,
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
old_value=None,
|
||||||
"updated_at": "2026-05-11T00:00:00Z",
|
new_value=collection.dict(),
|
||||||
"visit_count": 0,
|
user_id=user.get("id")
|
||||||
"is_bookmarked": False,
|
)
|
||||||
"source_set_id": None
|
db.add(audit)
|
||||||
}
|
db.commit()
|
||||||
]
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
@router.get("/", response_model=List[CollectionResponse])
|
return collection
|
||||||
async def list_collections():
|
|
||||||
"""List all collections."""
|
@staticmethod
|
||||||
return mock_get_collections()
|
def update_collection(collection_id: str, data: CollectionUpdate, request: Request) -> Optional[Collection]:
|
||||||
|
"""Update collection."""
|
||||||
|
db = get_db()
|
||||||
@router.get("/{collection_id}", response_model=CollectionResponse)
|
|
||||||
async def get_collection(collection_id: str):
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
"""Get collection by ID."""
|
|
||||||
collection = mock_get_collection(collection_id)
|
if not collection:
|
||||||
if not collection:
|
return None
|
||||||
raise HTTPException(status_code=404, detail="Collection not found")
|
|
||||||
return collection
|
# Update fields
|
||||||
|
for field_name, value in data.dict().items():
|
||||||
|
if value is not None:
|
||||||
@router.post("/", response_model=CollectionResponse, status_code=status.HTTP_201_CREATED)
|
if hasattr(collection, field_name):
|
||||||
async def create_collection(data: CollectionCreate):
|
setattr(collection, field_name, value)
|
||||||
"""Create new collection."""
|
elif field_name == "tags":
|
||||||
collection = mock_create_collection(data)
|
if isinstance(value, list):
|
||||||
return collection
|
collection.tags.add(*value)
|
||||||
|
else:
|
||||||
|
collection.tags.update(str(value))
|
||||||
@router.put("/{collection_id}", response_model=CollectionResponse)
|
|
||||||
async def update_collection(
|
db.commit()
|
||||||
collection_id: str,
|
db.refresh(collection)
|
||||||
data: CollectionUpdate
|
|
||||||
):
|
# Create audit log
|
||||||
"""Update collection."""
|
user = get_current_user(request)
|
||||||
collection = mock_update_collection(collection_id, data)
|
try:
|
||||||
if not collection:
|
audit = AuditLog(
|
||||||
raise HTTPException(status_code=404, detail="Collection not found")
|
action="update",
|
||||||
return collection
|
entity_type="Collection",
|
||||||
|
entity_id=collection_id,
|
||||||
|
old_value=collection.dict(),
|
||||||
@router.delete("/{collection_id}", response_model=dict)
|
new_value=collection.dict(),
|
||||||
async def delete_collection(collection_id: str):
|
user_id=user.get("id")
|
||||||
"""Delete collection."""
|
)
|
||||||
success = mock_delete_collection(collection_id)
|
db.add(audit)
|
||||||
if not success:
|
db.commit()
|
||||||
raise HTTPException(status_code=404, detail="Collection not found")
|
except Exception:
|
||||||
return {"message": "Collection deleted successfully"}
|
pass
|
||||||
|
|
||||||
|
return collection
|
||||||
@router.post("/{collection_id}/refresh", response_model=dict)
|
|
||||||
async def refresh_collection(collection_id: str):
|
@staticmethod
|
||||||
"""Refresh dynamic collection (re-evaluate query)."""
|
def delete_collection(collection_id: str, request: Request) -> dict:
|
||||||
return {"message": "Collection refreshed successfully"}
|
"""Delete collection."""
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
@router.post("/execute", response_model=List[dict])
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
async def execute_query(query_expression: dict):
|
|
||||||
"""Execute query and return result set."""
|
if not collection:
|
||||||
return mock_execute_query(query_expression)
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Collection not found")
|
||||||
|
|
||||||
|
db.delete(collection)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Create audit log
|
||||||
|
user = get_current_user(request)
|
||||||
|
try:
|
||||||
|
audit = AuditLog(
|
||||||
|
action="delete",
|
||||||
|
entity_type="Collection",
|
||||||
|
entity_id=collection_id,
|
||||||
|
old_value=collection.dict(),
|
||||||
|
new_value=None,
|
||||||
|
user_id=user.get("id")
|
||||||
|
)
|
||||||
|
db.add(audit)
|
||||||
|
db.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {"message": "Collection deleted successfully", "deleted_id": collection_id}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_collection_tags(collection_id: str) -> List[str]:
|
||||||
|
"""Get collection tags."""
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
|
|
||||||
|
if not collection:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return list(collection.tags)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_collection_bookmarks(collection_id: str, limit: int = 50, offset: int = 0) -> List[Bookmark]:
|
||||||
|
"""
|
||||||
|
Get bookmarks for collection (static or dynamic).
|
||||||
|
|
||||||
|
For dynamic collections with query expression:
|
||||||
|
Use query executor to parse and filter bookmarks
|
||||||
|
"""
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
|
|
||||||
|
if not collection:
|
||||||
|
return []
|
||||||
|
|
||||||
|
if collection.query_type == "static":
|
||||||
|
# Static collection: get all bookmarks
|
||||||
|
bookmarks = db.query(Bookmark).filter(Bookmark.collection_id == collection_id).limit(limit).offset(offset).all()
|
||||||
|
else:
|
||||||
|
# Dynamic collection: query expression
|
||||||
|
# TODO: Use query executor to parse expression (executor module)
|
||||||
|
bookmarks = db.query(Bookmark).limit(limit).offset(offset).all()
|
||||||
|
|
||||||
|
return bookmarks
|
||||||
|
|||||||
@@ -1,36 +1,46 @@
|
|||||||
"""
|
"""
|
||||||
LinkSyncServer - Link CRUD Endpoints
|
LinkSyncServer - Link CRUD Endpoints with SQLAlchemy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status, Query, Request
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session, sessionmaker
|
||||||
|
from sqlalchemy import func, or_
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
import uuid
|
import uuid
|
||||||
|
import logging
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from models.base import Base, Bookmark, User, AuditLog, get_engine, create_engine
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
import os
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/links", tags=["Links"])
|
router = APIRouter(prefix="/api/links", tags=["Links"])
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BookmarkCreate(BaseModel):
|
class BookmarkCreate(BaseModel):
|
||||||
url: str
|
url: str = Field(..., description="Bookmark URL")
|
||||||
title: str
|
title: str = Field(..., min_length=1, max_length=255, description="Bookmark title")
|
||||||
description: Optional[str] = None
|
description: Optional[str] = Field(None, max_length=500, description="Optional description")
|
||||||
notes: Optional[str] = None
|
notes: Optional[str] = Field(None, max_length=2000, description="Optional notes")
|
||||||
tags: Optional[List[str]] = None
|
tags: Optional[List[str]] = Field(default_factory=list, description="List of tag names")
|
||||||
favicon_url: Optional[str] = None
|
favicon_url: Optional[str] = Field(None, max_length=512, description="Favicon URL")
|
||||||
path: Optional[str] = None
|
path: Optional[str] = Field(None, max_length=512, description="Folder path")
|
||||||
visit_count: int = 0
|
visit_count: int = Field(ge=0, description="Visit counter")
|
||||||
is_bookmarked: bool = False
|
is_bookmarked: bool = Field(default=False, description="Bookmark flag")
|
||||||
|
|
||||||
|
|
||||||
class BookmarkUpdate(BaseModel):
|
class BookmarkUpdate(BaseModel):
|
||||||
url: Optional[str] = None
|
url: Optional[str] = Field(None, description="New URL")
|
||||||
title: Optional[str] = None
|
title: Optional[str] = Field(None, min_length=1, max_length=255)
|
||||||
description: Optional[str] = None
|
description: Optional[str] = Field(None, max_length=500)
|
||||||
notes: Optional[str] = None
|
notes: Optional[str] = Field(None, max_length=2000)
|
||||||
tags: Optional[List[str]] = None
|
tags: Optional[List[str]] = Field(None)
|
||||||
favicon_url: Optional[str] = None
|
favicon_url: Optional[str] = Field(None, max_length=512)
|
||||||
path: Optional[str] = None
|
path: Optional[str] = Field(None, max_length=512)
|
||||||
visit_count: Optional[int] = None
|
visit_count: Optional[int] = Field(None, ge=0)
|
||||||
is_bookmarked: Optional[bool] = None
|
is_bookmarked: Optional[bool] = None
|
||||||
|
|
||||||
|
|
||||||
@@ -48,128 +58,301 @@ class BookmarkResponse(BaseModel):
|
|||||||
visit_count: int
|
visit_count: int
|
||||||
is_bookmarked: bool
|
is_bookmarked: bool
|
||||||
source_set_id: Optional[str]
|
source_set_id: Optional[str]
|
||||||
|
user_id: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db_session():
|
||||||
"""Get database session."""
|
"""Get database session."""
|
||||||
from models.base import get_engine
|
try:
|
||||||
db = get_engine()
|
return sessionmaker(get_engine())()
|
||||||
return db
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def mock_create_bookmark(data: BookmarkCreate) -> dict:
|
def get_current_user(request: Request):
|
||||||
"""Create bookmark (mock implementation for demo)."""
|
"""Get current authenticated user."""
|
||||||
bookmark = {
|
SECRET_KEY = os.environ.get("SECRET_KEY")
|
||||||
"id": str(uuid.uuid4()),
|
|
||||||
"url": data.url,
|
auth_header = request.headers.get("Authorization") or request.headers.get("authorization")
|
||||||
"title": data.title,
|
|
||||||
"description": data.description,
|
if auth_header and auth_header.startswith("Bearer "):
|
||||||
"notes": data.notes,
|
token = auth_header[7:]
|
||||||
"tags": data.tags or [],
|
try:
|
||||||
"favicon_url": data.favicon_url,
|
import jwt
|
||||||
"path": data.path,
|
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
return {"username": payload.get("sub"), "id": payload.get("sub")}
|
||||||
"updated_at": "2026-05-11T00:00:00Z",
|
except Exception:
|
||||||
"visit_count": data.visit_count,
|
pass
|
||||||
"is_bookmarked": data.is_bookmarked,
|
|
||||||
"source_set_id": None
|
|
||||||
}
|
|
||||||
return bookmark
|
|
||||||
|
|
||||||
|
return {"username": "guest"}
|
||||||
def mock_get_bookmarks() -> List[dict]:
|
|
||||||
"""Get all bookmarks (mock implementation)."""
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"id": str(uuid.uuid4()),
|
|
||||||
"url": "https://example.com",
|
|
||||||
"title": "Example",
|
|
||||||
"description": "An example website",
|
|
||||||
"notes": "",
|
|
||||||
"tags": ["example", "demo"],
|
|
||||||
"favicon_url": None,
|
|
||||||
"path": "/Home",
|
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
|
||||||
"updated_at": "2026-05-11T00:00:00Z",
|
|
||||||
"visit_count": 0,
|
|
||||||
"is_bookmarked": False,
|
|
||||||
"source_set_id": None
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def mock_get_bookmark(bookmark_id: str) -> dict | None:
|
|
||||||
"""Get single bookmark by ID."""
|
|
||||||
# Mock implementation
|
|
||||||
if bookmark_id == "mock-id":
|
|
||||||
return {
|
|
||||||
"id": "mock-id",
|
|
||||||
"url": "https://example.com",
|
|
||||||
"title": "Example",
|
|
||||||
"description": "An example website",
|
|
||||||
"notes": "",
|
|
||||||
"tags": ["example", "demo"],
|
|
||||||
"favicon_url": None,
|
|
||||||
"path": "/Home",
|
|
||||||
"created_at": "2026-05-11T00:00:00Z",
|
|
||||||
"updated_at": "2026-05-11T00:00:00Z",
|
|
||||||
"visit_count": 0,
|
|
||||||
"is_bookmarked": False,
|
|
||||||
"source_set_id": None
|
|
||||||
}
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def mock_update_bookmark(bookmark_id: str, data: BookmarkUpdate) -> dict | None:
|
|
||||||
"""Update bookmark."""
|
|
||||||
# Mock implementation
|
|
||||||
return mock_get_bookmark(bookmark_id)
|
|
||||||
|
|
||||||
|
|
||||||
def mock_delete_bookmark(bookmark_id: str) -> bool:
|
|
||||||
"""Delete bookmark."""
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[BookmarkResponse])
|
@router.get("/", response_model=List[BookmarkResponse])
|
||||||
async def list_bookmarks(limit: int = 20, offset: int = 0):
|
async def list_bookmarks(
|
||||||
"""List all bookmarks."""
|
limit: int = Query(20, le=100, ge=1, description="Number of results per page"),
|
||||||
bookmarks = mock_get_bookmarks()
|
offset: int = Query(0, ge=0, description="Offset for pagination"),
|
||||||
return bookmarks[offset:offset + limit]
|
search: Optional[str] = Query(None, description="Search query"),
|
||||||
|
tags_filter: Optional[List[str]] = Query(None, description="Filter by tags"),
|
||||||
|
path_filter: Optional[str] = Query(None, description="Filter by folder path")
|
||||||
|
):
|
||||||
|
"""List all bookmarks with optional filters."""
|
||||||
|
db = get_db_session()
|
||||||
|
if not db:
|
||||||
|
return []
|
||||||
|
|
||||||
|
query = Bookmark.query
|
||||||
|
|
||||||
|
# Search filter
|
||||||
|
if search:
|
||||||
|
query = query.filter((Bookmark.title.contains(search)) |
|
||||||
|
(Bookmark.description.contains(search)) |
|
||||||
|
(Bookmark.url.contains(search)))
|
||||||
|
|
||||||
|
# Tag filter
|
||||||
|
if tags_filter:
|
||||||
|
or_clause = or_(*[Bookmark.tags.contains(tag) for tag in tags_filter])
|
||||||
|
query = query.filter(or_clause)
|
||||||
|
|
||||||
|
# Path filter
|
||||||
|
if path_filter:
|
||||||
|
query = query.filter(Bookmark.path.contains(path_filter))
|
||||||
|
|
||||||
|
bookmarks = query.limit(limit).offset(offset).all()
|
||||||
|
return bookmarks
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{bookmark_id}", response_model=BookmarkResponse)
|
@router.get("/{bookmark_id}", response_model=BookmarkResponse)
|
||||||
async def get_bookmark(bookmark_id: str):
|
async def get_bookmark(bookmark_id: str):
|
||||||
"""Get bookmark by ID."""
|
"""Get bookmark by ID."""
|
||||||
bookmark = mock_get_bookmark(bookmark_id)
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
if not bookmark:
|
if not bookmark:
|
||||||
raise HTTPException(status_code=404, detail="Bookmark not found")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
return bookmark
|
return bookmark
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=BookmarkResponse, status_code=status.HTTP_201_CREATED)
|
@router.post("/", response_model=BookmarkResponse, status_code=status.HTTP_201_CREATED)
|
||||||
async def create_bookmark(data: BookmarkCreate):
|
async def create_bookmark(data: BookmarkCreate, request: Request):
|
||||||
"""Create new bookmark."""
|
"""Create new bookmark."""
|
||||||
bookmark = mock_create_bookmark(data)
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database unavailable")
|
||||||
|
|
||||||
|
bookmark = Bookmark(
|
||||||
|
url=data.url,
|
||||||
|
title=data.title,
|
||||||
|
description=data.description,
|
||||||
|
notes=data.notes,
|
||||||
|
tags=data.tags or [],
|
||||||
|
favicon_url=data.favicon_url,
|
||||||
|
path=data.path,
|
||||||
|
visit_count=data.visit_count,
|
||||||
|
is_bookmarked=data.is_bookmarked
|
||||||
|
)
|
||||||
|
|
||||||
|
bookmark_id = f"{data.url[:20]}-{uuid.uuid4()[:8]}"
|
||||||
|
bookmark = db.add(bookmark)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(bookmark)
|
||||||
|
|
||||||
|
# Get user for audit log
|
||||||
|
user = get_current_user(request)
|
||||||
|
|
||||||
|
# Create audit log (optional)
|
||||||
|
try:
|
||||||
|
audit = AuditLog(
|
||||||
|
action="create",
|
||||||
|
entity_type="Bookmark",
|
||||||
|
entity_id=bookmark_id,
|
||||||
|
old_value=None,
|
||||||
|
new_value=bookmark.dict(),
|
||||||
|
user_id=user.get("id")
|
||||||
|
)
|
||||||
|
db.add(audit)
|
||||||
|
db.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return bookmark
|
return bookmark
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{bookmark_id}", response_model=BookmarkResponse)
|
@router.put("/{bookmark_id}", response_model=BookmarkResponse)
|
||||||
async def update_bookmark(
|
async def update_bookmark(
|
||||||
bookmark_id: str,
|
bookmark_id: str,
|
||||||
data: BookmarkUpdate
|
data: BookmarkUpdate,
|
||||||
|
request: Request
|
||||||
):
|
):
|
||||||
"""Update bookmark."""
|
"""Update bookmark."""
|
||||||
bookmark = mock_update_bookmark(bookmark_id, data)
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database unavailable")
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
if not bookmark:
|
if not bookmark:
|
||||||
raise HTTPException(status_code=404, detail="Bookmark not found")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
# Update fields
|
||||||
|
for field_name, value in data.dict().items():
|
||||||
|
if value is not None:
|
||||||
|
setattr(bookmark, field_name, value)
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
db.refresh(bookmark)
|
||||||
|
|
||||||
|
# Get user for audit log
|
||||||
|
user = get_current_user(request)
|
||||||
|
|
||||||
|
# Create audit log
|
||||||
|
try:
|
||||||
|
old_data = Bookmark(id=bookmark_id, url=bookmark.url, title=bookmark.title).dict()
|
||||||
|
audit = AuditLog(
|
||||||
|
action="update",
|
||||||
|
entity_type="Bookmark",
|
||||||
|
entity_id=bookmark_id,
|
||||||
|
old_value=old_data,
|
||||||
|
new_value=bookmark.dict(),
|
||||||
|
user_id=user.get("id")
|
||||||
|
)
|
||||||
|
db.add(audit)
|
||||||
|
db.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return bookmark
|
return bookmark
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{bookmark_id}", response_model=dict)
|
@router.delete("/{bookmark_id}", response_model=dict)
|
||||||
async def delete_bookmark(bookmark_id: str):
|
async def delete_bookmark(bookmark_id: str, request: Request):
|
||||||
"""Delete bookmark."""
|
"""Delete bookmark."""
|
||||||
success = mock_delete_bookmark(bookmark_id)
|
db = get_db_session()
|
||||||
if not success:
|
|
||||||
raise HTTPException(status_code=404, detail="Bookmark not found")
|
if not db:
|
||||||
return {"message": "Bookmark deleted successfully"}
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database unavailable")
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
|
if not bookmark:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
db.delete(bookmark)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Get user for audit log
|
||||||
|
user = get_current_user(request)
|
||||||
|
|
||||||
|
# Create audit log
|
||||||
|
try:
|
||||||
|
audit = AuditLog(
|
||||||
|
action="delete",
|
||||||
|
entity_type="Bookmark",
|
||||||
|
entity_id=bookmark_id,
|
||||||
|
old_value=bookmark.dict(),
|
||||||
|
new_value=None,
|
||||||
|
user_id=user.get("id")
|
||||||
|
)
|
||||||
|
db.add(audit)
|
||||||
|
db.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {"message": "Bookmark deleted successfully", "deleted_id": bookmark_id}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{bookmark_id}/tags")
|
||||||
|
async def add_tags(bookmark_id: str, tags: List[str], request: Request):
|
||||||
|
"""Add tags to bookmark."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database unavailable")
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
|
if not bookmark:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
for tag in tags:
|
||||||
|
if tag.lower() not in [t.lower() for t in bookmark.tags]:
|
||||||
|
bookmark.tags.append(tag)
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
db.refresh(bookmark)
|
||||||
|
|
||||||
|
return bookmark
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{bookmark_id}/tags")
|
||||||
|
async def remove_tags(bookmark_id: str, tags_to_remove: List[str], request: Request):
|
||||||
|
"""Remove tags from bookmark."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database unavailable")
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
|
if not bookmark:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
bookmark.tags = [t for t in bookmark.tags if t.lower() not in [tag.lower() for tag in tags_to_remove]]
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
db.refresh(bookmark)
|
||||||
|
|
||||||
|
return bookmark
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{bookmark_id}/stats")
|
||||||
|
async def get_bookmark_stats(bookmark_id: str, request: Request):
|
||||||
|
"""Get bookmark statistics."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
bookmark = db.query(Bookmark).filter(Bookmark.id == bookmark_id).first()
|
||||||
|
|
||||||
|
if not bookmark:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bookmark not found")
|
||||||
|
|
||||||
|
# Get visit count
|
||||||
|
visits = db.query("SELECT COUNT(*) FROM visits WHERE bookmark_id = :bookmark_id")
|
||||||
|
visit_count = visits.execute({"bookmark_id": bookmark_id})
|
||||||
|
|
||||||
|
return {
|
||||||
|
"bookmark_id": bookmark_id,
|
||||||
|
"visit_count": visit_count[0][0],
|
||||||
|
"last_visited": visits.execute({"bookmark_id": bookmark_id})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Audit log helper (optional)
|
||||||
|
def create_audit_log(action: str, entity_type: str, entity_id: str, old_value: dict, new_value: dict):
|
||||||
|
"""Create audit log entry."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
audit = AuditLog(
|
||||||
|
action=action,
|
||||||
|
entity_type=entity_type,
|
||||||
|
entity_id=entity_id,
|
||||||
|
old_value=old_value,
|
||||||
|
new_value=new_value,
|
||||||
|
ip_address=request.client.host if hasattr(request, 'client') and hasattr(request.client, 'host') else None
|
||||||
|
)
|
||||||
|
db.add(audit)
|
||||||
|
db.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
188
LinkSyncServer/api/endpoints/tags.py
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
"""
|
||||||
|
LinkSyncServer - Tag Management Endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from typing import List, Optional
|
||||||
|
import logging
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from models.base import Base, Tag, Bookmark, get_engine
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/tags", tags=["Tags"])
|
||||||
|
|
||||||
|
|
||||||
|
class TagCreate(BaseModel):
|
||||||
|
name: str = Field(..., min_length=1, max_length=50)
|
||||||
|
color: Optional[str] = Field(None, max_length=7)
|
||||||
|
|
||||||
|
|
||||||
|
class TagUpdate(BaseModel):
|
||||||
|
name: Optional[str] = Field(None)
|
||||||
|
color: Optional[str] = Field(None)
|
||||||
|
|
||||||
|
|
||||||
|
class TagResponse(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
color: Optional[str]
|
||||||
|
created_at: str
|
||||||
|
updated_at: str
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_session():
|
||||||
|
"""Get database session."""
|
||||||
|
try:
|
||||||
|
return Session(get_engine())
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user(request):
|
||||||
|
"""Get current authenticated user."""
|
||||||
|
SECRET_KEY = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
auth_header = request.headers.get("Authorization") or request.headers.get("authorization")
|
||||||
|
|
||||||
|
if auth_header and auth_header.startswith("Bearer "):
|
||||||
|
token = auth_header[7:]
|
||||||
|
import jwt
|
||||||
|
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
||||||
|
return {"username": payload.get("sub"), "id": payload.get("sub")}
|
||||||
|
elif not auth_header:
|
||||||
|
return {"username": "guest"}
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {"username": "guest"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/", response_model=List[TagResponse])
|
||||||
|
async def list_tags(page: int = Query(1, ge=1), per_page: int = Query(50, ge=1, le=200)):
|
||||||
|
"""List tags with pagination."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
return []
|
||||||
|
|
||||||
|
count = db.query(Tag).count()
|
||||||
|
tags = db.query(Tag).order_by(Tag.name).offset((page - 1) * per_page).limit(per_page).all()
|
||||||
|
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/count", response_model=dict)
|
||||||
|
async def tag_count():
|
||||||
|
"""Get total tag count."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
return {"count": 0}
|
||||||
|
|
||||||
|
return {"count": db.query(Tag).count()}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{tag_id}", response_model=TagResponse)
|
||||||
|
async def get_tag(tag_id: str):
|
||||||
|
"""Get tag by ID."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
|
|
||||||
|
tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
|
|
||||||
|
if not tag:
|
||||||
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
|
|
||||||
|
return tag
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{tag_id}/links")
|
||||||
|
async def get_tag_links(tag_id: str, limit: int = Query(50, ge=1), offset: int = Query(0, ge=0)):
|
||||||
|
"""Get links for tag.""""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
return []
|
||||||
|
|
||||||
|
tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
|
|
||||||
|
if not tag:
|
||||||
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
|
|
||||||
|
links = db.query(Bookmark).join(Tag).filter(Tag.id == tag_id).limit(limit).offset(offset).all()
|
||||||
|
|
||||||
|
return links
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/", response_model=TagResponse, status_code=201)
|
||||||
|
async def create_tag(data: TagCreate, request):
|
||||||
|
"""Create new tag."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=500, detail="Database unavailable")
|
||||||
|
|
||||||
|
tag = Tag(
|
||||||
|
id=f"tag-{uuid.uuid4()[:8]}",
|
||||||
|
name=data.name,
|
||||||
|
color=data.color
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(tag)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(tag)
|
||||||
|
|
||||||
|
return tag
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{tag_id}", response_model=TagResponse)
|
||||||
|
async def update_tag(tag_id: str, data: TagUpdate):
|
||||||
|
"""Update tag."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=500, detail="Database unavailable")
|
||||||
|
|
||||||
|
tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
|
|
||||||
|
if not tag:
|
||||||
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
|
|
||||||
|
for field_name in ["name", "color"]:
|
||||||
|
if field_name in data.dict() and data.dict()[field_name] is not None:
|
||||||
|
setattr(tag, field_name, data.dict()[field_name])
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
db.refresh(tag)
|
||||||
|
|
||||||
|
return tag
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{tag_id}", response_model=dict)
|
||||||
|
async def delete_tag(tag_id: str):
|
||||||
|
"""Delete tag (and remove from all links)."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
if not db:
|
||||||
|
raise HTTPException(status_code=500, detail="Database unavailable")
|
||||||
|
|
||||||
|
tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
|
|
||||||
|
if not tag:
|
||||||
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
|
|
||||||
|
# Remove tag from all bookmarks
|
||||||
|
bookmarks = db.query(Bookmark).filter(Bookmark.tags.contains(tag.name)).all()
|
||||||
|
|
||||||
|
for bookmark in bookmarks:
|
||||||
|
bookmark.tags = [t for t in bookmark.tags if t[0] != tag_id]
|
||||||
|
|
||||||
|
db.delete(tag)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return {"message": f"Tag '{tag.name}' deleted and removed from all links"}
|
||||||
151
LinkSyncServer/api/v1/sync.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
"""
|
||||||
|
LinkSyncServer - Sync Endpoint for Browser Extension
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import APIRouter, HTTPException, status
|
||||||
|
from typing import List, Dict
|
||||||
|
import jwt
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
from models.base import Bookmark, Collection, get_engine
|
||||||
|
from api.parsers.bookmarks import BookmarkParser
|
||||||
|
from api.parsers.sync import SyncParser
|
||||||
|
import os
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/v1/sync", tags=["Sync"])
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Get database and secrets
|
||||||
|
DATABASE_URL = os.environ.get("DATABASE_URL", "sqlite:///links.db")
|
||||||
|
SECRET_KEY = os.environ.get("SECRET_KEY", "fallback-for-dev")
|
||||||
|
|
||||||
|
# Initialize parser
|
||||||
|
bookmark_parser = BookmarkParser()
|
||||||
|
sync_parser = SyncParser()
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_session():
|
||||||
|
"""Get database session."""
|
||||||
|
from sqlalchemy.pool import StaticPool
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
|
||||||
|
engine = create_engine(
|
||||||
|
DATABASE_URL,
|
||||||
|
connect_args={'check_same_thread': False}
|
||||||
|
)
|
||||||
|
return Session(engine)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_request_token(request_token: str) -> Dict:
|
||||||
|
"""
|
||||||
|
Validate sync request token.
|
||||||
|
|
||||||
|
Accepts:
|
||||||
|
- Token header from extension
|
||||||
|
- No auth for demo/maintenance
|
||||||
|
"""
|
||||||
|
if not request_token:
|
||||||
|
# Allow anonymous for demo
|
||||||
|
return {"type": "anonymous", "permissions": {}}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to decode as JWT
|
||||||
|
payload = jwt.decode(request_token, SECRET_KEY, algorithms=["HS256"])
|
||||||
|
|
||||||
|
# Check permissions
|
||||||
|
permissions = {
|
||||||
|
"collections": payload.get("permissions", {}).get("collections", []),
|
||||||
|
"bookmarks": payload.get("permissions", {}).get("bookmarks", [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"type": "authorized",
|
||||||
|
"permissions": permissions
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
# Token invalid, fall back to anonymous
|
||||||
|
return {"type": "anonymous", "permissions": {}}
|
||||||
|
|
||||||
|
|
||||||
|
def sync_with_github(account_id: str, collection_id: str, request_token: str) -> Dict:
|
||||||
|
"""
|
||||||
|
Sync bookmarks from GitHub to local collection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
account_id: GitHub account ID
|
||||||
|
collection_id: LinkSync collection ID
|
||||||
|
request_token: Token from extension request
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Sync response (JSON payload for extension)
|
||||||
|
"""
|
||||||
|
# Validate token
|
||||||
|
token_info = validate_request_token(request_token)
|
||||||
|
|
||||||
|
if token_info["type"] != "authorized":
|
||||||
|
raise HTTPException(status_code=403, detail="Unauthorized access")
|
||||||
|
|
||||||
|
# Get collection
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
collection = db.query(Collection).filter(Collection.id == collection_id).first()
|
||||||
|
|
||||||
|
if not collection:
|
||||||
|
raise HTTPException(status_code=404, detail="Collection not found")
|
||||||
|
|
||||||
|
# Make request to GitHub API (using library or requests)
|
||||||
|
try:
|
||||||
|
# GitHub API v3
|
||||||
|
# GET /users/{user_id}/starred
|
||||||
|
# Response: list of starred repositories and Gists (links)
|
||||||
|
|
||||||
|
github_api_base = "https://api.github.com"
|
||||||
|
starred_response = requests.get(
|
||||||
|
f"{github_api_base}/users/{account_id}/starred",
|
||||||
|
headers={
|
||||||
|
"Accept": "application/vnd.github.v3+json"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if starred_response.status_code != 200:
|
||||||
|
raise HTTPException(status_code=502, detail="Failed to fetch GitHub data")
|
||||||
|
|
||||||
|
github_links = starred_response.json()
|
||||||
|
|
||||||
|
# Parse GitHub data
|
||||||
|
github_bookmarks = sync_parser.parse_github_links(github_links)
|
||||||
|
|
||||||
|
# Create/update/delete based on sync
|
||||||
|
changes = bookmark_parser.parse_sync(
|
||||||
|
github_bookmarks, collection_id
|
||||||
|
)
|
||||||
|
|
||||||
|
# Commit changes
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Build response
|
||||||
|
sync_response = {
|
||||||
|
"_links": {
|
||||||
|
"sync": {
|
||||||
|
"_links": {
|
||||||
|
"self": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"account_id": account_id,
|
||||||
|
"collections": [collection_id],
|
||||||
|
"changes": changes,
|
||||||
|
"total_synced": len(github_links)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sync_response
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Sync error: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
@@ -1,128 +1,18 @@
|
|||||||
"""
|
"""
|
||||||
LinkSyncServer - Main Application
|
LinkSyncServer - Main Application
|
||||||
|
|
||||||
FastAPI application for bookmark management with advanced collection
|
|
||||||
and query capabilities.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import FastAPI, Depends, HTTPException, status
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from routes import router as api_router
|
||||||
from fastapi.staticfiles import StaticFiles
|
|
||||||
from fastapi.templating import Jinja2Templates
|
|
||||||
from fastapi.responses import HTML, JSONResponse
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import Optional
|
|
||||||
import os
|
|
||||||
import secrets
|
|
||||||
import logging
|
|
||||||
|
|
||||||
# Configure logging
|
|
||||||
logging.basicConfig(level=os.environ.get('LOG_LEVEL', 'INFO'))
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# Create FastAPI app
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="LinkSyncServer",
|
title="LinkSyncServer",
|
||||||
description="Self-hosted bookmark server with advanced collection capabilities",
|
description="Self-hosted bookmark server with collections",
|
||||||
version="1.0.0",
|
version="1.0.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS configuration
|
app.include_router(api_router)
|
||||||
allow_origins = os.environ.get('CORS_ORIGINS', 'http://localhost:5555').split(',')
|
|
||||||
|
|
||||||
app.add_middleware(
|
|
||||||
CORSMiddleware,
|
|
||||||
allow_origins=allow_origins,
|
|
||||||
allow_credentials=True,
|
|
||||||
allow_methods=['*'],
|
|
||||||
allow_headers=['*'],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Static files
|
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
||||||
|
|
||||||
# Templates
|
|
||||||
app.mount(
|
|
||||||
"/templates",
|
|
||||||
StaticFiles(directory="templates"),
|
|
||||||
name="templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Database configuration
|
|
||||||
DATABASE_URL = os.environ.get('DATABASE_URL')
|
|
||||||
SECRET_KEY = os.environ.get('SECRET_KEY', secrets.token_urlsafe(32))
|
|
||||||
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
|
|
||||||
HOST = os.environ.get('HOST', '0.0.0.0')
|
|
||||||
PORT = int(os.environ.get('PORT', 5000))
|
|
||||||
|
|
||||||
# CORS origins from environment
|
|
||||||
CORS_ORIGINS = [o.strip() for o in os.environ.get('CORS_ORIGINS', 'http://localhost:5555').split(',')]
|
|
||||||
|
|
||||||
# Add CORS middleware
|
|
||||||
app.add_middleware(
|
|
||||||
CORSMiddleware,
|
|
||||||
allow_origins=CORS_ORIGINS,
|
|
||||||
allow_credentials=True,
|
|
||||||
allow_methods=['*'],
|
|
||||||
allow_headers=['*'],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Health check endpoint
|
|
||||||
@app.get("/health")
|
@app.get("/health")
|
||||||
async def health_check():
|
def health():
|
||||||
"""Health check endpoint for Docker monitoring."""
|
return {"status": "ok"}
|
||||||
return {"status": "ok", "service": "LinkSyncServer"}
|
|
||||||
|
|
||||||
# Root endpoint
|
|
||||||
@app.get("/")
|
|
||||||
async def root():
|
|
||||||
"""Root endpoint with redirect to web UI."""
|
|
||||||
return HTML("""
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head><title>LinkSyncServer</title></head>
|
|
||||||
<body>
|
|
||||||
<h1>LinkSyncServer</h1>
|
|
||||||
<p>Web UI: <a href="/login">Login</a></p>
|
|
||||||
<p>API Docs: <a href="/api/docs">API Documentation</a></p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
""")
|
|
||||||
|
|
||||||
# Error handler
|
|
||||||
@app.exception_handler(Exception)
|
|
||||||
async def global_exception_handler(request, exc):
|
|
||||||
logger.error(f"Exception: {exc}")
|
|
||||||
return JSONResponse(
|
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
||||||
content={"detail": "Internal server error"}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Error handler for specific exceptions
|
|
||||||
@app.exception_handler(HTTPException)
|
|
||||||
async def http_exception_handler(request, exc):
|
|
||||||
return JSONResponse(
|
|
||||||
status_code=exc.status_code,
|
|
||||||
content={"detail": exc.detail}
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_api_key(user):
|
|
||||||
"""Get API key from database for a user."""
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def get_current_user(token: Optional[str] = None):
|
|
||||||
"""Get current authenticated user."""
|
|
||||||
if token:
|
|
||||||
# Validate JWT token
|
|
||||||
# In production, implement proper JWT validation
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(
|
|
||||||
"app:app",
|
|
||||||
host=HOST,
|
|
||||||
port=PORT,
|
|
||||||
reload=DEBUG
|
|
||||||
)
|
|
||||||
0
LinkSyncServer/models/__init__.py
Normal file
220
LinkSyncServer/queries/executor.py
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
"""
|
||||||
|
LinkSyncServer - Query Executor
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import List, Dict, Any, Optional
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import func, and_, or_
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, 'models')
|
||||||
|
from base import Bookmark, User
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_query_expression(query_expression: dict, expressions: list = None) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Parse query expression in dict format.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{
|
||||||
|
"operation": "OR",
|
||||||
|
"operands": [
|
||||||
|
{"operation": "TERM", "value": "work"},
|
||||||
|
{"operation": "TERM", "value": "company"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
if not query_expression:
|
||||||
|
return
|
||||||
|
|
||||||
|
operation = query_expression.get('operation')
|
||||||
|
operands = query_expression.get('operands', [])
|
||||||
|
|
||||||
|
if not operands:
|
||||||
|
# Top-level expression (e.g., TERM)
|
||||||
|
if operation == 'TERM':
|
||||||
|
value = query_expression.get('value', '')
|
||||||
|
if value.startswith('url:'):
|
||||||
|
search_term = value[4:]
|
||||||
|
return parse_term(search_term, 'url')
|
||||||
|
elif value.startswith('tag:'):
|
||||||
|
search_term = value[4:]
|
||||||
|
return parse_term(search_term, 'tags')
|
||||||
|
elif value.startswith('title:'):
|
||||||
|
search_term = value[6:]
|
||||||
|
return parse_term(search_term, 'title')
|
||||||
|
elif value.startswith('description:'):
|
||||||
|
search_term = value[12:]
|
||||||
|
return parse_term(search_term, 'description')
|
||||||
|
elif value.startswith('id:'):
|
||||||
|
return {'operation': 'EQUALS', 'value': value[3:]}
|
||||||
|
else:
|
||||||
|
# Default: search title and description
|
||||||
|
return {'operation': 'OR', 'operands': [
|
||||||
|
{'operation': 'TERM', 'value': value, 'field': 'title'},
|
||||||
|
{'operation': 'TERM', 'value': value, 'field': 'description'}
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_term(term: str, field: str):
|
||||||
|
"""
|
||||||
|
Parse field:value term.
|
||||||
|
|
||||||
|
Returns SQLAlchemy filter clause.
|
||||||
|
"""
|
||||||
|
# Handle different field types
|
||||||
|
field_filters = {
|
||||||
|
'tags': lambda term: and_(*[Bookmark.tags.ilike(f'%{term}%') for tag in term.split(',')]),
|
||||||
|
'title': lambda term: Bookmark.title.ilike(f'%{term}%'),
|
||||||
|
'description': lambda term: Bookmark.description.ilike(f'%{term}%'),
|
||||||
|
'url': lambda term: Bookmark.url.ilike(f'%{term}%'),
|
||||||
|
'path': lambda term: Bookmark.path.ilike(f'%{term}%')
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get filter function
|
||||||
|
filter_fn = field_filters.get(field, lambda term: Bookmark.tags.ilike(f'%{term}%'))
|
||||||
|
|
||||||
|
# Apply filter
|
||||||
|
filter_clause = filter_fn(term)
|
||||||
|
|
||||||
|
# Return filter clause with field
|
||||||
|
return {'field': field, 'value': term, 'clause': filter_clause}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_or_filter(operators: list, operands: list) -> Any:
|
||||||
|
"""
|
||||||
|
Parse OR filter.
|
||||||
|
|
||||||
|
Operators: ['AND', 'OR', 'XOR']
|
||||||
|
"""
|
||||||
|
if not operands:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Default to AND for safety
|
||||||
|
op_type = operators[0] if operators else 'AND'
|
||||||
|
|
||||||
|
if op_type == 'OR':
|
||||||
|
return or_(*[parse_and_filter(operators[1:], operands[1:]) for _ in range(1)])
|
||||||
|
elif op_type == 'AND':
|
||||||
|
return and_(*[parse_and_filter(operators[1:], operands[1:]) for _ in range(1)])
|
||||||
|
else:
|
||||||
|
# XOR: not supported yet
|
||||||
|
raise ValueError("XOR not supported")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_and_filter(operands: list) -> Any:
|
||||||
|
"""Parse AND filter (default)."""
|
||||||
|
if not operands:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Parse each operand
|
||||||
|
clauses = []
|
||||||
|
for operand in operands:
|
||||||
|
if isinstance(operand, str):
|
||||||
|
clause = operand
|
||||||
|
elif isinstance(operand, dict):
|
||||||
|
if operand.get('operation') == 'EQUALS':
|
||||||
|
clause = operand['value']
|
||||||
|
elif operand.get('operation') == 'TERM':
|
||||||
|
clauses.append(parse_term(operand.get('value', ''), operand.get('field', 'tags')))
|
||||||
|
# Add other term types as needed
|
||||||
|
else:
|
||||||
|
clauses.append(operand)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown operand type: {type(operand)}")
|
||||||
|
|
||||||
|
if not clauses:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return clauses
|
||||||
|
|
||||||
|
|
||||||
|
def execute_query(query_expression: dict) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Execute query and return results.
|
||||||
|
|
||||||
|
query_expression: dict from parser
|
||||||
|
returns: list of bookmarks
|
||||||
|
"""
|
||||||
|
# Default session
|
||||||
|
session = Session()
|
||||||
|
|
||||||
|
if not query_expression:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Parse query expression
|
||||||
|
try:
|
||||||
|
# Handle single-term queries
|
||||||
|
if query_expression.get('operation') == 'TERM':
|
||||||
|
search_term = query_expression.get('value', '')
|
||||||
|
field = query_expression.get('field', 'title')
|
||||||
|
|
||||||
|
if field == 'tags':
|
||||||
|
tags = search_term.split(',')
|
||||||
|
filters = [Bookmark.tags.contains(tag) for tag in tags]
|
||||||
|
result = session.query(Bookmark).filter(or_(*filters)).all()
|
||||||
|
elif field == 'title':
|
||||||
|
result = session.query(Bookmark).filter(Bookmark.title.contains(search_term)).all()
|
||||||
|
elif field == 'description':
|
||||||
|
result = session.query(Bookmark).filter(Bookmark.description.contains(search_term)).all()
|
||||||
|
elif field == 'url':
|
||||||
|
result = session.query(Bookmark).filter(Bookmark.url.contains(search_term)).all()
|
||||||
|
else:
|
||||||
|
# Default: search title and description
|
||||||
|
filters = [
|
||||||
|
or_(Bookmark.title.contains(search_term),
|
||||||
|
Bookmark.description.contains(search_term))
|
||||||
|
]
|
||||||
|
result = session.query(Bookmark).filter(or_(*filters)).all()
|
||||||
|
elif query_expression.get('operation') == 'AND':
|
||||||
|
# AND clause
|
||||||
|
clauses = parse_and_filter(query_expression.get('operands', []))
|
||||||
|
if isinstance(clauses, list):
|
||||||
|
result = session.query(Bookmark).filter(and_(*clauses)).all()
|
||||||
|
else:
|
||||||
|
result = session.query(Bookmark).filter(clauses).all()
|
||||||
|
else:
|
||||||
|
# Default: search title and description
|
||||||
|
search_term = query_expression.get('value', '')
|
||||||
|
result = session.query(Bookmark).filter(
|
||||||
|
or_(Bookmark.title.contains(search_term),
|
||||||
|
Bookmark.description.contains(search_term))
|
||||||
|
).all()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Query execution error: {e}")
|
||||||
|
result = []
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def create_bookmarks_from_sync(sync_data: dict):
|
||||||
|
"""
|
||||||
|
Create bookmarks from sync response.
|
||||||
|
|
||||||
|
sync_data: dict from GitHub API
|
||||||
|
"""
|
||||||
|
if not sync_data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Parse sync JSON
|
||||||
|
sync_info = sync_data.get('_links', {}).get('sync', {}).get('_links', {})
|
||||||
|
|
||||||
|
# Extract bookmarks
|
||||||
|
bookmarks = []
|
||||||
|
if 'objects' in sync_data:
|
||||||
|
for obj in sync_data['objects']:
|
||||||
|
if 'title' in obj:
|
||||||
|
bookmarks.append({
|
||||||
|
'url': obj.get('url', ''),
|
||||||
|
'title': obj.get('title', ''),
|
||||||
|
'description': obj.get('description', ''),
|
||||||
|
'tags': obj.get('tags', []),
|
||||||
|
'favicon_url': obj.get('favicon_url', ''),
|
||||||
|
'path': obj.get('path', ''),
|
||||||
|
'visit_count': obj.get('visit_count', 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
return bookmarks
|
||||||
351
LinkSyncServer/queries/parser.py
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
"""
|
||||||
|
LinkSyncServer - Query Parser for Expression Parser
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import Union, Dict, List, Any
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class TokenType(Enum):
|
||||||
|
OPERATOR = "OPERATOR"
|
||||||
|
TERM = "TERM"
|
||||||
|
VALUE = "VALUE"
|
||||||
|
LPAREN = "LPAREN"
|
||||||
|
RPAREN = "RPAREN"
|
||||||
|
|
||||||
|
|
||||||
|
class Token:
|
||||||
|
def __init__(self, token_type: TokenType, value: Any, line: int = 0, column: int = 0):
|
||||||
|
self.type = token_type
|
||||||
|
self.value = value
|
||||||
|
self.line = line
|
||||||
|
self.column = column
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Token({self.type.value}, {self.value!r})"
|
||||||
|
|
||||||
|
|
||||||
|
class QuerySyntaxError(Exception):
|
||||||
|
"""Syntax error in query expression."""
|
||||||
|
def __init__(self, message: str, line: int = None, column: int = None):
|
||||||
|
self.message = message
|
||||||
|
self.line = line
|
||||||
|
self.column = column
|
||||||
|
super().__init__(f"{message} at line {line}, column {column}" if line and column else message)
|
||||||
|
|
||||||
|
|
||||||
|
def lex(expression: str) -> List[Token]:
|
||||||
|
"""
|
||||||
|
Lexical analysis - convert string to tokens.
|
||||||
|
|
||||||
|
Grammar:
|
||||||
|
expression := query_item (OP query_item)*
|
||||||
|
query_item := (expression) | value | term
|
||||||
|
term := OP | value
|
||||||
|
value := url:value | tag:value | title:value | description:value | id:value
|
||||||
|
"""
|
||||||
|
tokens = []
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
# Operators
|
||||||
|
operators = ['AND', 'OR', 'XOR']
|
||||||
|
|
||||||
|
while pos < len(expression):
|
||||||
|
# Skip whitespace
|
||||||
|
if expression[pos].isspace():
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for parentheses
|
||||||
|
if expression[pos] == '(':
|
||||||
|
tokens.append(Token(TokenType.LPAREN, '('))
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if expression[pos] == ')':
|
||||||
|
tokens.append(Token(TokenType.RPAREN, ')'))
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for operators (AND, OR, XOR)
|
||||||
|
if expression[pos:pos+4] == 'AND':
|
||||||
|
tokens.append(Token(TokenType.OPERATOR, 'AND'))
|
||||||
|
pos += 4
|
||||||
|
continue
|
||||||
|
|
||||||
|
if expression[pos:pos+3] == 'OR':
|
||||||
|
tokens.append(Token(TokenType.OPERATOR, 'OR'))
|
||||||
|
pos += 3
|
||||||
|
continue
|
||||||
|
|
||||||
|
if expression[pos:pos+4] == 'XOR':
|
||||||
|
tokens.append(Token(TokenType.OPERATOR, 'XOR'))
|
||||||
|
pos += 4
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for url: prefix
|
||||||
|
if expression[pos:pos+4] == 'url:':
|
||||||
|
pos += 4
|
||||||
|
# Find end of URL
|
||||||
|
end = expression.find(':', pos)
|
||||||
|
if end == -1 and expression[pos] == '://':
|
||||||
|
# Find end of URL (next space or end of string)
|
||||||
|
end = expression.find(' ', pos)
|
||||||
|
if end == -1:
|
||||||
|
end = len(expression)
|
||||||
|
|
||||||
|
tokens.append(Token(TokenType.TERM, expression[pos:end]))
|
||||||
|
pos = end
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for tag: prefix
|
||||||
|
if expression[pos:pos+5] == 'tag:':
|
||||||
|
pos += 5
|
||||||
|
end = expression.find(':', pos)
|
||||||
|
if end == -1:
|
||||||
|
end = len(expression)
|
||||||
|
tokens.append(Token(TokenType.TERM, expression[pos:end]))
|
||||||
|
pos = end
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for title: or description: prefixes
|
||||||
|
if expression[pos:pos+6] in ['title:', 'description:']:
|
||||||
|
field = 'title' if expression[pos:pos+6] == 'title:' else 'description'
|
||||||
|
pos += 6
|
||||||
|
end = expression.find(':', pos)
|
||||||
|
if end == -1 and expression[pos] == ':' :
|
||||||
|
end = len(expression)
|
||||||
|
|
||||||
|
tokens.append(Token(TokenType.TERM, expression[pos:end]))
|
||||||
|
pos = end
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for colon (key:value)
|
||||||
|
if expression[pos] == ':':
|
||||||
|
pos += 1
|
||||||
|
# Get field name (key)
|
||||||
|
field = expression[pos]
|
||||||
|
pos += 1
|
||||||
|
# Get value
|
||||||
|
end = expression.find(' ', pos)
|
||||||
|
if end == -1:
|
||||||
|
end = len(expression)
|
||||||
|
token_val = expression[pos:end].strip('"\'')
|
||||||
|
tokens.append(Token(TokenType.VALUE, f'{field}:{token_val}'))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Regular term - alphanumeric
|
||||||
|
if expression[pos].isalnum() or expression[pos] in '-_':
|
||||||
|
start = pos
|
||||||
|
while pos < len(expression) and (expression[pos].isalnum() or expression[pos] in '-_./?=?&'):
|
||||||
|
pos += 1
|
||||||
|
tokens.append(Token(TokenType.TERM, expression[start:pos]))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Unknown character - skip or error
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
|
||||||
|
class ASTNode:
|
||||||
|
"""Abstract Syntax Tree Node."""
|
||||||
|
def __init__(self, operator: str, children: List[Union[ASTNode, str, dict]] = None):
|
||||||
|
self.operator = operator
|
||||||
|
self.children = children if children else []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"AST({self.operator}, {self.children})"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_operator(token: Token) -> str:
|
||||||
|
"""Convert operator token to Python operator string."""
|
||||||
|
if token.type != TokenType.OPERATOR:
|
||||||
|
raise QuerySyntaxError(f"Expected operator, got {token.value}")
|
||||||
|
|
||||||
|
if token.value == 'AND':
|
||||||
|
return 'and'
|
||||||
|
elif token.value == 'OR':
|
||||||
|
return 'or'
|
||||||
|
elif token.value == 'XOR':
|
||||||
|
return 'xor'
|
||||||
|
else:
|
||||||
|
raise QuerySyntaxError(f"Unknown operator: {token.value}")
|
||||||
|
|
||||||
|
|
||||||
|
class QueryParser:
|
||||||
|
"""Parser for query expressions."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.tokens = []
|
||||||
|
self.pos = 0
|
||||||
|
self.current_token = None
|
||||||
|
self.error = False
|
||||||
|
|
||||||
|
def error(self, message: str):
|
||||||
|
"""Record and return error."""
|
||||||
|
self.error = True
|
||||||
|
return QuerySyntaxError(message)
|
||||||
|
|
||||||
|
def parse_expression(self) -> List[ASTNode]:
|
||||||
|
"""Parse top-level expression (list of clauses)."""
|
||||||
|
if not self.tokens:
|
||||||
|
return []
|
||||||
|
|
||||||
|
expressions = []
|
||||||
|
|
||||||
|
# Parse first clause
|
||||||
|
expr = self.parse_or()
|
||||||
|
if expr:
|
||||||
|
expressions.append(expr)
|
||||||
|
|
||||||
|
# Parse remaining clauses
|
||||||
|
while self.current_token and self.current_token.value in ['AND', 'OR', 'XOR']:
|
||||||
|
operator = self.current_token.value
|
||||||
|
self.pos += 1
|
||||||
|
expressions.append(operator)
|
||||||
|
expr2 = self.parse_or()
|
||||||
|
if expr2:
|
||||||
|
expressions.append(expr2)
|
||||||
|
|
||||||
|
return expressions
|
||||||
|
|
||||||
|
def parse_or(self) -> Union[ASTNode, None]:
|
||||||
|
"""Parse OR clause."""
|
||||||
|
if not self.current_token:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.parse_and()
|
||||||
|
|
||||||
|
def parse_and(self) -> Union[ASTNode, None]:
|
||||||
|
"""Parse AND clause."""
|
||||||
|
left = self.parse_xor()
|
||||||
|
|
||||||
|
while self.current_token and self.current_token.value == 'OR':
|
||||||
|
operator = self.parse_operator(self.current_token)
|
||||||
|
right = self.parse_xor()
|
||||||
|
left = ASTNode(operator, [left, right])
|
||||||
|
|
||||||
|
return left
|
||||||
|
|
||||||
|
def parse_xor(self) -> Union[ASTNode, None]:
|
||||||
|
"""Parse XOR clause."""
|
||||||
|
left = self.parse_term()
|
||||||
|
|
||||||
|
while self.current_token and self.current_token.value == 'AND':
|
||||||
|
operator = self.parse_operator(self.current_token)
|
||||||
|
right = self.parse_term()
|
||||||
|
left = ASTNode(operator, [left, right])
|
||||||
|
|
||||||
|
return left
|
||||||
|
|
||||||
|
def parse_term(self):
|
||||||
|
"""Parse term."""
|
||||||
|
if self.error:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if self.pos >= len(self.tokens):
|
||||||
|
return None
|
||||||
|
|
||||||
|
token = self.current_token
|
||||||
|
|
||||||
|
# Check for parentheses (subexpression)
|
||||||
|
if token and token.value == '(':
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
sub_expr = self.parse_expression()
|
||||||
|
if not sub_expr and not self.error:
|
||||||
|
return None
|
||||||
|
if self.error:
|
||||||
|
return None
|
||||||
|
if self.current_token and self.current_token.value == ')':
|
||||||
|
self.pos += 1
|
||||||
|
return sub_expr
|
||||||
|
elif token and token.value != ')':
|
||||||
|
return token
|
||||||
|
|
||||||
|
def parse_value(self) -> Union[None, str]:
|
||||||
|
"""Parse value term."""
|
||||||
|
if self.error:
|
||||||
|
return None
|
||||||
|
|
||||||
|
token = self.current_token
|
||||||
|
if not token or token.type != TokenType.TERM:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Extract URL, TAG, etc.
|
||||||
|
term = token.value
|
||||||
|
|
||||||
|
# Check for url: value
|
||||||
|
if term.startswith('url:'):
|
||||||
|
query = {'operation': 'TERM', 'value': term[4:]}
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
return query
|
||||||
|
elif term.startswith('tag:'):
|
||||||
|
query = {'operation': 'TERM', 'value': term[4:]}
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
return query
|
||||||
|
elif term.startswith('title:'):
|
||||||
|
query = {'operation': 'TERM', 'value': term[6:]}
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
return query
|
||||||
|
elif term.startswith('description:'):
|
||||||
|
query = {'operation': 'TERM', 'value': term[12:]}
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
return query
|
||||||
|
elif term.startswith('id:'):
|
||||||
|
query = {'operation': 'EQUALS', 'value': term[3:]}
|
||||||
|
self.pos += 1
|
||||||
|
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
|
||||||
|
return query
|
||||||
|
elif term.startswith('"') or term.startswith("'"):
|
||||||
|
# Direct value
|
||||||
|
return term
|
||||||
|
else:
|
||||||
|
self.error(f"Unknown term: {term}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse(self, expression: str) -> List[ASTNode]:
|
||||||
|
"""Parse complete expression."""
|
||||||
|
if not expression:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Check for empty expression
|
||||||
|
if not expression.strip():
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Lexical analysis
|
||||||
|
self.tokens = lex(expression)
|
||||||
|
self.pos = 0
|
||||||
|
self.current_token = self.tokens[0] if self.tokens else None
|
||||||
|
|
||||||
|
if not self.tokens:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Parse expression into AST
|
||||||
|
expr = self.parse_expression()
|
||||||
|
|
||||||
|
# Return AST as dict
|
||||||
|
return [self.ast_to_dict(node) for node in expr] if expr else []
|
||||||
|
|
||||||
|
def ast_to_dict(self, node, indent=0):
|
||||||
|
"""Convert AST node to dict representation."""
|
||||||
|
if isinstance(node, ASTNode):
|
||||||
|
if node.children:
|
||||||
|
return {
|
||||||
|
"operation": node.operator,
|
||||||
|
"operands": [self.ast_to_dict(child, indent + 1) for child in node.children]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return node.value
|
||||||
|
elif isinstance(node, str):
|
||||||
|
return node
|
||||||
|
elif isinstance(node, dict):
|
||||||
|
return node
|
||||||
|
else:
|
||||||
|
return str(node)
|
||||||
20
TicTacGaming/ministral-3-14b/vite.config.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
|
||||||
|
const config = defineConfig({
|
||||||
|
base: './',
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@/game': path.resolve('./src', 'game.ts'),
|
||||||
|
'@/ui': path.resolve('./src', 'ui.ts')
|
||||||
|
}},
|
||||||
|
build: {
|
||||||
|
outDir: 'dist',
|
||||||
|
emptyOutDir: true,
|
||||||
|
rollupOptions: {
|
||||||
|
input: { main: './index.html' },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default config
|
||||||
21
TicTacToe-Compare/cogito-14b/game.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* Modern Tic Tac Toe JavaScript file
|
||||||
|
* Copyright (c) David, 2024. */
|
||||||
|
|
||||||
|
// Get DOM elementsconst gridContainer = document.getElementById('board');
|
||||||
|
const squareButtons = Array.from(document.querySelectorAll('#board button'));
|
||||||
|
|
||||||
|
class Game {
|
||||||
|
constructor() {
|
||||||
|
this.board = [
|
||||||
|
[], [], []
|
||||||
|
];
|
||||||
|
this.gameOver = false;
|
||||||
|
this.currentPlayer = '';
|
||||||
|
this.movesCount = 0;
|
||||||
|
// Initialize game board squares
|
||||||
|
squareButtons.forEach(
|
||||||
|
(btn, idx) => (
|
||||||
|
btn.addEventListener('click', () => { if(this.moveIsValid(idx))
|
||||||
|
this.updateBoard({cell:btn,squareIndex:idx,mark:'X'});
|
||||||
|
else alert("Game is over");}
|
||||||
|
))))}}
|
||||||
18
TicTacToe-Compare/cogito-14b/index.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
!<!DOCTYPE html>>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Modern Tic-Tac-Toe</title>
|
||||||
|
<link rel = "stylesheet" href = "styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="game-container">
|
||||||
|
<!-- Displays coin flip banner -->
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1 id="banner">Coin Flip...</div></h1>
|
||||||
|
</header>
|
||||||
|
<table id="board" class="ttt-game-board">
|
||||||
|
<tr>
|
||||||
|
<col><button id='cell-0' data-square-index='0'>\<button></col>
|
||||||
|
<col><button>...</button></div></td>
|
||||||
|
</table>
|
||||||
127
TicTacToe-Compare/cogito-14b/styles.css
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/* Modern Tic Tac Toe style sheet
|
||||||
|
* Copyright (c) David, 2024. */
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
html { height: 100%; background: radial-gradient(
|
||||||
|
circle at top left, blue, deep navy);
|
||||||
|
} body { margin: 0; min-height: 100vh; max-width:75vw; display: flex;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
}
|
||||||
|
game-container {
|
||||||
|
display: flex;
|
||||||
|
column-gap: clamp(2ch,3%,4ch);
|
||||||
|
padding-top: clamp(2em,2.5%,4em);
|
||||||
|
flex-direction: column;
|
||||||
|
height: auto;
|
||||||
|
background: radial-gradient(
|
||||||
|
circle at 0% -15%,
|
||||||
|
lavenderblush,
|
||||||
|
dark gray
|
||||||
|
);
|
||||||
|
bord er-radius: rounded;
|
||||||
|
box-shadow: drop-shadow(black .3em 2vw .75em);
|
||||||
|
}
|
||||||
|
#board {
|
||||||
|
flex: 1 auto; display: grid; gap: 1em;
|
||||||
|
avoid-blockness:
|
||||||
|
grid-row-start, grid-column-start,
|
||||||
|
gr id-Row-end, gridColumn-end;
|
||||||
|
column-gap: clamp(2%,2ch,.86em);
|
||||||
|
row-gap: clamp(1.5%,1vw,.76em); border: solid .4em dark green;padding-top: 0;
|
||||||
|
padding-bottom: 0; padding-left: clamp(10px, 1%, 1.25em );padding-right: clamp(10px,1vw,1.5%);
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
position:relative;height:fit-content;
|
||||||
|
min-height:.8375rem;justify-self: stretch;
|
||||||
|
padding:clamp(.375ch,4vw,.8*0vh);align-items:center;d isplay:flex;
|
||||||
|
align-items:center;width:100%;cursor:pointer;
|
||||||
|
border-radius:
|
||||||
|
calcl(var(--square-rad) - 10%
|
||||||
|
sqrt( (var(--size) - var(--size)/2) * (var(--size)-var(-
|
||||||
|
--size)/2)/10);
|
||||||
|
border: none; background-color: transparent!important;
|
||||||
|
onfocusout { border:none !important; outline:none!imp ortant}
|
||||||
|
padding: clamp(.375rem, .6*.475em,.8*3vh); box-shadow:
|
||||||
|
solid rgba(0, 0.2, 0.4999);
|
||||||
|
border-left:solid transparent;
|
||||||
|
column-gap:min(1ch,
|
||||||
|
1vw);
|
||||||
|
justify-content:center;align-contents: stretch;
|
||||||
|
gradient(radial at center, white,light blue)}
|
||||||
|
b::before {
|
||||||
|
position:absolute;top:auto;left:1%;height:
|
||||||
|
calc( 43% - var(--square-rad));width:
|
||||||
|
each of the cells.
|
||||||
|
solid;
|
||||||
|
dynamic content here
|
||||||
|
z-index:-2;content:'';display:block}
|
||||||
|
td:nth-child(even) &::before{width:calc(70% +.35em);
|
||||||
|
height:clamp(
|
||||||
|
1ch, (var(--grid-scale)), .87142rem);top:
|
||||||
|
calc(var(--square-rad)*-0.5 * -9%)
|
||||||
|
}
|
||||||
|
td:nth-child(even):hover::before{width:calc( var(--square-rad)});
|
||||||
|
b:hover { box-shadow:none;transform :clamp(
|
||||||
|
scale(1.3));z-index:2;
|
||||||
|
backface-visibility:auto; transition: transform .1s ease
|
||||||
|
out cubic-bezier(.68, -.61, .57,.94);
|
||||||
|
perspective:.01*2em!important;}
|
||||||
|
.square {
|
||||||
|
cursor:pointer;width:
|
||||||
|
clamp( 5vw ,4ch,40vh);height:clamp(3.59vw,9ch,3.795em)
|
||||||
|
}/*cell animations*/
|
||||||
|
.animating-move {
|
||||||
|
anotation-transform:"translateZ(0)";
|
||||||
|
perspective:.6em !important;
|
||||||
|
transform-origin:center center !important;}/*game status*/}#statsContainer {position:fixed bottom:2rem left: .3%
|
||||||
|
bottom: calc(.48 vw +3.57 rem);padding-bottom.calc(.1vmin+.3 vh);
|
||||||
|
padding top:calc(2px * var(--unitSize) /0.76vw)*100%;
|
||||||
|
display:fle d !important; background:radialgradient(
|
||||||
|
light coral,goldenrod)
|
||||||
|
l .5 ch .48em linear-gradient(90deg, rgba(0.35% 0%, 0%
|
||||||
|
.64% 8%) calc(.475rem),transparent calc(.211em) );
|
||||||
|
border-radius:calc( clamp( 1vh,.4*1vw . 16 rem)); box-shadow:none
|
||||||
|
solid silver
|
||||||
|
,rgba(0,0,3%,10) 3.997px)
|
||||||
|
|
||||||
|
z-index:clamp(100%,2em,54); transition:.8 s ease-in-out;
|
||||||
|
column-gap;calc(.5 % .66em ); row gap calc(.6*
|
||||||
|
, clamp(80px-.57*, 50vw) .66em)
|
||||||
|
|
||||||
|
display:flex !important flex-direction:column flex-wrap wrap
|
||||||
|
align-items flex-start;
|
||||||
|
/*Game Stats & Messages*/}
|
||||||
|
game-container #status-banner {
|
||||||
|
--animate-fraction:1; position:absolute;height
|
||||||
|
x;opacity:.65
|
||||||
|
pointer-events:none;visibility:hidden;z-index:61
|
||||||
|
callback with a .7rem gap; padding 0.2%.4 em
|
||||||
|
margin-top:clamp(1.38v h, .62 vh, -2%)
|
||||||
|
backgrou nds:gold
|
||||||
|
/*Banner Animations */
|
||||||
|
tic-tac animation for the coin flip banner*/
|
||||||
|
crossfade to show winner/caller after game ends etc.
|
||||||
|
@keyframes coin-flip-anime {
|
||||||
|
only of frames 0%,100%
|
||||||
|
{
|
||||||
|
box-shadow:none;}35% {height: calc(2.347vw .6
|
||||||
|
9 em);margin- top:.8rem
|
||||||
|
}
|
||||||
|
37.5% transform:none
|
||||||
|
} animation coinflap-animate ease infinite 5s;}}
|
||||||
|
/*Hover effects on cells*/:hover td {
|
||||||
|
display:flex;
|
||||||
|
align-items:center !important justify-content:center;
|
||||||
|
css transition transform .2s ease-out cubic-bezier(.35, -0.71 , -.64);
|
||||||
|
box-shadow:none;
|
||||||
|
borders: solid .482px transparent;
|
||||||
|
border-radius:.9em;--square-rad:var(--defaultSquareRad
|
||||||
|
/*Grid Layout & Responsive Adjustments*/#board {
|
||||||
|
display:block!important;
|
||||||
|
grid-template_rows: repeat(3,var(--square-size))auto}
|
||||||
|
@media ( max-width :768px){html {
|
||||||
|
bord er-color:light brown;
|
||||||
|
color:pale goldenrod; height:auto; background:white !important
|
||||||
|
border:none } }
|
||||||
22
TicTacToe-Compare/ministral-3-14b/dist/index.html
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Tic-Tac-Toe with AI</title>
|
||||||
|
<link rel="modulepreload" href="/game.ts">
|
||||||
|
<link rel="modulepreload" href="/ui.ts">
|
||||||
|
<style scoped src="styles.css"></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="game-container">
|
||||||
|
<h1 id="logo">✖️ Tic-Tac-Toe ✖️</h1>
|
||||||
|
<div id="status" class="status"></div>
|
||||||
|
<div id="board"></div>
|
||||||
|
<p id="player-x">👤 X Player</p>
|
||||||
|
<p id="computer-o">🤖 O Computer</p>
|
||||||
|
<button id="replay">Play Again</button>
|
||||||
|
</div>
|
||||||
|
</script type="module" src="/ui.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
22
TicTacToe-Compare/ministral-3-14b/index.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Tic-Tac-Toe with AI</title>
|
||||||
|
<link rel="modulepreload" href="/game.ts">
|
||||||
|
<link rel="modulepreload" href="/ui.ts">
|
||||||
|
<style scoped src="styles.css"></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="game-container">
|
||||||
|
<h1 id="logo">✖️ Tic-Tac-Toe ✖️</h1>
|
||||||
|
<div id="status" class="status"></div>
|
||||||
|
<div id="board"></div>
|
||||||
|
<p id="player-x">👤 X Player</p>
|
||||||
|
<p id="computer-o">🤖 O Computer</p>
|
||||||
|
<button id="replay">Play Again</button>
|
||||||
|
</div>
|
||||||
|
</script type="module" src="/ui.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/create-vite
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../create-vite/index.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../create-vite/index.js" "$@"
|
||||||
|
fi
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/create-vite.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\create-vite\index.js" %*
|
||||||
28
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/create-vite.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/cva
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../create-vite/index.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../create-vite/index.js" "$@"
|
||||||
|
fi
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/cva.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\create-vite\index.js" %*
|
||||||
28
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/cva.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../create-vite/index.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/nanoid
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../nanoid/bin/nanoid.cjs" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../nanoid/bin/nanoid.cjs" "$@"
|
||||||
|
fi
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/nanoid.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nanoid\bin\nanoid.cjs" %*
|
||||||
28
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/nanoid.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/rolldown
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../rolldown/bin/cli.mjs" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../rolldown/bin/cli.mjs" "$@"
|
||||||
|
fi
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/rolldown.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\rolldown\bin\cli.mjs" %*
|
||||||
28
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/rolldown.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../rolldown/bin/cli.mjs" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../rolldown/bin/cli.mjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../rolldown/bin/cli.mjs" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../rolldown/bin/cli.mjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/vite
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../vite/bin/vite.js" "$@"
|
||||||
|
fi
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/vite.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\vite\bin\vite.js" %*
|
||||||
28
TicTacToe-Compare/ministral-3-14b/node_modules/.bin/vite.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../vite/bin/vite.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../vite/bin/vite.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../vite/bin/vite.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../vite/bin/vite.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
344
TicTacToe-Compare/ministral-3-14b/node_modules/.package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
{
|
||||||
|
"name": "tictactoe",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"node_modules/@oxc-project/types": {
|
||||||
|
"version": "0.130.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz",
|
||||||
|
"integrity": "sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/Boshen"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rolldown/pluginutils": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/create-vite": {
|
||||||
|
"version": "9.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/create-vite/-/create-vite-9.0.7.tgz",
|
||||||
|
"integrity": "sha512-TyuOQvwX4i/QN9acJzC7wzM7FfC12/1XlH3+d05PeD7Kj5o4BObuq78fB1x84SrEoi5KcQOi+b9K3JV+PWNHvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"create-vite": "index.js",
|
||||||
|
"cva": "index.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fdir": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"lightningcss-android-arm64": "1.32.0",
|
||||||
|
"lightningcss-darwin-arm64": "1.32.0",
|
||||||
|
"lightningcss-darwin-x64": "1.32.0",
|
||||||
|
"lightningcss-freebsd-x64": "1.32.0",
|
||||||
|
"lightningcss-linux-arm-gnueabihf": "1.32.0",
|
||||||
|
"lightningcss-linux-arm64-gnu": "1.32.0",
|
||||||
|
"lightningcss-linux-arm64-musl": "1.32.0",
|
||||||
|
"lightningcss-linux-x64-gnu": "1.32.0",
|
||||||
|
"lightningcss-linux-x64-musl": "1.32.0",
|
||||||
|
"lightningcss-win32-arm64-msvc": "1.32.0",
|
||||||
|
"lightningcss-win32-x64-msvc": "1.32.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-win32-x64-msvc": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
||||||
|
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/picocolors": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postcss": {
|
||||||
|
"version": "8.5.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
|
||||||
|
"integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.11",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"source-map-js": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rolldown": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@oxc-project/types": "=0.130.0",
|
||||||
|
"@rolldown/pluginutils": "^1.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rolldown": "bin/cli.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@rolldown/binding-android-arm64": "1.0.1",
|
||||||
|
"@rolldown/binding-darwin-arm64": "1.0.1",
|
||||||
|
"@rolldown/binding-darwin-x64": "1.0.1",
|
||||||
|
"@rolldown/binding-freebsd-x64": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-arm-gnueabihf": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-arm64-gnu": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-arm64-musl": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-ppc64-gnu": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-s390x-gnu": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-x64-gnu": "1.0.1",
|
||||||
|
"@rolldown/binding-linux-x64-musl": "1.0.1",
|
||||||
|
"@rolldown/binding-openharmony-arm64": "1.0.1",
|
||||||
|
"@rolldown/binding-wasm32-wasi": "1.0.1",
|
||||||
|
"@rolldown/binding-win32-arm64-msvc": "1.0.1",
|
||||||
|
"@rolldown/binding-win32-x64-msvc": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby": {
|
||||||
|
"version": "0.2.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
|
||||||
|
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fdir": "^6.5.0",
|
||||||
|
"picomatch": "^4.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vite": {
|
||||||
|
"version": "8.0.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz",
|
||||||
|
"integrity": "sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"lightningcss": "^1.32.0",
|
||||||
|
"picomatch": "^4.0.4",
|
||||||
|
"postcss": "^8.5.14",
|
||||||
|
"rolldown": "1.0.1",
|
||||||
|
"tinyglobby": "^0.2.16"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"vite": "bin/vite.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": "^20.19.0 || >=22.12.0",
|
||||||
|
"@vitejs/devtools": "^0.1.18",
|
||||||
|
"esbuild": "^0.27.0 || ^0.28.0",
|
||||||
|
"jiti": ">=1.21.0",
|
||||||
|
"less": "^4.0.0",
|
||||||
|
"sass": "^1.70.0",
|
||||||
|
"sass-embedded": "^1.70.0",
|
||||||
|
"stylus": ">=0.54.8",
|
||||||
|
"sugarss": "^5.0.0",
|
||||||
|
"terser": "^5.16.0",
|
||||||
|
"tsx": "^4.8.1",
|
||||||
|
"yaml": "^2.4.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@vitejs/devtools": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"esbuild": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"jiti": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"less": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sass": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sass-embedded": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"stylus": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sugarss": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"terser": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"tsx": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"yaml": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
TicTacToe-Compare/ministral-3-14b/node_modules/@oxc-project/types/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024-present VoidZero Inc. & Contributors
|
||||||
|
Copyright (c) 2023 Boshen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
3
TicTacToe-Compare/ministral-3-14b/node_modules/@oxc-project/types/README.md
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Oxc Types
|
||||||
|
|
||||||
|
Typescript definitions for Oxc AST nodes.
|
||||||
26
TicTacToe-Compare/ministral-3-14b/node_modules/@oxc-project/types/package.json
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@oxc-project/types",
|
||||||
|
"version": "0.130.0",
|
||||||
|
"description": "Types for Oxc AST nodes",
|
||||||
|
"keywords": [
|
||||||
|
"AST",
|
||||||
|
"Parser"
|
||||||
|
],
|
||||||
|
"homepage": "https://oxc.rs",
|
||||||
|
"bugs": "https://github.com/oxc-project/oxc/issues",
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Boshen and oxc contributors",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/oxc-project/oxc.git",
|
||||||
|
"directory": "npm/oxc-types"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/Boshen"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"types.d.ts"
|
||||||
|
],
|
||||||
|
"type": "module",
|
||||||
|
"types": "types.d.ts"
|
||||||
|
}
|
||||||
1912
TicTacToe-Compare/ministral-3-14b/node_modules/@oxc-project/types/types.d.ts
generated
vendored
Normal file
3
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/binding-win32-x64-msvc/README.md
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# `@rolldown/binding-win32-x64-msvc`
|
||||||
|
|
||||||
|
This is the **x86_64-pc-windows-msvc** binary for `@rolldown/binding`
|
||||||
37
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/binding-win32-x64-msvc/package.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "@rolldown/binding-win32-x64-msvc",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"main": "rolldown-binding.win32-x64-msvc.node",
|
||||||
|
"files": [
|
||||||
|
"rolldown-binding.win32-x64-msvc.node"
|
||||||
|
],
|
||||||
|
"description": "Fast JavaScript/TypeScript bundler in Rust with Rollup-compatible API.",
|
||||||
|
"keywords": [
|
||||||
|
"bundler",
|
||||||
|
"esbuild",
|
||||||
|
"parcel",
|
||||||
|
"rolldown",
|
||||||
|
"rollup",
|
||||||
|
"webpack"
|
||||||
|
],
|
||||||
|
"homepage": "https://rolldown.rs/",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/rolldown/rolldown.git",
|
||||||
|
"directory": "packages/rolldown"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://registry.npmjs.org/",
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/binding-win32-x64-msvc/rolldown-binding.win32-x64-msvc.node
generated
vendored
Normal file
21
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026-present, rolldown/plugins repository contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
145
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/README.md
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# @rolldown/pluginutils [](https://npmx.dev/package/@rolldown/pluginutils)
|
||||||
|
|
||||||
|
Plugin utilities for [Rolldown](https://rolldown.rs).
|
||||||
|
|
||||||
|
Includes regex helpers for plugin hook filters, composable filter expressions, and a helper for filtering out Vite-serve-only plugins.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm add -D @rolldown/pluginutils
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { exactRegex, prefixRegex, makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils'
|
||||||
|
```
|
||||||
|
|
||||||
|
All filter helpers are also exposed via the `/filter` subpath:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { and, or, id, include } from '@rolldown/pluginutils/filter'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Regex helpers
|
||||||
|
|
||||||
|
### `exactRegex`
|
||||||
|
|
||||||
|
- **Type:** `(str: string, flags?: string) => RegExp`
|
||||||
|
|
||||||
|
Constructs a `RegExp` that matches the exact string specified. Useful as a plugin hook filter.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { exactRegex } from '@rolldown/pluginutils'
|
||||||
|
|
||||||
|
const plugin = {
|
||||||
|
name: 'plugin',
|
||||||
|
resolveId: {
|
||||||
|
filter: { id: exactRegex('foo') },
|
||||||
|
handler(id) {}, // only called for `foo`
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `prefixRegex`
|
||||||
|
|
||||||
|
- **Type:** `(str: string, flags?: string) => RegExp`
|
||||||
|
|
||||||
|
Constructs a `RegExp` that matches values starting with the specified prefix.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { prefixRegex } from '@rolldown/pluginutils'
|
||||||
|
|
||||||
|
const plugin = {
|
||||||
|
name: 'plugin',
|
||||||
|
resolveId: {
|
||||||
|
filter: { id: prefixRegex('foo') },
|
||||||
|
handler(id) {}, // called for IDs starting with `foo`
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `makeIdFiltersToMatchWithQuery`
|
||||||
|
|
||||||
|
- **Type:** `(input: string | RegExp | (string | RegExp)[]) => string | RegExp | (string | RegExp)[]`
|
||||||
|
|
||||||
|
Converts an id filter so that it also matches ids that include a query string.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils'
|
||||||
|
|
||||||
|
const plugin = {
|
||||||
|
name: 'plugin',
|
||||||
|
transform: {
|
||||||
|
filter: { id: makeIdFiltersToMatchWithQuery(['**/*.js', /\.ts$/]) },
|
||||||
|
// Matches:
|
||||||
|
// foo.js, foo.js?foo, foo.txt?foo.js,
|
||||||
|
// foo.ts, foo.ts?foo, foo.txt?foo.ts
|
||||||
|
handler(code, id) {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Composable filters
|
||||||
|
|
||||||
|
[Composable filter expressions](https://rolldown.rs/apis/plugin-api/hook-filters#composable-filters) for use cases where a simple `id`/`include`/`exclude` is not enough. For example, when a plugin needs to combine `id`, `moduleType`, `code`, and `query` conditions.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { and, code, id, include, interpreter, moduleType, or } from '@rolldown/pluginutils'
|
||||||
|
|
||||||
|
const expr = include(and(or(id(/\.tsx?$/), id(/\.jsx?$/)), moduleType('tsx'), code(/import React/)))
|
||||||
|
|
||||||
|
interpreter(expr, sourceCode, sourceId, 'tsx') // boolean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Builders
|
||||||
|
|
||||||
|
| Builder | Description |
|
||||||
|
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `and(...exprs)` | All operands must match. |
|
||||||
|
| `or(...exprs)` | At least one operand must match. |
|
||||||
|
| `not(expr)` | Negates the operand. |
|
||||||
|
| `id(pattern, params?)` | Match the module id. `pattern` is `string` or `RegExp`. `params.cleanUrl` strips the query/hash before matching. |
|
||||||
|
| `importerId(pattern, params?)` | Match the importer's id. Same shape as `id`. |
|
||||||
|
| `moduleType(type)` | Match Rolldown's module type (`'js'`, `'jsx'`, `'ts'`, `'tsx'`, `'json'`, `'text'`, `'base64'`, `'dataurl'`, `'binary'`, `'empty'`, or a custom string). |
|
||||||
|
| `code(pattern)` | Match the module source. `string` matches with `includes`; `RegExp` with `test`. |
|
||||||
|
| `query(key, pattern)` | Match a single query parameter. `pattern` is `boolean` (key presence/truthiness), `string` (exact value), or `RegExp` (value pattern). |
|
||||||
|
| `queries(obj)` | Shorthand for `and(...)` over multiple `query` entries. |
|
||||||
|
| `include(expr)` | Top-level wrapper marking `expr` as an inclusion rule. |
|
||||||
|
| `exclude(expr)` | Top-level wrapper marking `expr` as an exclusion rule. |
|
||||||
|
|
||||||
|
### `interpreter`
|
||||||
|
|
||||||
|
- **Type:** `(exprs, code?, id?, moduleType?, importerId?) => boolean`
|
||||||
|
|
||||||
|
Evaluates one or more top-level expressions against the given inputs. Returns `true` when at least one `include` matches and no `exclude` matches; when no `include` is present, defaults to `true` unless an `exclude` matches.
|
||||||
|
|
||||||
|
The argument required by each expression must be provided. For example, evaluating an `id(...)` expression without passing `id` will throw.
|
||||||
|
|
||||||
|
## `filterVitePlugins`
|
||||||
|
|
||||||
|
- **Type:** `<T>(plugins: T | T[] | null | undefined | false) => T[]`
|
||||||
|
|
||||||
|
Removes Vite plugins that target the dev server (`apply: 'serve'`) from a (possibly nested) plugin array. Plugins whose `apply` is a function are invoked with a `command: 'build'` context to decide. Useful when reusing a Vite plugin array inside a Rolldown config.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from 'rolldown'
|
||||||
|
import { filterVitePlugins } from '@rolldown/pluginutils'
|
||||||
|
import viteReact from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: filterVitePlugins([
|
||||||
|
viteReact(),
|
||||||
|
{
|
||||||
|
name: 'dev-only',
|
||||||
|
apply: 'serve', // filtered out
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
323
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/dist/filter-B_mD-HGz.mjs
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
//#region src/utils.ts
|
||||||
|
const postfixRE = /[?#].*$/;
|
||||||
|
function cleanUrl(url) {
|
||||||
|
return url.replace(postfixRE, "");
|
||||||
|
}
|
||||||
|
function extractQueryWithoutFragment(url) {
|
||||||
|
const questionMarkIndex = url.indexOf("?");
|
||||||
|
if (questionMarkIndex === -1) return "";
|
||||||
|
const fragmentIndex = url.indexOf("#", questionMarkIndex);
|
||||||
|
if (fragmentIndex === -1) return url.substring(questionMarkIndex);
|
||||||
|
else return url.substring(questionMarkIndex, fragmentIndex);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region src/filter/composable-filters.ts
|
||||||
|
var And = class {
|
||||||
|
kind;
|
||||||
|
args;
|
||||||
|
constructor(...args) {
|
||||||
|
if (args.length === 0) throw new Error("`And` expects at least one operand");
|
||||||
|
this.args = args;
|
||||||
|
this.kind = "and";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Or = class {
|
||||||
|
kind;
|
||||||
|
args;
|
||||||
|
constructor(...args) {
|
||||||
|
if (args.length === 0) throw new Error("`Or` expects at least one operand");
|
||||||
|
this.args = args;
|
||||||
|
this.kind = "or";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Not = class {
|
||||||
|
kind;
|
||||||
|
expr;
|
||||||
|
constructor(expr) {
|
||||||
|
this.expr = expr;
|
||||||
|
this.kind = "not";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Id = class {
|
||||||
|
kind;
|
||||||
|
pattern;
|
||||||
|
params;
|
||||||
|
constructor(pattern, params) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.kind = "id";
|
||||||
|
this.params = params ?? { cleanUrl: false };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ImporterId = class {
|
||||||
|
kind;
|
||||||
|
pattern;
|
||||||
|
params;
|
||||||
|
constructor(pattern, params) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.kind = "importerId";
|
||||||
|
this.params = params ?? { cleanUrl: false };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ModuleType = class {
|
||||||
|
kind;
|
||||||
|
pattern;
|
||||||
|
constructor(pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.kind = "moduleType";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Code = class {
|
||||||
|
kind;
|
||||||
|
pattern;
|
||||||
|
constructor(expr) {
|
||||||
|
this.pattern = expr;
|
||||||
|
this.kind = "code";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Query = class {
|
||||||
|
kind;
|
||||||
|
key;
|
||||||
|
pattern;
|
||||||
|
constructor(key, pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.key = key;
|
||||||
|
this.kind = "query";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Include = class {
|
||||||
|
kind;
|
||||||
|
expr;
|
||||||
|
constructor(expr) {
|
||||||
|
this.expr = expr;
|
||||||
|
this.kind = "include";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var Exclude = class {
|
||||||
|
kind;
|
||||||
|
expr;
|
||||||
|
constructor(expr) {
|
||||||
|
this.expr = expr;
|
||||||
|
this.kind = "exclude";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function and(...args) {
|
||||||
|
return new And(...args);
|
||||||
|
}
|
||||||
|
function or(...args) {
|
||||||
|
return new Or(...args);
|
||||||
|
}
|
||||||
|
function not(expr) {
|
||||||
|
return new Not(expr);
|
||||||
|
}
|
||||||
|
function id(pattern, params) {
|
||||||
|
return new Id(pattern, params);
|
||||||
|
}
|
||||||
|
function importerId(pattern, params) {
|
||||||
|
return new ImporterId(pattern, params);
|
||||||
|
}
|
||||||
|
function moduleType(pattern) {
|
||||||
|
return new ModuleType(pattern);
|
||||||
|
}
|
||||||
|
function code(pattern) {
|
||||||
|
return new Code(pattern);
|
||||||
|
}
|
||||||
|
function query(key, pattern) {
|
||||||
|
return new Query(key, pattern);
|
||||||
|
}
|
||||||
|
function include(expr) {
|
||||||
|
return new Include(expr);
|
||||||
|
}
|
||||||
|
function exclude(expr) {
|
||||||
|
return new Exclude(expr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* convert a queryObject to FilterExpression like
|
||||||
|
* ```js
|
||||||
|
* and(query(k1, v1), query(k2, v2))
|
||||||
|
* ```
|
||||||
|
* @param queryFilterObject The query filter object needs to be matched.
|
||||||
|
* @returns a `And` FilterExpression
|
||||||
|
*/
|
||||||
|
function queries(queryFilter) {
|
||||||
|
return and(...Object.entries(queryFilter).map(([key, value]) => {
|
||||||
|
return new Query(key, value);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function interpreter(exprs, code, id, moduleType, importerId) {
|
||||||
|
let arr = [];
|
||||||
|
if (Array.isArray(exprs)) arr = exprs;
|
||||||
|
else arr = [exprs];
|
||||||
|
return interpreterImpl(arr, code, id, moduleType, importerId);
|
||||||
|
}
|
||||||
|
function interpreterImpl(expr, code, id, moduleType, importerId, ctx = {}) {
|
||||||
|
let hasInclude = false;
|
||||||
|
for (const e of expr) switch (e.kind) {
|
||||||
|
case "include":
|
||||||
|
hasInclude = true;
|
||||||
|
if (exprInterpreter(e.expr, code, id, moduleType, importerId, ctx)) return true;
|
||||||
|
break;
|
||||||
|
case "exclude":
|
||||||
|
if (exprInterpreter(e.expr, code, id, moduleType, importerId, ctx)) return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return !hasInclude;
|
||||||
|
}
|
||||||
|
function exprInterpreter(expr, code, id, moduleType, importerId, ctx = {}) {
|
||||||
|
switch (expr.kind) {
|
||||||
|
case "and": return expr.args.every((e) => exprInterpreter(e, code, id, moduleType, importerId, ctx));
|
||||||
|
case "or": return expr.args.some((e) => exprInterpreter(e, code, id, moduleType, importerId, ctx));
|
||||||
|
case "not": return !exprInterpreter(expr.expr, code, id, moduleType, importerId, ctx);
|
||||||
|
case "id": {
|
||||||
|
if (id === void 0) throw new Error("`id` is required for `id` expression");
|
||||||
|
let idToMatch = id;
|
||||||
|
if (expr.params.cleanUrl) idToMatch = cleanUrl(idToMatch);
|
||||||
|
return typeof expr.pattern === "string" ? idToMatch === expr.pattern : expr.pattern.test(idToMatch);
|
||||||
|
}
|
||||||
|
case "importerId": {
|
||||||
|
if (importerId === void 0) return false;
|
||||||
|
let importerIdToMatch = importerId;
|
||||||
|
if (expr.params.cleanUrl) importerIdToMatch = cleanUrl(importerIdToMatch);
|
||||||
|
return typeof expr.pattern === "string" ? importerIdToMatch === expr.pattern : expr.pattern.test(importerIdToMatch);
|
||||||
|
}
|
||||||
|
case "moduleType":
|
||||||
|
if (moduleType === void 0) throw new Error("`moduleType` is required for `moduleType` expression");
|
||||||
|
return moduleType === expr.pattern;
|
||||||
|
case "code":
|
||||||
|
if (code === void 0) throw new Error("`code` is required for `code` expression");
|
||||||
|
return typeof expr.pattern === "string" ? code.includes(expr.pattern) : expr.pattern.test(code);
|
||||||
|
case "query": {
|
||||||
|
if (id === void 0) throw new Error("`id` is required for `Query` expression");
|
||||||
|
if (!ctx.urlSearchParamsCache) {
|
||||||
|
let queryString = extractQueryWithoutFragment(id);
|
||||||
|
ctx.urlSearchParamsCache = new URLSearchParams(queryString);
|
||||||
|
}
|
||||||
|
let urlParams = ctx.urlSearchParamsCache;
|
||||||
|
if (typeof expr.pattern === "boolean") if (expr.pattern) return urlParams.has(expr.key);
|
||||||
|
else return !urlParams.has(expr.key);
|
||||||
|
else if (typeof expr.pattern === "string") return urlParams.get(expr.key) === expr.pattern;
|
||||||
|
else return expr.pattern.test(urlParams.get(expr.key) ?? "");
|
||||||
|
}
|
||||||
|
default: throw new Error(`Expression ${JSON.stringify(expr)} is not expected.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region src/filter/filter-vite-plugins.ts
|
||||||
|
/**
|
||||||
|
* Filters out Vite plugins that have `apply: 'serve'` set.
|
||||||
|
*
|
||||||
|
* Since Rolldown operates in build mode, plugins marked with `apply: 'serve'`
|
||||||
|
* are intended only for Vite's dev server and should be excluded from the build process.
|
||||||
|
*
|
||||||
|
* @param plugins - Array of plugins (can include nested arrays)
|
||||||
|
* @returns Filtered array with serve-only plugins removed
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { defineConfig } from 'rolldown';
|
||||||
|
* import { filterVitePlugins } from '@rolldown/pluginutils';
|
||||||
|
* import viteReact from '@vitejs/plugin-react';
|
||||||
|
*
|
||||||
|
* export default defineConfig({
|
||||||
|
* plugins: filterVitePlugins([
|
||||||
|
* viteReact(),
|
||||||
|
* {
|
||||||
|
* name: 'dev-only',
|
||||||
|
* apply: 'serve', // This will be filtered out
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ])
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function filterVitePlugins(plugins) {
|
||||||
|
if (!plugins) return [];
|
||||||
|
const pluginArray = Array.isArray(plugins) ? plugins : [plugins];
|
||||||
|
const result = [];
|
||||||
|
for (const plugin of pluginArray) {
|
||||||
|
if (!plugin) continue;
|
||||||
|
if (Array.isArray(plugin)) {
|
||||||
|
result.push(...filterVitePlugins(plugin));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const pluginWithApply = plugin;
|
||||||
|
if ("apply" in pluginWithApply) {
|
||||||
|
const applyValue = pluginWithApply.apply;
|
||||||
|
if (typeof applyValue === "function") try {
|
||||||
|
if (applyValue({}, {
|
||||||
|
command: "build",
|
||||||
|
mode: "production"
|
||||||
|
})) result.push(plugin);
|
||||||
|
} catch {
|
||||||
|
result.push(plugin);
|
||||||
|
}
|
||||||
|
else if (applyValue === "serve") continue;
|
||||||
|
else result.push(plugin);
|
||||||
|
} else result.push(plugin);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region src/filter/simple-filters.ts
|
||||||
|
/**
|
||||||
|
* Constructs a RegExp that matches the exact string specified.
|
||||||
|
*
|
||||||
|
* This is useful for plugin hook filters.
|
||||||
|
*
|
||||||
|
* @param str the string to match.
|
||||||
|
* @param flags flags for the RegExp.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { exactRegex } from '@rolldown/pluginutils';
|
||||||
|
* const plugin = {
|
||||||
|
* name: 'plugin',
|
||||||
|
* resolveId: {
|
||||||
|
* filter: { id: exactRegex('foo') },
|
||||||
|
* handler(id) {} // will only be called for `foo`
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function exactRegex(str, flags) {
|
||||||
|
return new RegExp(`^${escapeRegex(str)}$`, flags);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Constructs a RegExp that matches a value that has the specified prefix.
|
||||||
|
*
|
||||||
|
* This is useful for plugin hook filters.
|
||||||
|
*
|
||||||
|
* @param str the string to match.
|
||||||
|
* @param flags flags for the RegExp.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { prefixRegex } from '@rolldown/pluginutils';
|
||||||
|
* const plugin = {
|
||||||
|
* name: 'plugin',
|
||||||
|
* resolveId: {
|
||||||
|
* filter: { id: prefixRegex('foo') },
|
||||||
|
* handler(id) {} // will only be called for IDs starting with `foo`
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function prefixRegex(str, flags) {
|
||||||
|
return new RegExp(`^${escapeRegex(str)}`, flags);
|
||||||
|
}
|
||||||
|
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
|
||||||
|
function escapeRegex(str) {
|
||||||
|
return str.replace(escapeRegexRE, "\\$&");
|
||||||
|
}
|
||||||
|
function makeIdFiltersToMatchWithQuery(input) {
|
||||||
|
if (!Array.isArray(input)) return makeIdFilterToMatchWithQuery(input);
|
||||||
|
return input.map((i) => makeIdFilterToMatchWithQuery(i));
|
||||||
|
}
|
||||||
|
function makeIdFilterToMatchWithQuery(input) {
|
||||||
|
if (typeof input === "string") return `${input}{?*,}`;
|
||||||
|
return makeRegexIdFilterToMatchWithQuery(input);
|
||||||
|
}
|
||||||
|
function makeRegexIdFilterToMatchWithQuery(input) {
|
||||||
|
return new RegExp(input.source.replace(/(?<!\\)\$/g, "(?:\\?.*)?$"), input.flags);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
export { queries as _, and as a, exprInterpreter as c, include as d, interpreter as f, or as g, not as h, filterVitePlugins as i, id as l, moduleType as m, makeIdFiltersToMatchWithQuery as n, code as o, interpreterImpl as p, prefixRegex as r, exclude as s, exactRegex as t, importerId as u, query as v };
|
||||||
194
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/dist/filter/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
//#region src/filter/composable-filters.d.ts
|
||||||
|
type StringOrRegExp = string | RegExp;
|
||||||
|
type PluginModuleType = 'js' | 'jsx' | 'ts' | 'tsx' | 'json' | 'text' | 'base64' | 'dataurl' | 'binary' | 'empty' | (string & {});
|
||||||
|
type FilterExpressionKind = FilterExpression['kind'];
|
||||||
|
type FilterExpression = And | Or | Not | Id | ImporterId | ModuleType | Code | Query;
|
||||||
|
type TopLevelFilterExpression = Include | Exclude;
|
||||||
|
declare class And {
|
||||||
|
kind: 'and';
|
||||||
|
args: FilterExpression[];
|
||||||
|
constructor(...args: FilterExpression[]);
|
||||||
|
}
|
||||||
|
declare class Or {
|
||||||
|
kind: 'or';
|
||||||
|
args: FilterExpression[];
|
||||||
|
constructor(...args: FilterExpression[]);
|
||||||
|
}
|
||||||
|
declare class Not {
|
||||||
|
kind: 'not';
|
||||||
|
expr: FilterExpression;
|
||||||
|
constructor(expr: FilterExpression);
|
||||||
|
}
|
||||||
|
interface QueryFilterObject {
|
||||||
|
[key: string]: StringOrRegExp | boolean;
|
||||||
|
}
|
||||||
|
interface IdParams {
|
||||||
|
cleanUrl?: boolean;
|
||||||
|
}
|
||||||
|
declare class Id {
|
||||||
|
kind: 'id';
|
||||||
|
pattern: StringOrRegExp;
|
||||||
|
params: IdParams;
|
||||||
|
constructor(pattern: StringOrRegExp, params?: IdParams);
|
||||||
|
}
|
||||||
|
declare class ImporterId {
|
||||||
|
kind: 'importerId';
|
||||||
|
pattern: StringOrRegExp;
|
||||||
|
params: IdParams;
|
||||||
|
constructor(pattern: StringOrRegExp, params?: IdParams);
|
||||||
|
}
|
||||||
|
declare class ModuleType {
|
||||||
|
kind: 'moduleType';
|
||||||
|
pattern: PluginModuleType;
|
||||||
|
constructor(pattern: PluginModuleType);
|
||||||
|
}
|
||||||
|
declare class Code {
|
||||||
|
kind: 'code';
|
||||||
|
pattern: StringOrRegExp;
|
||||||
|
constructor(expr: StringOrRegExp);
|
||||||
|
}
|
||||||
|
declare class Query {
|
||||||
|
kind: 'query';
|
||||||
|
key: string;
|
||||||
|
pattern: StringOrRegExp | boolean;
|
||||||
|
constructor(key: string, pattern: StringOrRegExp | boolean);
|
||||||
|
}
|
||||||
|
declare class Include {
|
||||||
|
kind: 'include';
|
||||||
|
expr: FilterExpression;
|
||||||
|
constructor(expr: FilterExpression);
|
||||||
|
}
|
||||||
|
declare class Exclude {
|
||||||
|
kind: 'exclude';
|
||||||
|
expr: FilterExpression;
|
||||||
|
constructor(expr: FilterExpression);
|
||||||
|
}
|
||||||
|
declare function and(...args: FilterExpression[]): And;
|
||||||
|
declare function or(...args: FilterExpression[]): Or;
|
||||||
|
declare function not(expr: FilterExpression): Not;
|
||||||
|
declare function id(pattern: StringOrRegExp, params?: IdParams): Id;
|
||||||
|
declare function importerId(pattern: StringOrRegExp, params?: IdParams): ImporterId;
|
||||||
|
declare function moduleType(pattern: PluginModuleType): ModuleType;
|
||||||
|
declare function code(pattern: StringOrRegExp): Code;
|
||||||
|
declare function query(key: string, pattern: StringOrRegExp | boolean): Query;
|
||||||
|
declare function include(expr: FilterExpression): Include;
|
||||||
|
declare function exclude(expr: FilterExpression): Exclude;
|
||||||
|
/**
|
||||||
|
* convert a queryObject to FilterExpression like
|
||||||
|
* ```js
|
||||||
|
* and(query(k1, v1), query(k2, v2))
|
||||||
|
* ```
|
||||||
|
* @param queryFilterObject The query filter object needs to be matched.
|
||||||
|
* @returns a `And` FilterExpression
|
||||||
|
*/
|
||||||
|
declare function queries(queryFilter: QueryFilterObject): And;
|
||||||
|
declare function interpreter(exprs: TopLevelFilterExpression | TopLevelFilterExpression[], code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string): boolean;
|
||||||
|
interface InterpreterCtx {
|
||||||
|
urlSearchParamsCache?: URLSearchParams;
|
||||||
|
}
|
||||||
|
declare function interpreterImpl(expr: TopLevelFilterExpression[], code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string, ctx?: InterpreterCtx): boolean;
|
||||||
|
declare function exprInterpreter(expr: FilterExpression, code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string, ctx?: InterpreterCtx): boolean;
|
||||||
|
//#endregion
|
||||||
|
//#region src/filter/filter-vite-plugins.d.ts
|
||||||
|
/**
|
||||||
|
* Filters out Vite plugins that have `apply: 'serve'` set.
|
||||||
|
*
|
||||||
|
* Since Rolldown operates in build mode, plugins marked with `apply: 'serve'`
|
||||||
|
* are intended only for Vite's dev server and should be excluded from the build process.
|
||||||
|
*
|
||||||
|
* @param plugins - Array of plugins (can include nested arrays)
|
||||||
|
* @returns Filtered array with serve-only plugins removed
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { defineConfig } from 'rolldown';
|
||||||
|
* import { filterVitePlugins } from '@rolldown/pluginutils';
|
||||||
|
* import viteReact from '@vitejs/plugin-react';
|
||||||
|
*
|
||||||
|
* export default defineConfig({
|
||||||
|
* plugins: filterVitePlugins([
|
||||||
|
* viteReact(),
|
||||||
|
* {
|
||||||
|
* name: 'dev-only',
|
||||||
|
* apply: 'serve', // This will be filtered out
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ])
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function filterVitePlugins<T = any>(plugins: T | T[] | null | undefined | false): T[];
|
||||||
|
//#endregion
|
||||||
|
//#region src/filter/simple-filters.d.ts
|
||||||
|
/**
|
||||||
|
* Constructs a RegExp that matches the exact string specified.
|
||||||
|
*
|
||||||
|
* This is useful for plugin hook filters.
|
||||||
|
*
|
||||||
|
* @param str the string to match.
|
||||||
|
* @param flags flags for the RegExp.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { exactRegex } from '@rolldown/pluginutils';
|
||||||
|
* const plugin = {
|
||||||
|
* name: 'plugin',
|
||||||
|
* resolveId: {
|
||||||
|
* filter: { id: exactRegex('foo') },
|
||||||
|
* handler(id) {} // will only be called for `foo`
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function exactRegex(str: string, flags?: string): RegExp;
|
||||||
|
/**
|
||||||
|
* Constructs a RegExp that matches a value that has the specified prefix.
|
||||||
|
*
|
||||||
|
* This is useful for plugin hook filters.
|
||||||
|
*
|
||||||
|
* @param str the string to match.
|
||||||
|
* @param flags flags for the RegExp.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { prefixRegex } from '@rolldown/pluginutils';
|
||||||
|
* const plugin = {
|
||||||
|
* name: 'plugin',
|
||||||
|
* resolveId: {
|
||||||
|
* filter: { id: prefixRegex('foo') },
|
||||||
|
* handler(id) {} // will only be called for IDs starting with `foo`
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function prefixRegex(str: string, flags?: string): RegExp;
|
||||||
|
type WidenString<T> = T extends string ? string : T;
|
||||||
|
/**
|
||||||
|
* Converts a id filter to match with an id with a query.
|
||||||
|
*
|
||||||
|
* @param input the id filters to convert.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils';
|
||||||
|
* const plugin = {
|
||||||
|
* name: 'plugin',
|
||||||
|
* transform: {
|
||||||
|
* filter: { id: makeIdFiltersToMatchWithQuery(['**' + '/*.js', /\.ts$/]) },
|
||||||
|
* // The handler will be called for IDs like:
|
||||||
|
* // - foo.js
|
||||||
|
* // - foo.js?foo
|
||||||
|
* // - foo.txt?foo.js
|
||||||
|
* // - foo.ts
|
||||||
|
* // - foo.ts?foo
|
||||||
|
* // - foo.txt?foo.ts
|
||||||
|
* handler(code, id) {}
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function makeIdFiltersToMatchWithQuery<T extends string | RegExp>(input: T): WidenString<T>;
|
||||||
|
declare function makeIdFiltersToMatchWithQuery<T extends string | RegExp>(input: readonly T[]): WidenString<T>[];
|
||||||
|
declare function makeIdFiltersToMatchWithQuery(input: string | RegExp | readonly (string | RegExp)[]): string | RegExp | (string | RegExp)[];
|
||||||
|
//#endregion
|
||||||
|
export { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||||
2
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/dist/filter/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { _ as queries, a as and, c as exprInterpreter, d as include, f as interpreter, g as or, h as not, i as filterVitePlugins, l as id, m as moduleType, n as makeIdFiltersToMatchWithQuery, o as code, p as interpreterImpl, r as prefixRegex, s as exclude, t as exactRegex, u as importerId, v as query } from "../filter-B_mD-HGz.mjs";
|
||||||
|
export { and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||||
2
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/dist/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query } from "./filter/index.mjs";
|
||||||
|
export { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||||
2
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { _ as queries, a as and, c as exprInterpreter, d as include, f as interpreter, g as or, h as not, i as filterVitePlugins, l as id, m as moduleType, n as makeIdFiltersToMatchWithQuery, o as code, p as interpreterImpl, r as prefixRegex, s as exclude, t as exactRegex, u as importerId, v as query } from "./filter-B_mD-HGz.mjs";
|
||||||
|
export { and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||||
40
TicTacToe-Compare/ministral-3-14b/node_modules/@rolldown/pluginutils/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "@rolldown/pluginutils",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"description": "Plugin utilities for Rolldown",
|
||||||
|
"keywords": [
|
||||||
|
"filter",
|
||||||
|
"plugin",
|
||||||
|
"rolldown"
|
||||||
|
],
|
||||||
|
"homepage": "https://github.com/rolldown/plugins/tree/main/packages/pluginutils#readme",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/rolldown/plugins/issues"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/rolldown/plugins.git",
|
||||||
|
"directory": "packages/pluginutils"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": "./dist/index.mjs",
|
||||||
|
"./filter": "./dist/filter/index.mjs",
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/picomatch": "^4.0.3",
|
||||||
|
"picomatch": "^4.0.4",
|
||||||
|
"typescript": "^5.9.3"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsdown --watch",
|
||||||
|
"build": "tsdown",
|
||||||
|
"test": "vitest --project pluginutils",
|
||||||
|
"test:types": "vitest --project pluginutils --typecheck.only"
|
||||||
|
}
|
||||||
|
}
|
||||||
577
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,577 @@
|
|||||||
|
# create-vite license
|
||||||
|
create-vite is released under the MIT license:
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019-present, VoidZero Inc. and Vite contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
# License of the files in the directories starting with "template-" in create-vite
|
||||||
|
The files in the directories starting with "template-" in create-vite and files
|
||||||
|
generated from those files are licensed under the CC0 1.0 Universal license:
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator and
|
||||||
|
subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for the
|
||||||
|
purpose of contributing to a commons of creative, cultural and scientific
|
||||||
|
works ("Commons") that the public can reliably and without fear of later
|
||||||
|
claims of infringement build upon, modify, incorporate in other works, reuse
|
||||||
|
and redistribute as freely as possible in any form whatsoever and for any
|
||||||
|
purposes, including without limitation commercial purposes. These owners may
|
||||||
|
contribute to the Commons to promote the ideal of a free culture and the
|
||||||
|
further production of creative, cultural and scientific works, or to gain
|
||||||
|
reputation or greater distribution for their Work in part through the use and
|
||||||
|
efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any expectation
|
||||||
|
of additional consideration or compensation, the person associating CC0 with a
|
||||||
|
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
|
||||||
|
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
|
||||||
|
and publicly distribute the Work under its terms, with knowledge of his or her
|
||||||
|
Copyright and Related Rights in the Work and the meaning and intended legal
|
||||||
|
effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not limited
|
||||||
|
to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display, communicate,
|
||||||
|
and translate a Work;
|
||||||
|
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or likeness
|
||||||
|
depicted in a Work;
|
||||||
|
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data in
|
||||||
|
a Work;
|
||||||
|
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation thereof,
|
||||||
|
including any amended or successor version of such directive); and
|
||||||
|
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the world
|
||||||
|
based on applicable law or treaty, and any national implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention of,
|
||||||
|
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
|
||||||
|
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
|
||||||
|
and Related Rights and associated claims and causes of action, whether now
|
||||||
|
known or unknown (including existing as well as future claims and causes of
|
||||||
|
action), in the Work (i) in all territories worldwide, (ii) for the maximum
|
||||||
|
duration provided by applicable law or treaty (including future time
|
||||||
|
extensions), (iii) in any current or future medium and for any number of
|
||||||
|
copies, and (iv) for any purpose whatsoever, including without limitation
|
||||||
|
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
|
||||||
|
the Waiver for the benefit of each member of the public at large and to the
|
||||||
|
detriment of Affirmer's heirs and successors, fully intending that such Waiver
|
||||||
|
shall not be subject to revocation, rescission, cancellation, termination, or
|
||||||
|
any other legal or equitable action to disrupt the quiet enjoyment of the Work
|
||||||
|
by the public as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason be
|
||||||
|
judged legally invalid or ineffective under applicable law, then the Waiver
|
||||||
|
shall be preserved to the maximum extent permitted taking into account
|
||||||
|
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
|
||||||
|
is so judged Affirmer hereby grants to each affected person a royalty-free,
|
||||||
|
non transferable, non sublicensable, non exclusive, irrevocable and
|
||||||
|
unconditional license to exercise Affirmer's Copyright and Related Rights in
|
||||||
|
the Work (i) in all territories worldwide, (ii) for the maximum duration
|
||||||
|
provided by applicable law or treaty (including future time extensions), (iii)
|
||||||
|
in any current or future medium and for any number of copies, and (iv) for any
|
||||||
|
purpose whatsoever, including without limitation commercial, advertising or
|
||||||
|
promotional purposes (the "License"). The License shall be deemed effective as
|
||||||
|
of the date CC0 was applied by Affirmer to the Work. Should any part of the
|
||||||
|
License for any reason be judged legally invalid or ineffective under
|
||||||
|
applicable law, such partial invalidity or ineffectiveness shall not
|
||||||
|
invalidate the remainder of the License, and in such case Affirmer hereby
|
||||||
|
affirms that he or she will not (i) exercise any of his or her remaining
|
||||||
|
Copyright and Related Rights in the Work or (ii) assert any associated claims
|
||||||
|
and causes of action with respect to the Work, in either case contrary to
|
||||||
|
Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or warranties
|
||||||
|
of any kind concerning the Work, express, implied, statutory or otherwise,
|
||||||
|
including without limitation warranties of title, merchantability, fitness
|
||||||
|
for a particular purpose, non infringement, or the absence of latent or
|
||||||
|
other defects, accuracy, or the present or absence of errors, whether or not
|
||||||
|
discoverable, all to the greatest extent permissible under applicable law.
|
||||||
|
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without limitation
|
||||||
|
any person's Copyright and Related Rights in the Work. Further, Affirmer
|
||||||
|
disclaims responsibility for obtaining any necessary consents, permissions
|
||||||
|
or other rights required for any use of the Work.
|
||||||
|
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to this
|
||||||
|
CC0 or use of the Work.
|
||||||
|
|
||||||
|
For more information, please see
|
||||||
|
<http://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
|
||||||
|
# Licenses of bundled dependencies
|
||||||
|
The published create-vite artifact additionally contains code with the following licenses:
|
||||||
|
Apache-2.0, ISC, MIT
|
||||||
|
|
||||||
|
# Bundled dependencies:
|
||||||
|
## @clack/core, @clack/prompts
|
||||||
|
License: MIT
|
||||||
|
By: Nate Moore
|
||||||
|
Repositories: https://github.com/bombshell-dev/clack, https://github.com/bombshell-dev/clack
|
||||||
|
|
||||||
|
> MIT License
|
||||||
|
>
|
||||||
|
> Copyright (c) Nate Moore
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## @vercel/detect-agent
|
||||||
|
License: Apache-2.0
|
||||||
|
By: Vercel
|
||||||
|
Repository: https://github.com/vercel/vercel
|
||||||
|
|
||||||
|
> Apache License
|
||||||
|
> Version 2.0, January 2004
|
||||||
|
> http://www.apache.org/licenses/
|
||||||
|
>
|
||||||
|
> TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
>
|
||||||
|
> 1. Definitions.
|
||||||
|
>
|
||||||
|
> "License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
> and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
>
|
||||||
|
> "Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
> the copyright owner that is granting the License.
|
||||||
|
>
|
||||||
|
> "Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
> other entities that control, are controlled by, or are under common
|
||||||
|
> control with that entity. For the purposes of this definition,
|
||||||
|
> "control" means (i) the power, direct or indirect, to cause the
|
||||||
|
> direction or management of such entity, whether by contract or
|
||||||
|
> otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
> outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
>
|
||||||
|
> "You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
> exercising permissions granted by this License.
|
||||||
|
>
|
||||||
|
> "Source" form shall mean the preferred form for making modifications,
|
||||||
|
> including but not limited to software source code, documentation
|
||||||
|
> source, and configuration files.
|
||||||
|
>
|
||||||
|
> "Object" form shall mean any form resulting from mechanical
|
||||||
|
> transformation or translation of a Source form, including but
|
||||||
|
> not limited to compiled object code, generated documentation,
|
||||||
|
> and conversions to other media types.
|
||||||
|
>
|
||||||
|
> "Work" shall mean the work of authorship, whether in Source or
|
||||||
|
> Object form, made available under the License, as indicated by a
|
||||||
|
> copyright notice that is included in or attached to the work
|
||||||
|
> (an example is provided in the Appendix below).
|
||||||
|
>
|
||||||
|
> "Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
> form, that is based on (or derived from) the Work and for which the
|
||||||
|
> editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
> represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
> of this License, Derivative Works shall not include works that remain
|
||||||
|
> separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
> the Work and Derivative Works thereof.
|
||||||
|
>
|
||||||
|
> "Contribution" shall mean any work of authorship, including
|
||||||
|
> the original version of the Work and any modifications or additions
|
||||||
|
> to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
> submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
> or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
> the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
> means any form of electronic, verbal, or written communication sent
|
||||||
|
> to the Licensor or its representatives, including but not limited to
|
||||||
|
> communication on electronic mailing lists, source code control systems,
|
||||||
|
> and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
> Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
> excluding communication that is conspicuously marked or otherwise
|
||||||
|
> designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
>
|
||||||
|
> "Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
> on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
> subsequently incorporated within the Work.
|
||||||
|
>
|
||||||
|
> 2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
> this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
> worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
> copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
> publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
> Work and such Derivative Works in Source or Object form.
|
||||||
|
>
|
||||||
|
> 3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
> this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
> worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
> (except as stated in this section) patent license to make, have made,
|
||||||
|
> use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
> where such license applies only to those patent claims licensable
|
||||||
|
> by such Contributor that are necessarily infringed by their
|
||||||
|
> Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
> with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
> institute patent litigation against any entity (including a
|
||||||
|
> cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
> or a Contribution incorporated within the Work constitutes direct
|
||||||
|
> or contributory patent infringement, then any patent licenses
|
||||||
|
> granted to You under this License for that Work shall terminate
|
||||||
|
> as of the date such litigation is filed.
|
||||||
|
>
|
||||||
|
> 4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
> Work or Derivative Works thereof in any medium, with or without
|
||||||
|
> modifications, and in Source or Object form, provided that You
|
||||||
|
> meet the following conditions:
|
||||||
|
>
|
||||||
|
> (a) You must give any other recipients of the Work or
|
||||||
|
> Derivative Works a copy of this License; and
|
||||||
|
>
|
||||||
|
> (b) You must cause any modified files to carry prominent notices
|
||||||
|
> stating that You changed the files; and
|
||||||
|
>
|
||||||
|
> (c) You must retain, in the Source form of any Derivative Works
|
||||||
|
> that You distribute, all copyright, patent, trademark, and
|
||||||
|
> attribution notices from the Source form of the Work,
|
||||||
|
> excluding those notices that do not pertain to any part of
|
||||||
|
> the Derivative Works; and
|
||||||
|
>
|
||||||
|
> (d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
> distribution, then any Derivative Works that You distribute must
|
||||||
|
> include a readable copy of the attribution notices contained
|
||||||
|
> within such NOTICE file, excluding those notices that do not
|
||||||
|
> pertain to any part of the Derivative Works, in at least one
|
||||||
|
> of the following places: within a NOTICE text file distributed
|
||||||
|
> as part of the Derivative Works; within the Source form or
|
||||||
|
> documentation, if provided along with the Derivative Works; or,
|
||||||
|
> within a display generated by the Derivative Works, if and
|
||||||
|
> wherever such third-party notices normally appear. The contents
|
||||||
|
> of the NOTICE file are for informational purposes only and
|
||||||
|
> do not modify the License. You may add Your own attribution
|
||||||
|
> notices within Derivative Works that You distribute, alongside
|
||||||
|
> or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
> that such additional attribution notices cannot be construed
|
||||||
|
> as modifying the License.
|
||||||
|
>
|
||||||
|
> You may add Your own copyright statement to Your modifications and
|
||||||
|
> may provide additional or different license terms and conditions
|
||||||
|
> for use, reproduction, or distribution of Your modifications, or
|
||||||
|
> for any such Derivative Works as a whole, provided Your use,
|
||||||
|
> reproduction, and distribution of the Work otherwise complies with
|
||||||
|
> the conditions stated in this License.
|
||||||
|
>
|
||||||
|
> 5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
> any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
> by You to the Licensor shall be under the terms and conditions of
|
||||||
|
> this License, without any additional terms or conditions.
|
||||||
|
> Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
> the terms of any separate license agreement you may have executed
|
||||||
|
> with Licensor regarding such Contributions.
|
||||||
|
>
|
||||||
|
> 6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
> names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
> except as required for reasonable and customary use in describing the
|
||||||
|
> origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
>
|
||||||
|
> 7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
> agreed to in writing, Licensor provides the Work (and each
|
||||||
|
> Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
> implied, including, without limitation, any warranties or conditions
|
||||||
|
> of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
> PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
> appropriateness of using or redistributing the Work and assume any
|
||||||
|
> risks associated with Your exercise of permissions under this License.
|
||||||
|
>
|
||||||
|
> 8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
> whether in tort (including negligence), contract, or otherwise,
|
||||||
|
> unless required by applicable law (such as deliberate and grossly
|
||||||
|
> negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
> liable to You for damages, including any direct, indirect, special,
|
||||||
|
> incidental, or consequential damages of any character arising as a
|
||||||
|
> result of this License or out of the use or inability to use the
|
||||||
|
> Work (including but not limited to damages for loss of goodwill,
|
||||||
|
> work stoppage, computer failure or malfunction, or any and all
|
||||||
|
> other commercial damages or losses), even if such Contributor
|
||||||
|
> has been advised of the possibility of such damages.
|
||||||
|
>
|
||||||
|
> 9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
> the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
> and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
> or other liability obligations and/or rights consistent with this
|
||||||
|
> License. However, in accepting such obligations, You may act only
|
||||||
|
> on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
> of any other Contributor, and only if You agree to indemnify,
|
||||||
|
> defend, and hold each Contributor harmless for any liability
|
||||||
|
> incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
> of your accepting any such warranty or additional liability.
|
||||||
|
>
|
||||||
|
> END OF TERMS AND CONDITIONS
|
||||||
|
>
|
||||||
|
> APPENDIX: How to apply the Apache License to your work.
|
||||||
|
>
|
||||||
|
> To apply the Apache License to your work, attach the following
|
||||||
|
> boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
> replaced with your own identifying information. (Don't include
|
||||||
|
> the brackets!) The text should be enclosed in the appropriate
|
||||||
|
> comment syntax for the file format. We also recommend that a
|
||||||
|
> file or class name and description of purpose be included on the
|
||||||
|
> same "printed page" as the copyright notice for easier
|
||||||
|
> identification within third-party archives.
|
||||||
|
>
|
||||||
|
> Copyright 2017 Vercel, Inc.
|
||||||
|
>
|
||||||
|
> Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
> you may not use this file except in compliance with the License.
|
||||||
|
> You may obtain a copy of the License at
|
||||||
|
>
|
||||||
|
> http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
>
|
||||||
|
> Unless required by applicable law or agreed to in writing, software
|
||||||
|
> distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
> See the License for the specific language governing permissions and
|
||||||
|
> limitations under the License.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## cross-spawn
|
||||||
|
License: MIT
|
||||||
|
By: André Cruz
|
||||||
|
Repository: https://github.com/moxystudio/node-cross-spawn
|
||||||
|
|
||||||
|
> The MIT License (MIT)
|
||||||
|
>
|
||||||
|
> Copyright (c) 2018 Made With MOXY Lda <hello@moxy.studio>
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
> in the Software without restriction, including without limitation the rights
|
||||||
|
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
> copies of the Software, and to permit persons to whom the Software is
|
||||||
|
> furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in
|
||||||
|
> all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
> THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## fast-string-truncated-width, fast-string-width
|
||||||
|
License: MIT
|
||||||
|
Repositories: https://github.com/fabiospampinato/fast-string-truncated-width, https://github.com/fabiospampinato/fast-string-width
|
||||||
|
|
||||||
|
> The MIT License (MIT)
|
||||||
|
>
|
||||||
|
> Copyright (c) 2024-present Fabio Spampinato
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
> copy of this software and associated documentation files (the "Software"),
|
||||||
|
> to deal in the Software without restriction, including without limitation
|
||||||
|
> the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
> and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
> Software is furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in
|
||||||
|
> all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
> DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## fast-wrap-ansi
|
||||||
|
License: MIT
|
||||||
|
By: James Garbutt
|
||||||
|
Repository: https://github.com/43081j/fast-wrap-ansi
|
||||||
|
|
||||||
|
> MIT License
|
||||||
|
>
|
||||||
|
> Copyright (c) 2025 James Garbutt
|
||||||
|
>
|
||||||
|
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
> in the Software without restriction, including without limitation the rights
|
||||||
|
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
> copies of the Software, and to permit persons to whom the Software is
|
||||||
|
> furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all
|
||||||
|
> copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
> SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## isexe, which
|
||||||
|
License: ISC
|
||||||
|
By: Isaac Z. Schlueter
|
||||||
|
Repositories: https://github.com/isaacs/isexe, https://github.com/isaacs/node-which
|
||||||
|
|
||||||
|
> The ISC License
|
||||||
|
>
|
||||||
|
> Copyright (c) Isaac Z. Schlueter and Contributors
|
||||||
|
>
|
||||||
|
> Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
> purpose with or without fee is hereby granted, provided that the above
|
||||||
|
> copyright notice and this permission notice appear in all copies.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||||
|
> IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## mri
|
||||||
|
License: MIT
|
||||||
|
By: Luke Edwards
|
||||||
|
Repository: https://github.com/lukeed/mri
|
||||||
|
|
||||||
|
> The MIT License (MIT)
|
||||||
|
>
|
||||||
|
> Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
> in the Software without restriction, including without limitation the rights
|
||||||
|
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
> copies of the Software, and to permit persons to whom the Software is
|
||||||
|
> furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in
|
||||||
|
> all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
> THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## path-key, shebang-regex
|
||||||
|
License: MIT
|
||||||
|
By: Sindre Sorhus
|
||||||
|
Repositories: https://github.com/sindresorhus/path-key, https://github.com/sindresorhus/shebang-regex
|
||||||
|
|
||||||
|
> MIT License
|
||||||
|
>
|
||||||
|
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## shebang-command
|
||||||
|
License: MIT
|
||||||
|
By: Kevin Mårtensson
|
||||||
|
Repository: https://github.com/kevva/shebang-command
|
||||||
|
|
||||||
|
> MIT License
|
||||||
|
>
|
||||||
|
> Copyright (c) Kevin Mårtensson <kevinmartensson@gmail.com> (github.com/kevva)
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## sisteransi
|
||||||
|
License: MIT
|
||||||
|
By: Terkel Gjervig
|
||||||
|
Repository: https://github.com/terkelg/sisteransi
|
||||||
|
|
||||||
|
> MIT License
|
||||||
|
>
|
||||||
|
> Copyright (c) 2018 Terkel Gjervig Nielsen
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
> in the Software without restriction, including without limitation the rights
|
||||||
|
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
> copies of the Software, and to permit persons to whom the Software is
|
||||||
|
> furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all
|
||||||
|
> copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
> SOFTWARE.
|
||||||
92
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/README.md
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# create-vite <a href="https://npmjs.com/package/create-vite"><img src="https://img.shields.io/npm/v/create-vite" alt="npm package"></a>
|
||||||
|
|
||||||
|
## Scaffolding Your First Vite Project
|
||||||
|
|
||||||
|
> **Compatibility Note:**
|
||||||
|
> Vite requires [Node.js](https://nodejs.org/en/) version 20.19+, 22.12+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it.
|
||||||
|
|
||||||
|
With NPM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create vite@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
With Yarn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn create vite
|
||||||
|
```
|
||||||
|
|
||||||
|
With PNPM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm create vite
|
||||||
|
```
|
||||||
|
|
||||||
|
With Bun:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun create vite
|
||||||
|
```
|
||||||
|
|
||||||
|
With Deno:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
deno init --npm vite
|
||||||
|
```
|
||||||
|
|
||||||
|
Then follow the prompts!
|
||||||
|
|
||||||
|
You can also directly specify the project name and the template you want to use via additional command line options. For example, to scaffold a Vite + Vue project, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm 7+, extra double-dash is needed:
|
||||||
|
npm create vite@latest my-vue-app -- --template vue
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn create vite my-vue-app --template vue
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm create vite my-vue-app --template vue
|
||||||
|
|
||||||
|
# Bun
|
||||||
|
bun create vite my-vue-app --template vue
|
||||||
|
|
||||||
|
# Deno
|
||||||
|
deno init --npm vite my-vue-app --template vue
|
||||||
|
```
|
||||||
|
|
||||||
|
Currently supported template presets include:
|
||||||
|
|
||||||
|
- `vanilla`
|
||||||
|
- `vanilla-ts`
|
||||||
|
- `vue`
|
||||||
|
- `vue-ts`
|
||||||
|
- `react`
|
||||||
|
- `react-compiler`
|
||||||
|
- `react-ts`
|
||||||
|
- `react-compiler-ts`
|
||||||
|
- `preact`
|
||||||
|
- `preact-ts`
|
||||||
|
- `lit`
|
||||||
|
- `lit-ts`
|
||||||
|
- `svelte`
|
||||||
|
- `svelte-ts`
|
||||||
|
- `solid`
|
||||||
|
- `solid-ts`
|
||||||
|
- `qwik`
|
||||||
|
- `qwik-ts`
|
||||||
|
|
||||||
|
You can use `.` for the project name to scaffold in the current directory.
|
||||||
|
|
||||||
|
## Community Templates
|
||||||
|
|
||||||
|
create-vite is a tool to quickly start a project from a basic template for popular frameworks. Check out Awesome Vite for [community maintained templates](https://github.com/vitejs/awesome-vite#templates) that include other tools or target different frameworks. You can use a tool like [tiged](https://github.com/tiged/tiged) to scaffold your project with one of the templates.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tiged user/project my-project
|
||||||
|
cd my-project
|
||||||
|
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
89
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/dist/index.js
generated
vendored
Normal file
3
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import './dist/index.js'
|
||||||
43
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/package.json
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "create-vite",
|
||||||
|
"version": "9.0.7",
|
||||||
|
"type": "module",
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Evan You",
|
||||||
|
"bin": {
|
||||||
|
"create-vite": "index.js",
|
||||||
|
"cva": "index.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"template-*",
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/vitejs/vite.git",
|
||||||
|
"directory": "packages/create-vite"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/vitejs/vite/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/create-vite#readme",
|
||||||
|
"funding": "https://github.com/vitejs/vite?sponsor=1",
|
||||||
|
"devDependencies": {
|
||||||
|
"@clack/prompts": "^1.3.0",
|
||||||
|
"@vercel/detect-agent": "^1.2.3",
|
||||||
|
"cross-spawn": "^7.0.6",
|
||||||
|
"mri": "^1.2.0",
|
||||||
|
"tsdown": "^0.22.0",
|
||||||
|
"unrun": "^0.3.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsdown --watch",
|
||||||
|
"build": "tsdown",
|
||||||
|
"typecheck": "tsc",
|
||||||
|
"execute": "node index.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/_gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/index.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Lit + TS</title>
|
||||||
|
<link rel="stylesheet" href="./src/index.css" />
|
||||||
|
<script type="module" src="/src/my-element.ts"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<my-element>
|
||||||
|
<h1>Get started</h1>
|
||||||
|
</my-element>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/package.json
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "vite-lit-ts-starter",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lit": "^3.3.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "~6.0.2",
|
||||||
|
"vite": "^8.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/public/favicon.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/public/icons.svg
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
||||||
|
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
||||||
|
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="discord-icon" viewBox="0 0 20 19">
|
||||||
|
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="github-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="social-icon" viewBox="0 0 20 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="x-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
BIN
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/src/assets/hero.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/src/assets/lit.svg
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="25.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 320"><path fill="#00E8FF" d="m64 192l25.926-44.727l38.233-19.114l63.974 63.974l10.833 61.754L192 320l-64-64l-38.074-25.615z"></path><path fill="#283198" d="M128 256V128l64-64v128l-64 64ZM0 256l64 64l9.202-60.602L64 192l-37.542 23.71L0 256Z"></path><path fill="#324FFF" d="M64 192V64l64-64v128l-64 64Zm128 128V192l64-64v128l-64 64ZM0 256V128l64 64l-64 64Z"></path><path fill="#0FF" d="M64 320V192l64 64z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 639 B |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/src/assets/vite.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/src/index.css
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
background-color: #16171d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100svh;
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
438
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/src/my-element.ts
generated
vendored
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
import { LitElement, css, html } from 'lit'
|
||||||
|
import { customElement, property } from 'lit/decorators.js'
|
||||||
|
import litLogo from './assets/lit.svg'
|
||||||
|
import viteLogo from './assets/vite.svg'
|
||||||
|
import heroImg from './assets/hero.png'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An example element.
|
||||||
|
*
|
||||||
|
* @slot - This element has a slot
|
||||||
|
* @csspart button - The button
|
||||||
|
*/
|
||||||
|
@customElement('my-element')
|
||||||
|
export class MyElement extends LitElement {
|
||||||
|
/**
|
||||||
|
* The number of times the button has been clicked.
|
||||||
|
*/
|
||||||
|
@property({ type: Number })
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<section id="center">
|
||||||
|
<div class="hero">
|
||||||
|
<img src=${heroImg} class="base" width="170" height="179" alt="" />
|
||||||
|
<img src=${litLogo} class="framework" alt="Lit logo" />
|
||||||
|
<img src=${viteLogo} class="vite" alt="Vite logo" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/my-element.ts</code> and save to test
|
||||||
|
<code>HMR</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="counter"
|
||||||
|
@click=${this._onClick}
|
||||||
|
part="button"
|
||||||
|
>
|
||||||
|
Count is ${this.count}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
|
||||||
|
<section id="next-steps">
|
||||||
|
<div id="docs">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#documentation-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Documentation</h2>
|
||||||
|
<p>Your questions, answered</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vite.dev/" target="_blank">
|
||||||
|
<img class="logo" src=${viteLogo} alt="" />
|
||||||
|
Explore Vite
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://lit.dev/" target="_blank">
|
||||||
|
<img class="button-icon" src=${litLogo} alt="" />
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="social">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#social-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Connect with us</h2>
|
||||||
|
<p>Join the Vite community</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/vitejs/vite" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#github-icon"></use>
|
||||||
|
</svg>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vite.dev/" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#discord-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://x.com/vite_js" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#x-icon"></use>
|
||||||
|
</svg>
|
||||||
|
X.com
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://bsky.app/profile/vite.dev" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#bluesky-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Bluesky
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
<section id="spacer"></section>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onClick() {
|
||||||
|
this.count++
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
:host {
|
||||||
|
--text: #6b6375;
|
||||||
|
--text-h: #08060d;
|
||||||
|
--bg: #fff;
|
||||||
|
--border: #e5e4e7;
|
||||||
|
--code-bg: #f4f3ec;
|
||||||
|
--accent: #aa3bff;
|
||||||
|
--accent-bg: rgba(170, 59, 255, 0.1);
|
||||||
|
--accent-border: rgba(170, 59, 255, 0.5);
|
||||||
|
--social-bg: rgba(244, 243, 236, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
|
||||||
|
|
||||||
|
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--mono: ui-monospace, Consolas, monospace;
|
||||||
|
|
||||||
|
font: 18px/145% var(--sans);
|
||||||
|
letter-spacing: 0.18px;
|
||||||
|
|
||||||
|
width: 1126px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border-inline: 1px solid var(--border);
|
||||||
|
min-height: 100svh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:host {
|
||||||
|
--text: #9ca3af;
|
||||||
|
--text-h: #f3f4f6;
|
||||||
|
--bg: #16171d;
|
||||||
|
--border: #2e303a;
|
||||||
|
--code-bg: #1f2028;
|
||||||
|
--accent: #c084fc;
|
||||||
|
--accent-bg: rgba(192, 132, 252, 0.15);
|
||||||
|
--accent-border: rgba(192, 132, 252, 0.5);
|
||||||
|
--social-bg: rgba(47, 48, 58, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.4) 0 10px 15px -3px,
|
||||||
|
rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#social .button-icon {
|
||||||
|
filter: invert(1) brightness(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
::slotted(h1),
|
||||||
|
::slotted(h2) {
|
||||||
|
font-family: var(--heading);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
::slotted(h1) {
|
||||||
|
font-size: 56px;
|
||||||
|
letter-spacing: -1.68px;
|
||||||
|
margin: 32px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 118%;
|
||||||
|
letter-spacing: -0.24px;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 135%;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--text-h);
|
||||||
|
background: var(--code-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 16px;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-bg);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter:hover {
|
||||||
|
border-color: var(--accent-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter:focus-visible {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .base,
|
||||||
|
.hero .framework,
|
||||||
|
.hero .vite {
|
||||||
|
inset-inline: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .base {
|
||||||
|
width: 170px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .framework,
|
||||||
|
.hero .vite {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .framework {
|
||||||
|
z-index: 1;
|
||||||
|
top: 34px;
|
||||||
|
height: 28px;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg)
|
||||||
|
rotateY(39deg) scale(1.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .vite {
|
||||||
|
z-index: 0;
|
||||||
|
top: 107px;
|
||||||
|
height: 26px;
|
||||||
|
width: auto;
|
||||||
|
color: var(--vite-logo);
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg)
|
||||||
|
rotateY(39deg) scale(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 25px;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps > div {
|
||||||
|
flex: 1 1 0;
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps .icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 32px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .logo {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .logo svg {
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a {
|
||||||
|
color: var(--text-h);
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--social-bg);
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a:hover {
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .button-icon {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 88px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::before,
|
||||||
|
.ticks::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -4.5px;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::before {
|
||||||
|
left: 0;
|
||||||
|
border-left-color: var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::after {
|
||||||
|
right: 0;
|
||||||
|
border-right-color: var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
:host {
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
::slotted(h1) {
|
||||||
|
font-size: 36px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2,
|
||||||
|
::slotted(h2) {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
padding: 32px 20px 24px;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps > div {
|
||||||
|
padding: 24px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
margin-top: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul li {
|
||||||
|
flex: 1 1 calc(50% - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'my-element': MyElement
|
||||||
|
}
|
||||||
|
}
|
||||||
25
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit-ts/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2023",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"module": "esnext",
|
||||||
|
"lib": ["ES2023", "DOM"],
|
||||||
|
"types": ["vite/client"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/_gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
16
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/index.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Lit</title>
|
||||||
|
<link rel="stylesheet" href="./src/index.css" />
|
||||||
|
<script type="module" src="/src/my-element.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<my-element>
|
||||||
|
<h1>Get started</h1>
|
||||||
|
</my-element>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
17
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/package.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "vite-lit-starter",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lit": "^3.3.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vite": "^8.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/public/favicon.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/public/icons.svg
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
||||||
|
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
||||||
|
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="discord-icon" viewBox="0 0 20 19">
|
||||||
|
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="github-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="social-icon" viewBox="0 0 20 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="x-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
BIN
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/src/assets/hero.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/src/assets/lit.svg
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="25.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 320"><path fill="#00E8FF" d="m64 192l25.926-44.727l38.233-19.114l63.974 63.974l10.833 61.754L192 320l-64-64l-38.074-25.615z"></path><path fill="#283198" d="M128 256V128l64-64v128l-64 64ZM0 256l64 64l9.202-60.602L64 192l-37.542 23.71L0 256Z"></path><path fill="#324FFF" d="M64 192V64l64-64v128l-64 64Zm128 128V192l64-64v128l-64 64ZM0 256V128l64 64l-64 64Z"></path><path fill="#0FF" d="M64 320V192l64 64z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 639 B |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/src/assets/vite.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/src/index.css
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
background-color: #16171d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100svh;
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
442
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-lit/src/my-element.js
generated
vendored
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
import { LitElement, css, html } from 'lit'
|
||||||
|
import litLogo from './assets/lit.svg'
|
||||||
|
import viteLogo from './assets/vite.svg'
|
||||||
|
import heroImg from './assets/hero.png'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An example element.
|
||||||
|
*
|
||||||
|
* @slot - This element has a slot
|
||||||
|
* @csspart button - The button
|
||||||
|
*/
|
||||||
|
export class MyElement extends LitElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* The number of times the button has been clicked.
|
||||||
|
*/
|
||||||
|
count: { type: Number },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<section id="center">
|
||||||
|
<div class="hero">
|
||||||
|
<img src=${heroImg} class="base" width="170" height="179" alt="" />
|
||||||
|
<img src=${litLogo} class="framework" alt="Lit logo" />
|
||||||
|
<img src=${viteLogo} class="vite" alt="Vite logo" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/my-element.js</code> and save to test
|
||||||
|
<code>HMR</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="counter"
|
||||||
|
@click=${this._onClick}
|
||||||
|
part="button"
|
||||||
|
>
|
||||||
|
Count is ${this.count}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
|
||||||
|
<section id="next-steps">
|
||||||
|
<div id="docs">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#documentation-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Documentation</h2>
|
||||||
|
<p>Your questions, answered</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vite.dev/" target="_blank">
|
||||||
|
<img class="logo" src=${viteLogo} alt="" />
|
||||||
|
Explore Vite
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://lit.dev/" target="_blank">
|
||||||
|
<img class="button-icon" src=${litLogo} alt="" />
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="social">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#social-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Connect with us</h2>
|
||||||
|
<p>Join the Vite community</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/vitejs/vite" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#github-icon"></use>
|
||||||
|
</svg>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vite.dev/" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#discord-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://x.com/vite_js" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#x-icon"></use>
|
||||||
|
</svg>
|
||||||
|
X.com
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://bsky.app/profile/vite.dev" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#bluesky-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Bluesky
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
<section id="spacer"></section>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
_onClick() {
|
||||||
|
this.count++
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
--text: #6b6375;
|
||||||
|
--text-h: #08060d;
|
||||||
|
--bg: #fff;
|
||||||
|
--border: #e5e4e7;
|
||||||
|
--code-bg: #f4f3ec;
|
||||||
|
--accent: #aa3bff;
|
||||||
|
--accent-bg: rgba(170, 59, 255, 0.1);
|
||||||
|
--accent-border: rgba(170, 59, 255, 0.5);
|
||||||
|
--social-bg: rgba(244, 243, 236, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.1) 0 10px 15px -3px,
|
||||||
|
rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
|
||||||
|
|
||||||
|
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--mono: ui-monospace, Consolas, monospace;
|
||||||
|
|
||||||
|
font: 18px/145% var(--sans);
|
||||||
|
letter-spacing: 0.18px;
|
||||||
|
|
||||||
|
width: 1126px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border-inline: 1px solid var(--border);
|
||||||
|
min-height: 100svh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:host {
|
||||||
|
--text: #9ca3af;
|
||||||
|
--text-h: #f3f4f6;
|
||||||
|
--bg: #16171d;
|
||||||
|
--border: #2e303a;
|
||||||
|
--code-bg: #1f2028;
|
||||||
|
--accent: #c084fc;
|
||||||
|
--accent-bg: rgba(192, 132, 252, 0.15);
|
||||||
|
--accent-border: rgba(192, 132, 252, 0.5);
|
||||||
|
--social-bg: rgba(47, 48, 58, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.4) 0 10px 15px -3px,
|
||||||
|
rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#social .button-icon {
|
||||||
|
filter: invert(1) brightness(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
::slotted(h1),
|
||||||
|
::slotted(h2) {
|
||||||
|
font-family: var(--heading);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
::slotted(h1) {
|
||||||
|
font-size: 56px;
|
||||||
|
letter-spacing: -1.68px;
|
||||||
|
margin: 32px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 118%;
|
||||||
|
letter-spacing: -0.24px;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 135%;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--text-h);
|
||||||
|
background: var(--code-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 16px;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-bg);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter:hover {
|
||||||
|
border-color: var(--accent-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter:focus-visible {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .base,
|
||||||
|
.hero .framework,
|
||||||
|
.hero .vite {
|
||||||
|
inset-inline: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .base {
|
||||||
|
width: 170px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .framework,
|
||||||
|
.hero .vite {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .framework {
|
||||||
|
z-index: 1;
|
||||||
|
top: 34px;
|
||||||
|
height: 28px;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg)
|
||||||
|
rotateY(39deg) scale(1.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .vite {
|
||||||
|
z-index: 0;
|
||||||
|
top: 107px;
|
||||||
|
height: 26px;
|
||||||
|
width: auto;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg)
|
||||||
|
rotateY(39deg) scale(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 25px;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps > div {
|
||||||
|
flex: 1 1 0;
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps .icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 32px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .logo {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .logo svg {
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a {
|
||||||
|
color: var(--text-h);
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--social-bg);
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a:hover {
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul .button-icon {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 88px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::before,
|
||||||
|
.ticks::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -4.5px;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::before {
|
||||||
|
left: 0;
|
||||||
|
border-left-color: var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks::after {
|
||||||
|
right: 0;
|
||||||
|
border-right-color: var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
:host {
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
::slotted(h1) {
|
||||||
|
font-size: 36px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2,
|
||||||
|
::slotted(h2) {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
padding: 32px 20px 24px;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps > div {
|
||||||
|
padding: 24px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
margin-top: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul li {
|
||||||
|
flex: 1 1 calc(50% - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul a {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('my-element', MyElement)
|
||||||
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/_gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
13
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/index.html
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Preact + TS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/package.json
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "vite-preact-ts-starter",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"preact": "^10.29.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@preact/preset-vite": "^2.10.5",
|
||||||
|
"@types/node": "^24.12.3",
|
||||||
|
"typescript": "~6.0.2",
|
||||||
|
"vite": "^8.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/public/favicon.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/public/icons.svg
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
||||||
|
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
||||||
|
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="discord-icon" viewBox="0 0 20 19">
|
||||||
|
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="github-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="social-icon" viewBox="0 0 20 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="x-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
196
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/app.css
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
.counter {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-bg);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--accent-border);
|
||||||
|
}
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.base,
|
||||||
|
.framework,
|
||||||
|
.vite {
|
||||||
|
inset-inline: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.base {
|
||||||
|
width: 170px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework,
|
||||||
|
.vite {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework {
|
||||||
|
z-index: 1;
|
||||||
|
top: 34px;
|
||||||
|
height: 28px;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
|
||||||
|
scale(1.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vite {
|
||||||
|
z-index: 0;
|
||||||
|
top: 107px;
|
||||||
|
height: 26px;
|
||||||
|
width: auto;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
|
||||||
|
scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
width: 1126px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border-inline: 1px solid var(--border);
|
||||||
|
min-height: 100svh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 25px;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
padding: 32px 20px 24px;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 1 1 0;
|
||||||
|
padding: 32px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
padding: 24px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 32px 0 0;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-h);
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--social-bg);
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
.button-icon {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
margin-top: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
li {
|
||||||
|
flex: 1 1 calc(50% - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 88px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -4.5px;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
left: 0;
|
||||||
|
border-left-color: var(--border);
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
right: 0;
|
||||||
|
border-right-color: var(--border);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/app.tsx
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import { useState } from 'preact/hooks'
|
||||||
|
import preactLogo from './assets/preact.svg'
|
||||||
|
import viteLogo from './assets/vite.svg'
|
||||||
|
import heroImg from './assets/hero.png'
|
||||||
|
import './app.css'
|
||||||
|
|
||||||
|
export function App() {
|
||||||
|
const [count, setCount] = useState(0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section id="center">
|
||||||
|
<div class="hero">
|
||||||
|
<img src={heroImg} class="base" width="170" height="179" alt="" />
|
||||||
|
<img src={preactLogo} class="framework" alt="Preact logo" />
|
||||||
|
<img src={viteLogo} class="vite" alt="Vite logo" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>Get started</h1>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/app.tsx</code> and save to test <code>HMR</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="counter"
|
||||||
|
onClick={() => setCount((count) => count + 1)}
|
||||||
|
>
|
||||||
|
Count is {count}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
|
||||||
|
<section id="next-steps">
|
||||||
|
<div id="docs">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#documentation-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Documentation</h2>
|
||||||
|
<p>Your questions, answered</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vite.dev/" target="_blank">
|
||||||
|
<img class="logo" src={viteLogo} alt="" />
|
||||||
|
Explore Vite
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://preactjs.com/" target="_blank">
|
||||||
|
<img class="button-icon" src={preactLogo} alt="" />
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="social">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#social-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Connect with us</h2>
|
||||||
|
<p>Join the Vite community</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/vitejs/vite" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#github-icon"></use>
|
||||||
|
</svg>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vite.dev/" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#discord-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://x.com/vite_js" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#x-icon"></use>
|
||||||
|
</svg>
|
||||||
|
X.com
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://bsky.app/profile/vite.dev" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#bluesky-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Bluesky
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
<section id="spacer"></section>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
BIN
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/assets/hero.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/assets/preact.svg
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="27.68" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 296"><path fill="#673AB8" d="m128 0l128 73.9v147.8l-128 73.9L0 221.7V73.9z"></path><path fill="#FFF" d="M34.865 220.478c17.016 21.78 71.095 5.185 122.15-34.704c51.055-39.888 80.24-88.345 63.224-110.126c-17.017-21.78-71.095-5.184-122.15 34.704c-51.055 39.89-80.24 88.346-63.224 110.126Zm7.27-5.68c-5.644-7.222-3.178-21.402 7.573-39.253c11.322-18.797 30.541-39.548 54.06-57.923c23.52-18.375 48.303-32.004 69.281-38.442c19.922-6.113 34.277-5.075 39.92 2.148c5.644 7.223 3.178 21.403-7.573 39.254c-11.322 18.797-30.541 39.547-54.06 57.923c-23.52 18.375-48.304 32.004-69.281 38.441c-19.922 6.114-34.277 5.076-39.92-2.147Z"></path><path fill="#FFF" d="M220.239 220.478c17.017-21.78-12.169-70.237-63.224-110.126C105.96 70.464 51.88 53.868 34.865 75.648c-17.017 21.78 12.169 70.238 63.224 110.126c51.055 39.889 105.133 56.485 122.15 34.704Zm-7.27-5.68c-5.643 7.224-19.998 8.262-39.92 2.148c-20.978-6.437-45.761-20.066-69.28-38.441c-23.52-18.376-42.74-39.126-54.06-57.923c-10.752-17.851-13.218-32.03-7.575-39.254c5.644-7.223 19.999-8.261 39.92-2.148c20.978 6.438 45.762 20.067 69.281 38.442c23.52 18.375 42.739 39.126 54.06 57.923c10.752 17.85 13.218 32.03 7.574 39.254Z"></path><path fill="#FFF" d="M127.552 167.667c10.827 0 19.603-8.777 19.603-19.604c0-10.826-8.776-19.603-19.603-19.603c-10.827 0-19.604 8.777-19.604 19.603c0 10.827 8.777 19.604 19.604 19.604Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/assets/vite.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
111
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/index.css
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
:root {
|
||||||
|
--text: #6b6375;
|
||||||
|
--text-h: #08060d;
|
||||||
|
--bg: #fff;
|
||||||
|
--border: #e5e4e7;
|
||||||
|
--code-bg: #f4f3ec;
|
||||||
|
--accent: #aa3bff;
|
||||||
|
--accent-bg: rgba(170, 59, 255, 0.1);
|
||||||
|
--accent-border: rgba(170, 59, 255, 0.5);
|
||||||
|
--social-bg: rgba(244, 243, 236, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
|
||||||
|
|
||||||
|
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--mono: ui-monospace, Consolas, monospace;
|
||||||
|
|
||||||
|
font: 18px/145% var(--sans);
|
||||||
|
letter-spacing: 0.18px;
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: var(--text);
|
||||||
|
background: var(--bg);
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--text: #9ca3af;
|
||||||
|
--text-h: #f3f4f6;
|
||||||
|
--bg: #16171d;
|
||||||
|
--border: #2e303a;
|
||||||
|
--code-bg: #1f2028;
|
||||||
|
--accent: #c084fc;
|
||||||
|
--accent-bg: rgba(192, 132, 252, 0.15);
|
||||||
|
--accent-border: rgba(192, 132, 252, 0.5);
|
||||||
|
--social-bg: rgba(47, 48, 58, 0.5);
|
||||||
|
--shadow:
|
||||||
|
rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#social .button-icon {
|
||||||
|
filter: invert(1) brightness(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
width: 1126px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border-inline: 1px solid var(--border);
|
||||||
|
min-height: 100svh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2 {
|
||||||
|
font-family: var(--heading);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 56px;
|
||||||
|
letter-spacing: -1.68px;
|
||||||
|
margin: 32px 0;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 36px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 118%;
|
||||||
|
letter-spacing: -0.24px;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,
|
||||||
|
.counter {
|
||||||
|
font-family: var(--mono);
|
||||||
|
display: inline-flex;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--text-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 135%;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background: var(--code-bg);
|
||||||
|
}
|
||||||
5
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/src/main.tsx
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { render } from 'preact'
|
||||||
|
import './index.css'
|
||||||
|
import { App } from './app.tsx'
|
||||||
|
|
||||||
|
render(<App />, document.getElementById('app')!)
|
||||||
30
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/tsconfig.app.json
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "es2023",
|
||||||
|
"module": "esnext",
|
||||||
|
"lib": ["ES2023", "DOM"],
|
||||||
|
"types": ["vite/client"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"paths": {
|
||||||
|
"react": ["./node_modules/preact/compat/"],
|
||||||
|
"react-dom": ["./node_modules/preact/compat/"]
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "preact",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
7
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/tsconfig.node.json
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "es2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "esnext",
|
||||||
|
"types": ["node"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
7
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact-ts/vite.config.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import preact from '@preact/preset-vite'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [preact()],
|
||||||
|
})
|
||||||
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/_gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
13
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/index.html
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Preact</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/package.json
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "vite-preact-starter",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"preact": "^10.29.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@preact/preset-vite": "^2.10.5",
|
||||||
|
"vite": "^8.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/public/favicon.svg
generated
vendored
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
24
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/public/icons.svg
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
||||||
|
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
||||||
|
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="discord-icon" viewBox="0 0 20 19">
|
||||||
|
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="github-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="social-icon" viewBox="0 0 20 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="x-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
196
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/src/app.css
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
.counter {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-bg);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--accent-border);
|
||||||
|
}
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.base,
|
||||||
|
.framework,
|
||||||
|
.vite {
|
||||||
|
inset-inline: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.base {
|
||||||
|
width: 170px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework,
|
||||||
|
.vite {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework {
|
||||||
|
z-index: 1;
|
||||||
|
top: 34px;
|
||||||
|
height: 28px;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
|
||||||
|
scale(1.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vite {
|
||||||
|
z-index: 0;
|
||||||
|
top: 107px;
|
||||||
|
height: 26px;
|
||||||
|
width: auto;
|
||||||
|
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
|
||||||
|
scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
width: 1126px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border-inline: 1px solid var(--border);
|
||||||
|
min-height: 100svh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 25px;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
padding: 32px 20px 24px;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 1 1 0;
|
||||||
|
padding: 32px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
padding: 24px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#docs {
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#next-steps ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 32px 0 0;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-h);
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--social-bg);
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
.button-icon {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
margin-top: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
li {
|
||||||
|
flex: 1 1 calc(50% - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacer {
|
||||||
|
height: 88px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticks {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -4.5px;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
left: 0;
|
||||||
|
border-left-color: var(--border);
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
right: 0;
|
||||||
|
border-right-color: var(--border);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/src/app.jsx
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import { useState } from 'preact/hooks'
|
||||||
|
import preactLogo from './assets/preact.svg'
|
||||||
|
import viteLogo from './assets/vite.svg'
|
||||||
|
import heroImg from './assets/hero.png'
|
||||||
|
import './app.css'
|
||||||
|
|
||||||
|
export function App() {
|
||||||
|
const [count, setCount] = useState(0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section id="center">
|
||||||
|
<div class="hero">
|
||||||
|
<img src={heroImg} class="base" width="170" height="179" alt="" />
|
||||||
|
<img src={preactLogo} class="framework" alt="Preact logo" />
|
||||||
|
<img src={viteLogo} class="vite" alt="Vite logo" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>Get started</h1>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/app.jsx</code> and save to test <code>HMR</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="counter"
|
||||||
|
onClick={() => setCount((count) => count + 1)}
|
||||||
|
>
|
||||||
|
Count is {count}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
|
||||||
|
<section id="next-steps">
|
||||||
|
<div id="docs">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#documentation-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Documentation</h2>
|
||||||
|
<p>Your questions, answered</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vite.dev/" target="_blank">
|
||||||
|
<img class="logo" src={viteLogo} alt="" />
|
||||||
|
Explore Vite
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://preactjs.com/" target="_blank">
|
||||||
|
<img class="button-icon" src={preactLogo} alt="" />
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="social">
|
||||||
|
<svg class="icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#social-icon"></use>
|
||||||
|
</svg>
|
||||||
|
<h2>Connect with us</h2>
|
||||||
|
<p>Join the Vite community</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/vitejs/vite" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#github-icon"></use>
|
||||||
|
</svg>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vite.dev/" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#discord-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://x.com/vite_js" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#x-icon"></use>
|
||||||
|
</svg>
|
||||||
|
X.com
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://bsky.app/profile/vite.dev" target="_blank">
|
||||||
|
<svg class="button-icon" role="presentation" aria-hidden="true">
|
||||||
|
<use href="/icons.svg#bluesky-icon"></use>
|
||||||
|
</svg>
|
||||||
|
Bluesky
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="ticks"></div>
|
||||||
|
<section id="spacer"></section>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
BIN
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/src/assets/hero.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
1
TicTacToe-Compare/ministral-3-14b/node_modules/create-vite/template-preact/src/assets/preact.svg
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="27.68" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 296"><path fill="#673AB8" d="m128 0l128 73.9v147.8l-128 73.9L0 221.7V73.9z"></path><path fill="#FFF" d="M34.865 220.478c17.016 21.78 71.095 5.185 122.15-34.704c51.055-39.888 80.24-88.345 63.224-110.126c-17.017-21.78-71.095-5.184-122.15 34.704c-51.055 39.89-80.24 88.346-63.224 110.126Zm7.27-5.68c-5.644-7.222-3.178-21.402 7.573-39.253c11.322-18.797 30.541-39.548 54.06-57.923c23.52-18.375 48.303-32.004 69.281-38.442c19.922-6.113 34.277-5.075 39.92 2.148c5.644 7.223 3.178 21.403-7.573 39.254c-11.322 18.797-30.541 39.547-54.06 57.923c-23.52 18.375-48.304 32.004-69.281 38.441c-19.922 6.114-34.277 5.076-39.92-2.147Z"></path><path fill="#FFF" d="M220.239 220.478c17.017-21.78-12.169-70.237-63.224-110.126C105.96 70.464 51.88 53.868 34.865 75.648c-17.017 21.78 12.169 70.238 63.224 110.126c51.055 39.889 105.133 56.485 122.15 34.704Zm-7.27-5.68c-5.643 7.224-19.998 8.262-39.92 2.148c-20.978-6.437-45.761-20.066-69.28-38.441c-23.52-18.376-42.74-39.126-54.06-57.923c-10.752-17.851-13.218-32.03-7.575-39.254c5.644-7.223 19.999-8.261 39.92-2.148c20.978 6.438 45.762 20.067 69.281 38.442c23.52 18.375 42.739 39.126 54.06 57.923c10.752 17.85 13.218 32.03 7.574 39.254Z"></path><path fill="#FFF" d="M127.552 167.667c10.827 0 19.603-8.777 19.603-19.604c0-10.826-8.776-19.603-19.603-19.603c-10.827 0-19.604 8.777-19.604 19.603c0 10.827 8.777 19.604 19.604 19.604Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |