diff --git a/docs/reference/dsl_how_to_guides.md b/docs/reference/dsl_how_to_guides.md index 66137c1ff..0d0370a23 100644 --- a/docs/reference/dsl_how_to_guides.md +++ b/docs/reference/dsl_how_to_guides.md @@ -630,7 +630,7 @@ For more comprehensive examples have a look at the [DSL examples](https://github ### Document [doc_type] -If you want to create a model-like wrapper around your documents, use the `Document` class. It can also be used to create all the necessary mappings and settings in elasticsearch (see `life-cycle` for details). +If you want to create a model-like wrapper around your documents, use the `Document` class (or the equivalent `AsyncDocument` for asynchronous applications). It can also be used to create all the necessary mappings and settings in Elasticsearch (see [Document life cycle](#life-cycle) below for details). ```python from datetime import datetime @@ -721,9 +721,19 @@ class Post(Document): published: bool # same as published = Boolean(required=True) ``` -It is important to note that when using `Field` subclasses such as `Text`, `Date` and `Boolean`, they must be given in the right-side of an assignment, as shown in examples above. Using these classes as type hints will result in errors. +::::{note} +When using `Field` subclasses such as `Text`, `Date` and `Boolean` to define attributes, these classes must be given in the right-hand side. + +```python +class Post(Document): + title = Text() # correct + subtitle: Text # incorrect +``` -Python types are mapped to their corresponding field types according to the following table: +Using a `Field` subclass as a Python type hint will result in errors. +:::: + +Python types are mapped to their corresponding `Field` types according to the following table: | Python type | DSL field | | --- | --- | @@ -735,7 +745,7 @@ Python types are mapped to their corresponding field types according to the foll | `datetime` | `Date(required=True)` | | `date` | `Date(format="yyyy-MM-dd", required=True)` | -To type a field as optional, the standard `Optional` modifier from the Python `typing` package can be used. When using Python 3.10 or newer, "pipe" syntax can also be used, by adding `| None` to a type. The `List` modifier can be added to a field to convert it to an array, similar to using the `multi=True` argument on the field object. +To type a field as optional, the standard `Optional` modifier from the Python `typing` package can be used. When using Python 3.10 or newer, "pipe" syntax can also be used, by adding `| None` to a type. The `List` modifier can be added to a field to convert it to an array, similar to using the `multi=True` argument on the `Field` object. ```python from typing import Optional, List @@ -763,7 +773,7 @@ class Post(Document): comments: List[Comment] # same as comments = Nested(Comment, required=True) ``` -Unfortunately it is impossible to have Python type hints that uniquely identify every possible Elasticsearch field type. To choose a field type that is different than the one that is assigned according to the table above, the desired field instance can be added explicitly as a right-side assignment in the field declaration. The next example creates a field that is typed as `Optional[str]`, but is mapped to `Keyword` instead of `Text`: +Unfortunately it is impossible to have Python type hints that uniquely identify every possible Elasticsearch `Field` type. To choose a type that is different than the one that is assigned according to the table above, the desired `Field` instance can be added explicitly as a right-side assignment in the field declaration. The next example creates a field that is typed as `Optional[str]`, but is mapped to `Keyword` instead of `Text`: ```python class MyDocument(Document): @@ -787,7 +797,7 @@ class MyDocument(Document): category: str = mapped_field(Keyword(), default="general") ``` -When using the `mapped_field()` wrapper function, an explicit field type instance can be passed as a first positional argument, as the `category` field does in the example above. +The `mapped_field()` wrapper function can optionally be given an explicit field type instance as a first positional argument, as the `category` field does in the example above to be defined as `Keyword` instead of the `Text` default. Static type checkers such as [mypy](https://mypy-lang.org/) and [pyright](https://github.com/microsoft/pyright) can use the type hints and the dataclass-specific options added to the `mapped_field()` function to improve type inference and provide better real-time code completion and suggestions in IDEs. @@ -829,7 +839,7 @@ s = MyDocument.search().sort(-MyDocument.created_at, MyDocument.title) When specifying sorting order, the `+` and `-` unary operators can be used on the class field attributes to indicate ascending and descending order. -Finally, the `ClassVar` annotation can be used to define a regular class attribute that should not be mapped to the Elasticsearch index: +Finally, it is also possible to define class attributes and request that they are ignored when building the Elasticsearch mapping. One way is to type attributes with the `ClassVar` annotation. Alternatively, the `mapped_field()` wrapper function accepts an `exclude` argument that can be set to `True`: ```python from typing import ClassVar @@ -837,9 +847,9 @@ from typing import ClassVar class MyDoc(Document): title: M[str] created_at: M[datetime] = mapped_field(default_factory=datetime.now) my_var: ClassVar[str] # regular class variable, ignored by Elasticsearch + anoter_custom_var: int = mapped_field(exclude=True) # also ignored by Elasticsearch ``` - #### Note on dates [_note_on_dates] The DSL module will always respect the timezone information (or lack thereof) on the `datetime` objects passed in or stored in Elasticsearch. Elasticsearch itself interprets all datetimes with no timezone information as `UTC`. If you wish to reflect this in your python code, you can specify `default_timezone` when instantiating a `Date` field: @@ -878,7 +888,7 @@ first.meta.id = 47 first.save() ``` -All the metadata fields (`id`, `routing`, `index` etc) can be accessed (and set) via a `meta` attribute or directly using the underscored variant: +All the metadata fields (`id`, `routing`, `index`, etc.) can be accessed (and set) via a `meta` attribute or directly using the underscored variant: ```python post = Post(meta={'id': 42}) @@ -961,12 +971,111 @@ first = Post.get(id=42) first.delete() ``` +#### Integration with Pydantic models + +::::{warning} +This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. +:::: + +::::{note} +This feature is available in the Python Elasticsearch client starting with release 9.2.0. +:::: + +Applications that define their data models using [Pydantic](https://docs.pydantic.dev/latest/) can combine these +models with Elasticsearch DSL annotations. To take advantage of this option, Pydantic's `BaseModel` base class +needs to be replaced with `BaseESModel` (or `AsyncBaseESModel` for asynchronous applications), and then the model +can include type annotations for Pydantic and Elasticsearch both, as demonstrated in the following example: + +```python +from typing import Annotated +from pydantic import Field +from elasticsearch import dsl +from elasticsearch.dsl.pydantic import BaseESModel + +class Quote(BaseESModel): + quote: str + author: Annotated[str, dsl.Keyword()] + tags: Annotated[list[str], dsl.Keyword(normalizer="lowercase")] + embedding: Annotated[list[float], dsl.DenseVector()] = Field(init=False, default=[]) + + class Index: + name = "quotes" +``` + +In this example, the `quote` attribute is annotated with a `str` type hint. Both Pydantic and Elasticsearch use this +annotation. + +The `author` and `tags` attributes have a Python type hint and an Elasticsearch annotation, both wrapped with +Python's `typing.Annotated`. When using the `BaseESModel` class, the typing information intended for Elasticsearch needs +to be defined inside `Annotated`. + +The `embedding` attribute includes a base Python type and an Elasticsearch annotation in the same format as the +other fields, but it adds Pydantic's `Field` definition as a right-hand side assignment. + +Finally, any other items that need to be defined for the Elasticsearch document class, such as `class Index` and +`class Meta` entries (discussed later), can be added as well. + +The next example demonstrates how to define `Object` and `Nested` fields: + +```python +from typing import Annotated +from pydantic import BaseModel, Field +from elasticsearch import dsl +from elasticsearch.dsl.pydantic import BaseESModel + +class Phone(BaseModel): + type: Annotated[str, dsl.Keyword()] = Field(default="Home") + number: str + +class Person(BaseESModel): + name: str + main_phone: Phone # same as Object(Phone) + other_phones: list[Phone] # same as Nested(Phone) + + class Index: + name = "people" +``` + +Note that inner classes do not need to be defined with a custom base class; these should be standard Pydantic model +classes. The attributes defined in these classes can include Elasticsearch annotations, as long as they are given +in an `Annotated` type hint. + +All model classes that are created as described in this section function like normal Pydantic models and can be used +anywhere standard Pydantic models are used, but they have some added attributes: + +- `_doc`: a class attribute that is a dynamically generated `Document` class to use with the Elasticsearch index. +- `meta`: an attribute added to all models that includes Elasticsearch document metadata items such as `id`, `score`, etc. +- `to_doc()`: a method that converts the Pydantic model to an Elasticsearch document. +- `from_doc()`: a class method that accepts an Elasticsearch document as an argument and returns an equivalent Pydantic model. + +These are demonstrated in the examples below: + +```python +# create a Pydantic model +quote = Quote( + quote="An unexamined life is not worth living.", + author="Socrates", + tags=["phillosophy"] +) + +# save the model to the Elasticsearch index +quote.to_doc().save() + +# get a document from the Elasticsearch index as a Pydantic model +quote = Quote.from_doc(Quote._doc.get(id=42)) + +# run a search and print the Pydantic models +s = Quote._doc.search().query(Match(Quote._doc.quote, "life")) +for doc in s: + quote = Quote.from_doc(doc) + print(quote.meta.id, quote.meta.score, quote.quote) +``` #### Analysis [_analysis] To specify `analyzer` values for `Text` fields you can just use the name of the analyzer (as a string) and either rely on the analyzer being defined (like built-in analyzers) or define the analyzer yourself manually. -Alternatively you can create your own analyzer and have the persistence layer handle its creation, from our example earlier: +Alternatively, you can create your own analyzer and have the persistence layer handle its creation, from our example earlier: ```python from elasticsearch.dsl import analyzer, tokenizer @@ -1634,7 +1743,7 @@ for response in responses: ### Asynchronous Documents, Indexes, and more [_asynchronous_documents_indexes_and_more] -The `Document`, `Index`, `IndexTemplate`, `Mapping`, `UpdateByQuery` and `FacetedSearch` classes all have asynchronous versions that use the same name with an `Async` prefix. These classes expose the same interfaces as the synchronous versions, but any methods that perform I/O are defined as coroutines. +The `Document`, `BaseESModel`, `Index`, `IndexTemplate`, `Mapping`, `UpdateByQuery` and `FacetedSearch` classes all have asynchronous versions that use the same name with an `Async` prefix. These classes expose the same interfaces as the synchronous versions, but any methods that perform I/O are defined as coroutines. Auxiliary classes that do not perform I/O do not have asynchronous versions. The same classes can be used in synchronous and asynchronous applications. diff --git a/docs/reference/dsl_tutorials.md b/docs/reference/dsl_tutorials.md index 16224a13f..f53baefbe 100644 --- a/docs/reference/dsl_tutorials.md +++ b/docs/reference/dsl_tutorials.md @@ -134,7 +134,7 @@ In this example you can see: * retrieving and saving the object into Elasticsearch * accessing the underlying client for other APIs -You can see more in the `persistence` chapter. +You can see more in the [persistence](dsl_how_to_guides.md#_persistence_2) chapter. ## Pre-built Faceted Search [_pre_built_faceted_search] diff --git a/elasticsearch/dsl/document_base.py b/elasticsearch/dsl/document_base.py index 72f0364a4..d3f7eee09 100644 --- a/elasticsearch/dsl/document_base.py +++ b/elasticsearch/dsl/document_base.py @@ -34,6 +34,8 @@ overload, ) +from typing_extensions import _AnnotatedAlias + try: import annotationlib except ImportError: @@ -358,6 +360,10 @@ def __init__(self, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]): # the field has a type annotation, so next we try to figure out # what field type we can use type_ = annotations[name] + type_metadata = [] + if isinstance(type_, _AnnotatedAlias): + type_metadata = type_.__metadata__ + type_ = type_.__origin__ skip = False required = True multi = False @@ -404,6 +410,12 @@ def __init__(self, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]): # use best field type for the type hint provided field, field_kwargs = self.type_annotation_map[type_] # type: ignore[assignment] + # if this field does not have a right-hand value, we look in the metadata + # of the annotation to see if we find it there + for md in type_metadata: + if isinstance(md, (_FieldMetadataDict, Field)): + attrs[name] = md + if field: field_kwargs = { "multi": multi, @@ -416,17 +428,20 @@ def __init__(self, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]): # this field has a right-side value, which can be field # instance on its own or wrapped with mapped_field() attr_value = attrs[name] - if isinstance(attr_value, dict): + if isinstance(attr_value, _FieldMetadataDict): # the mapped_field() wrapper function was used so we need # to look for the field instance and also record any # dataclass-style defaults + if attr_value.get("exclude"): + # skip this field + continue attr_value = attrs[name].get("_field") default_value = attrs[name].get("default") or attrs[name].get( "default_factory" ) if default_value: field_defaults[name] = default_value - if attr_value: + if isinstance(attr_value, Field): value = attr_value if required is not None: value._required = required @@ -505,12 +520,19 @@ def __delete__(self, instance: Any) -> None: ... M = Mapped +class _FieldMetadataDict(dict[str, Any]): + """This class is used to identify metadata returned by the `mapped_field()` function.""" + + pass + + def mapped_field( field: Optional[Field] = None, *, init: bool = True, default: Any = None, default_factory: Optional[Callable[[], Any]] = None, + exclude: bool = False, **kwargs: Any, ) -> Any: """Construct a field using dataclass behaviors @@ -520,22 +542,25 @@ def mapped_field( options. :param field: The instance of ``Field`` to use for this field. If not provided, - an instance that is appropriate for the type given to the field is used. + an instance that is appropriate for the type given to the field is used. :param init: a value of ``True`` adds this field to the constructor, and a - value of ``False`` omits it from it. The default is ``True``. + value of ``False`` omits it from it. The default is ``True``. :param default: a default value to use for this field when one is not provided - explicitly. + explicitly. :param default_factory: a callable that returns a default value for the field, - when one isn't provided explicitly. Only one of ``factory`` and - ``default_factory`` can be used. + when one isn't provided explicitly. Only one of ``factory`` and + ``default_factory`` can be used. + :param exclude: Set to ``True`` to exclude this field from the Elasticsearch + index. """ - return { - "_field": field, - "init": init, - "default": default, - "default_factory": default_factory, + return _FieldMetadataDict( + _field=field, + init=init, + default=default, + default_factory=default_factory, + exclude=exclude, **kwargs, - } + ) @dataclass_transform(field_specifiers=(mapped_field,)) diff --git a/elasticsearch/dsl/pydantic.py b/elasticsearch/dsl/pydantic.py new file mode 100644 index 000000000..d1f8efaac --- /dev/null +++ b/elasticsearch/dsl/pydantic.py @@ -0,0 +1,152 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you 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. + +from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type + +from pydantic import BaseModel, Field, PrivateAttr +from typing_extensions import Annotated, Self, dataclass_transform + +from elasticsearch import dsl + + +class ESMeta(BaseModel): + """Metadata items associated with Elasticsearch documents.""" + + id: str = "" + index: str = "" + primary_term: int = 0 + seq_no: int = 0 + version: int = 0 + score: float = 0 + + +class _BaseModel(BaseModel): + meta: Annotated[ESMeta, dsl.mapped_field(exclude=True)] = Field( + default=ESMeta(), + init=False, + ) + + +class _BaseESModelMetaclass(type(BaseModel)): # type: ignore[misc] + """Generic metaclass methods for BaseEsModel and AsyncBaseESModel.""" + + @staticmethod + def process_annotations( + metacls: Type["_BaseESModelMetaclass"], annotations: Dict[str, Any] + ) -> Dict[str, Any]: + """Process Pydantic typing annotations and adapt them so that they can + be used to create the Elasticsearch document. + """ + updated_annotations = {} + for var, ann in annotations.items(): + if isinstance(ann, type(BaseModel)): + # an inner Pydantic model is transformed into an Object field + updated_annotations[var] = metacls.make_dsl_class( + metacls, dsl.InnerDoc, ann + ) + elif ( + hasattr(ann, "__origin__") + and ann.__origin__ in [list, List] + and isinstance(ann.__args__[0], type(BaseModel)) + ): + # an inner list of Pydantic models is transformed into a Nested field + updated_annotations[var] = List[ # type: ignore[assignment,misc] + metacls.make_dsl_class(metacls, dsl.InnerDoc, ann.__args__[0]) + ] + else: + updated_annotations[var] = ann + return updated_annotations + + @staticmethod + def make_dsl_class( + metacls: Type["_BaseESModelMetaclass"], + dsl_class: type, + pydantic_model: type, + pydantic_attrs: Optional[Dict[str, Any]] = None, + ) -> type: + """Create a DSL document class dynamically, using the structure of a + Pydantic model.""" + dsl_attrs = { + attr: value + for attr, value in dsl_class.__dict__.items() + if not attr.startswith("__") + } + pydantic_attrs = { + **(pydantic_attrs or {}), + "__annotations__": metacls.process_annotations( + metacls, pydantic_model.__annotations__ + ), + } + return type(dsl_class)( + f"_ES{pydantic_model.__name__}", + (dsl_class,), + { + **pydantic_attrs, + **dsl_attrs, + "__qualname__": f"_ES{pydantic_model.__name__}", + }, + ) + + +class BaseESModelMetaclass(_BaseESModelMetaclass): + """Metaclass for the BaseESModel class.""" + + def __new__(cls, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]) -> Any: + model = super().__new__(cls, name, bases, attrs) + model._doc = cls.make_dsl_class(cls, dsl.Document, model, attrs) + return model + + +class AsyncBaseESModelMetaclass(_BaseESModelMetaclass): + """Metaclass for the AsyncBaseESModel class.""" + + def __new__(cls, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]) -> Any: + model = super().__new__(cls, name, bases, attrs) + model._doc = cls.make_dsl_class(cls, dsl.AsyncDocument, model, attrs) + return model + + +@dataclass_transform(kw_only_default=True, field_specifiers=(Field, PrivateAttr)) +class BaseESModel(_BaseModel, metaclass=BaseESModelMetaclass): + _doc: ClassVar[Type[dsl.Document]] + + def to_doc(self) -> dsl.Document: + """Convert this model to an Elasticsearch document.""" + data = self.model_dump() + meta = {f"_{k}": v for k, v in data.pop("meta", {}).items() if v} + return self._doc(**meta, **data) + + @classmethod + def from_doc(cls, dsl_obj: dsl.Document) -> Self: + """Create a model from the given Elasticsearch document.""" + return cls(meta=ESMeta(**dsl_obj.meta.to_dict()), **dsl_obj.to_dict()) + + +@dataclass_transform(kw_only_default=True, field_specifiers=(Field, PrivateAttr)) +class AsyncBaseESModel(_BaseModel, metaclass=AsyncBaseESModelMetaclass): + _doc: ClassVar[Type[dsl.AsyncDocument]] + + def to_doc(self) -> dsl.AsyncDocument: + """Convert this model to an Elasticsearch document.""" + data = self.model_dump() + meta = {f"_{k}": v for k, v in data.pop("meta", {}).items() if v} + return self._doc(**meta, **data) + + @classmethod + def from_doc(cls, dsl_obj: dsl.AsyncDocument) -> Self: + """Create a model from the given Elasticsearch document.""" + return cls(meta=ESMeta(**dsl_obj.meta.to_dict()), **dsl_obj.to_dict()) diff --git a/examples/quotes/.gitignore b/examples/quotes/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/examples/quotes/.gitignore @@ -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? diff --git a/examples/quotes/README.md b/examples/quotes/README.md new file mode 100644 index 000000000..135a30b2b --- /dev/null +++ b/examples/quotes/README.md @@ -0,0 +1,107 @@ +# Quotes +Quotes database example, which demonstrates the Elasticsearch integration with +Pydantic models. This example features a React frontend and a FastAPI back end. + +![Quotes app screenshot](screenshot.png) + +## What is this? + +This directory contains a small application that demonstrates how easy it is +to set up a full-text and vector database using [Elasticsearch](https://www.elastic.co/elasticsearch), +while defining the data model with [Pydantic](https://docs.pydantic.dev/latest/). + +The application includes a FastAPI back end and a React front end. It ingests a +dataset of famous quotes into in an Elasticsearch index, and for each quote it +generates an embedding using the +[all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2) +Sentence Transformers model. + +The dataset has about 850 famous quotes, each with their author and tags. The +data is a subset of a +[Kaggle dataset](https://www.kaggle.com/datasets/akmittal/quotes-dataset) that +appears to have been generated from quotes that were scraped from the Goodreads +[popular quotes](https://www.goodreads.com/quotes) page. + +## Requirements + +Please make sure you have the following installed: + +- Python 3.10 or newer +- Node.js 18 or newer + +## How To Run + +Follow these steps to install this demo on your computer: + +### Clone this repository + +Run the following command to install a copy of this project on your computer: + +```bash +git clone https://github.com/elastic/elasticsearch-py +cd examples/quotes +``` + +### Install the Node and Python dependencies + +Run the following command to set up the JavaScript and Python environment and +install all the dependencies: + +```bash +npm install +``` + +### Start a development Elasticsearch container + +You can use [start-local](https://www.elastic.co/docs/deploy-manage/deploy/self-managed/local-development-installation-quickstart) +to start a small Elasticsearch instance. + +Use this command to launch the instance (Docker and Docker Compose are required): + +```bash +curl -fsSL https://elastic.co/start-local | sh +``` + +Once your Elasticsearch instead is deployed, create an environment variable called +`ELASTICSEARCH_URL`, making sure it includes the password generated by start-local. +Example: + +```bash +export ELASTICSEARCH_URL=http://elastic:your-password-here@localhost:9200 +``` + +### Create the quotes database + +Run this command in your terminal: + +```bash +npm run ingest +``` + +Note that the `ELASTICSEARCH_URL` variable must be defined in the terminal +session in which you run this command. + +This task should take a minute or less. The GPU, if available, is used optimize +the generation of the embeddings. + +### Start the back end + +Run this command in your terminal: + +```bash +npm run backend +``` + +Note that the `ELASTICSEARCH_URL` variable must be defined in the terminal +session in which you run this command. + +### Start the front end + +Open a second terminal window and run this command: + +```bash +npm run dev +``` + +You can now navigate to `http://localhost:5173` on your web browser to access +the application. diff --git a/examples/quotes/backend/pyproject.toml b/examples/quotes/backend/pyproject.toml new file mode 100644 index 000000000..a91e2c53c --- /dev/null +++ b/examples/quotes/backend/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "quotes" +version = "0.1" +dependencies = [ + "elasticsearch[async]>=9,<10", + "fastapi", + "orjson", + "sentence-transformers", + "uvicorn", +] + +[project.optional-dependencies] +dev = [ +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" diff --git a/examples/quotes/backend/quotes.csv b/examples/quotes/backend/quotes.csv new file mode 100644 index 000000000..44d95eb7a --- /dev/null +++ b/examples/quotes/backend/quotes.csv @@ -0,0 +1,843 @@ +"quote","author","tags" +"Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.","Albert Einstein","attributed-no-source,human-nature,humor,infinity,philosophy,science,stupidity,universe" +"In three words I can sum up everything I've learned about life: it goes on.","Robert Frost","moving-on,learned" +"If you tell the truth, you don't have to remember anything.","Mark Twain","lies,lying,memory,truth" +"I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel.","Maya Angelou","61419-likes" +"There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.","Albert Einstein","attributed-no-source,inspirational,life,live,miracle,miracles" +"Good friends, good books, and a sleepy conscience: this is the ideal life.","Mark Twain","books,contentment,friends,friendship,life" +"Whenever you find yourself on the side of the majority, it is time to reform (or pause and reflect).","Mark Twain","individuality,majority,minority,pause,reflect,wisdom" +"The man who does not read has no advantage over the man who cannot read.","Mark Twain","aliteracy,attributed-no-source,literacy" +"Outside of a dog, a book is man's best friend. Inside of a dog it's too dark to read.","Groucho Marx","animals,books,dogs,friends,humor" +"I am enough of an artist to draw freely upon my imagination. Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world.","Albert Einstein","1929,imagination,inspirational,viereck-interview" +"Never put off till tomorrow what may be done day after tomorrow just as well.","Mark Twain","humor,procrastination" +"If you can't explain it to a six year old, you don't understand it yourself.","Albert Einstein","attributed-no-source,simplicity,understand" +"Everything you can imagine is real.","Pablo Picasso","art,imagination,inspirational,life" +"If you want your children to be intelligent, read them fairy tales. If you want them to be more intelligent, read them more fairy tales.","Albert Einstein","attributed-no-source,children,fairy-tales" +"Logic will get you from A to Z; imagination will get you everywhere.","Albert Einstein","attributed-no-source,imagination" +"I find television very educating. Every time somebody turns on the set, I go into the other room and read a book.","Groucho Marx","books,humor,reading,television" +"When one door of happiness closes, another opens; but often we look so long at the closed door that we do not see the one which has been opened for us.","Helen Keller","inspirational" +"Life is like riding a bicycle. To keep your balance, you must keep moving.","Albert Einstein","balance,moving,bicycle" +"If everyone is moving forward together, then success takes care of itself.","Henry Ford","together,care,moving" +"Love is like a beautiful flower which I may not touch, but whose fragrance makes the garden a place of delight just the same.","Helen Keller","flower,beautiful,garden" +"What's money? A man is a success if he gets up in the morning and goes to bed at night and in between does what he wants to do.","Bob Dylan","morning,money,night" +"The most beautiful thing we can experience is the mysterious. It is the source of all true art and science.","Albert Einstein","experience,science" +"You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us. And the world will live as one.","John Lennon","beatles,connection,dreamers,dreaming,dreams,hope,inspirational,peace" +"Optimism is the faith that leads to achievement. Nothing can be done without hope and confidence.","Helen Keller","motivational,faith" +"Love is an irresistible desire to be irresistibly desired.","Robert Frost","love" +"Love is the flower you've got to let grow.","John Lennon","flower,grow" +"Success depends upon previous preparation, and without such preparation there is sure to be failure.","Confucius","failure,sure,depends" +"Imagine all the people living life in peace. You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us, and the world will be as one.","John Lennon","peace,hope,dreamer" +"The question isn't who is going to let me; it's who is going to stop me.","Ayn Rand","15880-likes" +"Coming together is a beginning; keeping together is progress; working together is success.","Henry Ford","together,progress" +"I have never let my schooling interfere with my education.","Mark Twain","attributed-no-source,education" +"Try not to become a man of success, but rather try to become a man of value.","Albert Einstein","value,rather" +"Anyone who has never made a mistake has never tried anything new.","Albert Einstein","attributed-no-source,mistakes" +"Action is the foundational key to all success.","Pablo Picasso","action,key" +"The fear of death follows from the fear of life. A man who lives fully is prepared to die at any time.","Mark Twain","death,life" +"′Classic′ - a book which people praise and don't read.","Mark Twain","books,classic,reading" +"The biggest adventure you can take is to live the life of your dreams.","Oprah Winfrey","dreams,adventure,biggest" +"Alcohol may be man's worst enemy, but the bible says love your enemy.","Frank Sinatra","alcohol,bible,drinking,enemies,religion" +"Happiness lies in the joy of achievement and the thrill of creative effort.","Franklin D. Roosevelt","happiness" +"All you need in this life is ignorance and confidence, and then success is sure.","Mark Twain","success,ignorance" +"Love recognizes no barriers. It jumps hurdles, leaps fences, penetrates walls to arrive at its destination full of hope.","Maya Angelou","love" +"The foundation stones for a balanced success are honesty, character, integrity, faith, love and loyalty.","Zig Ziglar","success,faith,character" +"Strive not to be a success, but rather to be of value.","Albert Einstein","business,success,value" +"I've failed over and over and over again in my life and that is why I succeed.","Michael Jordan","success,succeed,again" +"True art is characterized by an irresistible urge in the creative artist.","Albert Einstein","creative,artist,true" +"Everyone has inside of him a piece of good news. The good news is that you don't know how great you can be! How much you can love! What you can accomplish! And what your potential is!","Anne Frank","love,good,great" +"I believe that being successful means having a balance of success stories across the many areas of your life. You can't truly be considered successful in your business life if your home life is in shambles.","Zig Ziglar","home,life,business" +"I am enough of an artist to draw freely upon my imagination.","Albert Einstein","artist,draw,freely" +"It is easy to hate and it is difficult to love. This is how the whole scheme of things works. All good things are difficult to achieve; and bad things are very easy to get.","Confucius","good,achieve,hate" +"Choose a job you love, and you will never have to work a day in your life.","Confucius","work,love,choose" +"If you have only one smile in you give it to the people you love.","Maya Angelou","valentine's-day" +"Sculpture is the art of the intelligence.","Pablo Picasso","sculpture" +"A lie can travel half way around the world while the truth is putting on its shoes.","Mark Twain","misattributed-mark-twain,truth" +"Only a life lived for others is a life worthwhile.","Albert Einstein","others,worthwhile,lived" +"Never tell the truth to people who are not worthy of it.","Mark Twain","truth" +"Success is like reaching an important birthday and finding you're exactly the same.","Audrey Hepburn","birthday,finding,reaching" +"My great hope is to laugh as much as I cry; to get my work done and try to love somebody and have the courage to accept the love in return.","Maya Angelou","being-loved,courage,laugh,love,loving" +"The ladder of success is best climbed by stepping on the rungs of opportunity.","Ayn Rand","best,ladder,stepping" +"Learn from yesterday, live for today, hope for tomorrow. The important thing is not to stop questioning.","Albert Einstein","today,learn,tomorrow" +"I believe that unarmed truth and unconditional love will have the final word in reality. This is why right, temporarily defeated, is stronger than evil triumphant.","Martin Luther King Jr.","good-and-evil,love,truth" +"We must accept finite disappointment, but never lose infinite hope.","Martin Luther King Jr.","hope" +"We have always held to the hope, the belief, the conviction that there is a better life, a better world, beyond the horizon.","Franklin D. Roosevelt","hope,conviction,belief" +"I simply can't build my hopes on a foundation of confusion, misery and death... I think... peace and tranquillity will return again.","Anne Frank","death,peace,foundation" +"You can make positive deposits in your own economy every day by reading and listening to powerful, positive, life-changing content and by associating with encouraging and hope-building people.","Zig Ziglar","positive,reading,listening" +"Youth is easily deceived because it is quick to hope.","Aristotle","youth,deceived,quick" +"Speak the truth, do not yield to anger; give, if thou art asked for little; by these three steps thou wilt go near the gods.","Confucius","truth,anger,speak" +"Knowing yourself is the beginning of all wisdom.","Aristotle","introspection,self-discovery,wisdom" +"Art washes away from the soul the dust of everyday life.","Pablo Picasso","art" +"A person with a new idea is a crank until the idea succeeds.","Mark Twain","crank,succeeds,until" +"I would rather walk with a friend in the dark, than alone in the light.","Helen Keller","friendship" +"Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make the big choices in life. Because almost everything - all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important.","Steve Jobs","failure,death,fear" +"The overwhelming majority of Americans are possessed of two great qualities a sense of humor and a sense of proportion.","Franklin D. Roosevelt","great,qualities,majority" +"Part of the secret of a success in life is to eat what you like and let the food fight it out inside.","Mark Twain","food,life,fight" +"Love is a better teacher than duty.","Albert Einstein","teacher,duty" +"In the flush of love's light, we dare be brave. And suddenly we see that love costs all we are, and will ever be. Yet it is only love which sets us free.","Maya Angelou","light,free,brave" +"I speak to everyone in the same way, whether he is the garbage man or the president of the university.","Albert Einstein","life,respect" +"You cannot climb the ladder of success dressed in the costume of failure.","Zig Ziglar","failure,ladder,climb" +"Keep away from people who try to belittle your ambitions. Small people always do that, but the really great make you feel that you, too, can become great.","Mark Twain","greatness" +"Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it.","Steve Jobs","life,love,work" +"The beauty of a woman must be seen from in her eyes, because that is the doorway to her heart, the place where love resides.","Audrey Hepburn","beauty,eyes,heart" +"A person will sometimes devote all his life to the development of one part of his body - the wishbone.","Robert Frost","body,devote,wishbone" +"People are basically the same the world over. Everybody wants the same things - to be happy, to be healthy, to be at least reasonably prosperous, and to be secure. They want friends, peace of mind, good family relationships, and hope that tomorrow is going to be even better than today.","Zig Ziglar","family,good,peace" +"How wonderful it is that nobody need wait a single moment before starting to improve the world.","Anne Frank","moment,improve,wait" +"Nothing is impossible, the word itself says 'I'm possible'!","Audrey Hepburn","impossible,possible" +"We should measure welfare's success by how many people leave welfare, not by how many are added.","Ronald Reagan","welfare,measure,leave" +"We've got this gift of love, but love is like a precious plant. You can't just accept it and leave it in the cupboard or just think it's going to get on by itself. You've got to keep watering it. You've got to really look after it and nurture it.","John Lennon","relationship,nurture,gift" +"I write some country music. There's a song called 'I Hope You Dance.' Incredible. I was going to write that poem; somebody beat me to it.","Maya Angelou","music,dance,song" +"Painting is just another way of keeping a diary.","Pablo Picasso","painting,diary,keeping" +"If you find it in your heart to care for somebody else, you will have succeeded.","Maya Angelou","care,heart,succeeded" +"There is a very fine line between loving life and being greedy for it.","Maya Angelou","greed,life" +"We love the things we love for what they are.","Robert Frost","love,poetry" +"I decided, very early on, just to accept life unconditionally; I never expected it to do anything special for me, yet I seemed to accomplish far more than I had ever hoped. Most of the time it just happened to me without my ever seeking it.","Audrey Hepburn","time,accept,special" +"Count your age by friends, not years. Count your life by smiles, not tears.","John Lennon","happiness,timelessness,wisdom" +"I remember a specific moment, watching my grandmother hang the clothes on the line, and her saying to me, 'you are going to have to learn to do this,' and me being in that space of awareness and knowing that my life would not be the same as my grandmother's life.","Oprah Winfrey","space,learn,moment" +"When you're in jail, a good friend will be trying to bail you out. A best friend will be in the cell next to you saying, 'Damn, that was fun'.","Groucho Marx","friends,humor,jail" +"I believe that a simple and unassuming manner of life is best for everyone, best both for the body and the mind.","Albert Einstein","best,simple,body" +"When you are courting a nice girl an hour seems like a second. When you sit on a red-hot cinder a second seems like an hour. That's relativity.","Albert Einstein","humor" +"In a good bookroom you feel in some mysterious way that you are absorbing the wisdom contained in all the books through your skin, without even opening them.","Mark Twain","bookroom,books,libraries,wisdom" +"Loving someone liberates the lover as well as the beloved. And that kind of love comes with age.","Maya Angelou","age,lover,loving" +"For the past 33 years, I have looked in the mirror every morning and asked myself: 'If today were the last day of my life, would I want to do what I am about to do today?' And whenever the answer has been 'No' for too many days in a row, I know I need to change something.","Steve Jobs","change,morning,mirror" +"Never memorize something that you can look up.","Albert Einstein","humor,science" +"He that lives upon hope will die fasting.","Benjamin Franklin","die,fasting,lives" +"I always entertain great hopes.","Robert Frost","great,hopes,entertain" +"Lord save us all from old age and broken health and a hope tree that has lost the faculty of putting out blossoms.","Mark Twain","health,age,tree" +"Hope is a waking dream.","Aristotle","dreams,hope" +"In the end, that's what this election is about. Do we participate in a politics of cynicism or a politics of hope?","Barack Obama","politics,election,cynicism" +"A clever person solves a problem. A wise person avoids it.","Albert Einstein","8292-likes" +"Reader, suppose you were an idiot. And suppose you were a member of Congress. But I repeat myself.","Mark Twain","humor,politics" +"Substitute 'damn' every time you're inclined to write 'very;' your editor will delete it and the writing will be just as it should be.","Mark Twain","humor,writing" +"Science without religion is lame, religion without science is blind.","Albert Einstein","religion,science" +"I love people who make me laugh. I honestly think it's the thing I like most, to laugh. It cures a multitude of ills. It's probably the most important thing in a person.","Audrey Hepburn","love,honestly,laugh" +"When someone shows you who they are believe them; the first time.","Maya Angelou","oprah-s-thank-you-game,people" +"Reality is merely an illusion, albeit a very persistent one.","Albert Einstein","reality" +"I attribute my success to this - I never gave or took any excuse.","Florence Nightingale","motivational,excuse" +"Whatever you want to do, if you want to be great at it, you have to love it and be able to make sacrifices for it.","Maya Angelou","great,whatever,sacrifices" +"Don’t go around saying the world owes you a living. The world owes you nothing. It was here first.","Mark Twain","living,world" +"I believe in everything until it's disproved. So I believe in fairies, the myths, dragons. It all exists, even if it's in your mind. Who's to say that dreams and nightmares aren't as real as the here and now?","John Lennon","beatles,dragons,dreamers,dreaming,dreams,fairies,faith,mythology,nightmares,reality,truth" +"Knowledge is love and light and vision.","Helen Keller","knowledge,light,vision" +"Honesty and integrity are absolutely essential for success in life - all areas of life. The really good news is that anyone can develop both honesty and integrity.","Zig Ziglar","success,good,integrity" +"Life is what happens while you are busy making other plans.","John Lennon","busy,plans,happens" +"The more one does and sees and feels, the more one is able to do, and the more genuine may be one's appreciation of fundamental things like home, and love, and understanding companionship.","Amelia Earhart","home,genuine,feels" +"If we knew what it was we were doing, it would not be called research, would it?","Albert Einstein","science" +"Don't go around saying the world owes you a living. The world owes you nothing. It was here first.","Mark Twain","owes,living,saying" +"Faith is taking the first step even when you can't see the whole staircase.","Martin Luther King Jr.","inspirational-faith" +"The superior man makes the difficulty to be overcome his first interest; success only comes later.","Confucius","overcome,difficulty" +"I have no special talents. I am only passionately curious.","Albert Einstein","inspirational-life" +"Good friends, good books and a sleepy conscience: this is the ideal life.","Mark Twain","good,books,conscience" +"Well, Art is Art, isn't it? Still, on the other hand, water is water. And east is east and west is west and if you take cranberries and stew them like applesauce they taste much more like prunes than rhubarb does. Now you tell me what you know.","Groucho Marx","water,hand,taste" +"When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy’. They told me I didn’t understand the assignment, and I told them they didn’t understand life.","John Lennon","inspirational,life" +"Whether you think you can, or you think you can't--you're right.","Henry Ford","thinking" +"In the end, we will remember not the words of our enemies, but the silence of our friends.","Martin Luther King Jr.","inspirational" +"I should have no objection to go over the same life from its beginning to the end: requesting only the advantage authors have, of correcting in a second edition the faults of the first.","Benjamin Franklin","beginning,advantage,second" +"Think of all the beauty still left around you and be happy.","Anne Frank","anne,beauty,frank,happy" +"The most important thing is to enjoy your life—to be happy—it's all that matters.","Audrey Hepburn","happiness,life" +"If a cluttered desk is a sign of a cluttered mind, of what, then, is an empty desk a sign?","Albert Einstein","einstein,human,humor,philosophy,stupidity" +"Never be bullied into silence. Never allow yourself to be made a victim. Accept no one’s definition of your life; define yourself.","Robert Frost","6617-likes" +"Everything is clearer when you're in love.","John Lennon","love" +"I did not attend his funeral, but I sent a nice letter saying I approved of it.","Mark Twain","classic-insult,funeral,funny,humor" +"What is a friend? A single soul dwelling in two bodies.","Aristotle","friendship,soul" +"God created war so that Americans would learn geography.","Mark Twain","americans,geography,war" +"My mission in life is not merely to survive, but to thrive; and to do so with some passion, some compassion, some humor, and some style.","Maya Angelou","life,humor,compassion" +"Love is the greatest refreshment in life.","Pablo Picasso","life,greatest" +"We delight in the beauty of the butterfly, but rarely admit the changes it has gone through to achieve that beauty.","Maya Angelou","inspiration" +"Gravitation is not responsible for people falling in love.","Albert Einstein","love" +"As usual, there is a great woman behind every idiot.","John Lennon","beatles,men,women" +"Either write something worth reading or do something worth writing.","Benjamin Franklin","hmmm" +"If you can't fly then run, if you can't run then walk, if you can't walk then crawl, but whatever you do you have to keep moving forward.","Martin Luther King Jr.","inspirational" +"If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed.","Albert Einstein","good,fear,punishment" +"I was gratified to be able to answer promptly, and I did. I said I didn’t know.","Mark Twain","humor,knowledge" +"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?","Mark Twain","humor-satan" +"If money is your hope for independence you will never have it. The only real security that a man will have in this world is a reserve of knowledge, experience, and ability.","Henry Ford","knowledge,money,experience" +"I love to see a young girl go out and grab the world by the lapels. Life's a bitch. You've got to go out and kick ass.","Maya Angelou","humor,inspirational,life" +"Never allow someone to be your priority while allowing yourself to be their option.","Mark Twain","heartbreak" +"The important thing is to not stop questioning. Curiosity has its own reason for existence. One cannot help but be in awe when he contemplates the mysteries of eternity, of life, of the marvelous structure of reality. It is enough if one tries merely to comprehend a little of this mystery each day.—"Old Man's Advice to Youth: 'Never Lose a Holy Curiosity.'"LIFE Magazine (2 May 1955) p. 64","Albert Einstein","1955,curiosity,mystery,physics,science" +"A youth, when at home, should be filial and, abroad, respectful to his elders. He should be earnest and truthful. He should overflow in love to all and cultivate the friendship of the good. When he has time and opportunity, after the performance of these things, he should employ them in polite studies.","Confucius","love,time,home" +"No tears in the writer, no tears in the reader. No surprise in the writer, no surprise in the reader.","Robert Frost","reading,writing" +"Try not to become a man of success. Rather become a man of value.","Albert Einstein","adulthood,success,value" +"Turn your wounds into wisdom.","Oprah Winfrey","experience,inspirational,pain,wisdom,wounds" +"I thank God I'm myself and for the life I'm given to live and for friends and lovers and beloveds, and I thank God for knowing that all those people have already paid for me.","Maya Angelou","god,knowing,lovers" +"Every child is an artist. The problem is how to remain an artist once he grows up.","Pablo Picasso","art,attributed-no-source" +"Loyalty to country ALWAYS. Loyalty to government, when it deserves it.","Mark Twain","patriotism,politics" +"Wrinkles should merely indicate where the smiles have been.","Mark Twain","age" +"Courage is the most important of all the virtues because without courage, you can't practice any other virtue consistently.","Maya Angelou","character,consistency,courage,determination,essence,ethos,fortitude,goodness,inspiration,life-lessons,persistence,resolve,self-reliance,strength,virtue,virtues" +"Any fool can know. The point is to understand.","Albert Einstein","knowledge,learning,understanding,wisdom" +"Life would be infinitely happier if we could only be born at the age of eighty and gradually approach eighteen.","Mark Twain","age,born,approach" +"And I loved Fats Waller. I love his instrumental abilities, his vocal abilities and his sense of humor.","Paul McCartney","humor,loved,ability" +"The best and most beautiful things in the world cannot be seen or even touched. They must be felt with the heart","Helen Keller","by-anne-sullivan,emotions,feelings" +"No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to make way for the new.","Steve Jobs","death,change,best" +"Rhetoric may be defined as the faculty of observing in any given case the available means of persuasion. This is not a function of any other art.","Aristotle","persuasion,rhetoric" +"I don't trust people who don't love themselves and tell me, 'I love you.' ... There is an African saying which is: Be careful when a naked person offers you a shirt.","Maya Angelou","1997,annie-clark-tanner-lecture,inspirational,love,trust" +"I've missed more than 9000 shots in my career. I've lost almost 300 games. 26 times, I've been trusted to take the game winning shot and missed. I've failed over and over and over again in my life. And that is why I succeed.","Michael Jordan","inspirational" +"Once you can accept the universe as matter expanding into nothing that is something, wearing stripes with plaid comes easy.","Albert Einstein","funny" +"Microsoft has had two goals in the last 10 years. One was to copy the Mac, and the other was to copy Lotus' success in the spreadsheet - basically, the applications business. And over the course of the last 10 years, Microsoft accomplished both of those goals. And now they are completely lost.","Steve Jobs","business,goals,lost" +"Try to look at your weakness and convert it into your strength. That's success.","Zig Ziglar","strength,weakness,convert" +"A woman's heart should be so hidden in God that a man has to seek Him just to find her.","Maya Angelou","inspirational" +"What material success does is provide you with the ability to concentrate on other things that really matter. And that is being able to make a difference, not only in your own life, but in other people's lives.","Oprah Winfrey","life,ability,difference" +"You can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.","Steve Jobs","future,trust,karma" +"What we have once enjoyed we can never lose. All that we love deeply becomes a part of us.","Helen Keller","lose,becomes,enjoyed" +"Music was my refuge. I could crawl into the space between the notes and curl my back to loneliness.","Maya Angelou","loneliness,music,refuge" +"Love many things, for therein lies the true strength, and whosoever loves much performs much, and can accomplish much, and what is done in love is done well.","Vincent Van Gogh","strength,true,accomplish" +"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest.","Confucius","wisdom" +"Humor must not professedly teach and it must not professedly preach, but it must do both if it would live forever.","Mark Twain","teach,forever,preach" +"I met Woz when I was 13, at a friend's garage. He was about 18. He was, like, the first person I met who knew more electronics than I did at that point. We became good friends, because we shared an interest in computers and we had a sense of humor. We pulled all kinds of pranks together.","Steve Jobs","good,computers,together" +"The purpose of art is washing the dust of daily life off our souls.","Pablo Picasso","life,daily,purpose" +"If I were not a physicist, I would probably be a musician. I often think in music. I live my daydreams in music. I see my life in terms of music.","Albert Einstein","music" +"Only in the darkness can you see the stars.","Martin Luther King Jr.","hope,inspirational" +"No person is your friend who demands your silence, or denies your right to grow.","Alice Walker","silence,friend,grow" +"The Bush Administration's failure to be consistently involved in helping Israel achieve peace with the Palestinians has been both wrong for our friendship with Israel, as well as badly damaging to our standing in the Arab world.","Barack Obama","failure,peace,achieve" +"The most difficult thing is the decision to act, the rest is merely tenacity. The fears are paper tigers. You can do anything you decide to do. You can act to change and control your life; and the procedure, the process is its own reward.","Amelia Earhart","change,decision,control" +"The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.","Albert Einstein","change,deep-thoughts,thinking,world" +"Be true to the game, because the game will be true to you. If you try to shortcut the game, then the game will shortcut you. If you put forth the effort, good things will be bestowed upon you. That's truly about the game, and in some ways that's about life too.","Michael Jordan","good,effort,game" +"Art is the lie that enables us to realize the truth.","Pablo Picasso","art,truth" +"The more I see, the less I know for sure.","John Lennon","beatles,life,perception,truth" +"I do not fear death. I had been dead for billions and billions of years before I was born, and had not suffered the slightest inconvenience from it.","Mark Twain","death,inspirational" +"Books are for people who wish they were somewhere else.","Mark Twain","books-reading" +"Those who educate children well are more to be honored than they who produce them; for these only gave them life, those the art of living well.","Aristotle","greek,mentors,philosophy,teachers" +"What would men be without women? Scarce, sir...mighty scarce.","Mark Twain","humor,men,women" +"The secret source of humor is not joy but sorrow; there is no humor in Heaven.","Mark Twain","joy,heaven,sorrow" +"I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones.","Albert Einstein","albert-einstein,future,war,wisdom" +"Success is liking yourself, liking what you do, and liking how you do it.","Maya Angelou","4051-likes" +"You never fail until you stop trying.","Albert Einstein","inspirational" +"We all know that Art is not truth. Art is a lie that makes us realize the truth, at least the truth that is given to us to understand.","Pablo Picasso","truth,lie,understand" +"Great spirits have always encountered violent opposition from mediocre minds.","Albert Einstein","greatness,opposition,spirit" +"I did then what I knew how to do. Now that I know better, I do better.","Maya Angelou","attributed,attributed-no-source,education,intelligence,knowledge,unsourced" +"Some say the world will end in fire,Some say in ice.From what I've tasted of desire,I hold with those who favor fire. But if it had to perish twiceI think I know enough of hateTo say that for destruction iceIs also greatAnd would suffice.","Robert Frost","poetry" +"Sanity and happiness are an impossible combination.","Mark Twain","happiness,sanity" +"My mission in life is not merely to survive, but to thrive; and to do so with some passion, some compassion, some humor, and some style","Maya Angelou","3758-likes" +"A poem begins as a lump in the throat, a sense of wrong, a homesickness, a lovesickness.","Robert Frost","poetry" +"Clothes make the man. Naked people have little or no influence on society.","Mark Twain","clothing" +"Don't part with your illusions. When they are gone you may still exist, but you have ceased to live.","Mark Twain","illusions,life" +"I can shake off everything as I write; my sorrows disappear, my courage is reborn.","Anne Frank","writing" +"The aim of art is to represent not the outward appearance of things, but their inward significance.","Aristotle","art,philosophy" +"Our brand of democracy is hard. But I can promise that a year from now, when I no longer hold this office, I'll be right there with you as a citizen - inspired by those voices of fairness and vision, of grit and good humor and kindness that have helped America travel so far.","Barack Obama","travel,good,kindness" +"If you hear a voice within you say 'you cannot paint,' then by all means paint, and that voice will be silenced.","Vincent Van Gogh","voice,within,paint" +"From the moment I picked up your book until I put it down, I was convulsed with laughter. Some day I intend reading it.","Groucho Marx","books,humor,reading" +"The most common way people give up their power is by thinking they don't have any.","Alice Walker","inspirational" +"I'll always stay connected with Apple. I hope that throughout my life I'll sort of have the thread of my life and the thread of Apple weave in and out of each other, like a tapestry. There may be a few years when I'm not there, but I'll always come back.","Steve Jobs","life,connected,apple" +"There can be no deep disappointment where there is not deep love.","Martin Luther King Jr.","justice,love,segregation" +"Have enough courage to trust love one more time and always one more time.","Maya Angelou","courage,love,trust" +"Achievement of your happiness is the only moral purpose of your life, and that happiness, not pain or mindless self-indulgence, is the proof of your moral integrity, since it is the proof and the result of your loyalty to the achievement of your values.","Ayn Rand","happiness,pain,integrity" +"If you pick up a starving dog and make him prosperous he will not bite you. This is the principal difference between a dog and man.","Mark Twain","animals,dogs" +"When I was a boy of 14, my father was so ignorant I could hardly stand to have the old man around. But when I got to be 21, I was astonished at how much the old man had learned in seven years.","Mark Twain","arrogance,humor,ignorance" +"Everything human is pathetic. The secret source of humor itself is not joy but sorrow. There is no humor in heaven.","Mark Twain","joy,heaven,sorrow" +"Always do what is right. It will gratify half of mankind and astound the other.","Mark Twain","morals" +"The artist is a receptacle for emotions that come from all over the place: from the sky, from the earth, from a scrap of paper, from a passing shape, from a spider's web.","Pablo Picasso","sky,earth,emotions" +"There is more to sex appeal than just measurements. I don't need a bedroom to prove my womanliness. I can convey just as much sex appeal, picking apples off a tree or standing in the rain.","Audrey Hepburn","sex-appeal,women" +"Education is the ability to listen to almost anything without losing your temper or your self-confidence.","Robert Frost","education" +"Perfect friendship is the friendship of men who are good, and alike in excellence; for these wish well alike to each other qua good, and they are good in themselves.","Aristotle","good,men,excellence" +"It is not that I'm so smart. But I stay with the questions much longer.","Albert Einstein","intelligence,learning,wisdom" +"A woman without a man is like a fish without a bicycle.","Gloria Steinem","feminism,humour" +"The trouble is not in dying for a friend, but in finding a friend worth dying for.","Mark Twain","3011-likes" +"The more you praise and celebrate your life, the more there is in life to celebrate.","Oprah Winfrey","happiness,life" +"One thing you can't hide - is when you're crippled inside.","John Lennon","beatles,emotions,hypocrisy,pain,suffering" +"Fighting for one's freedom, struggling towards being free, is like struggling to be a poet or a good Christian or a good Jew or a good Muslim or good Zen Buddhist. You work all day long and achieve some kind of level of success by nightfall, go to sleep and wake up the next morning with the job still to be done. So you start all over again.","Maya Angelou","work,morning,freedom" +"If you don't read the newspaper, you're uninformed. If you read the newspaper, you're mis-informed.","Mark Twain","newspapers" +"There are millions of Americans outside Washington who are tired of stale political arguments and are moving this country forward. They believe, and I believe, that here in America, our success should depend not on accident of birth, but the strength of our work ethic and the scope of our dreams.","Barack Obama","work,strength,dreams" +"Creativity is intelligence having fun.","Albert Einstein","2946-likes" +"Wheresoever you go, go with all your heart.","Confucius","2940-likes" +"The measure of intelligence is the ability to change.","Albert Einstein","adaptation,flexibility,intelligence,open-mindedness,wisdom" +"Everything has beauty, but not everyone sees it.","Confucius","beauty,everything,seeing" +"Learn to value yourself, which means: fight for your happiness.","Ayn Rand","fight,happiness,learn" +"The world is a dangerous place to live, not because of the people who are evil, but because of the people who don't do anything about it.","Albert Einstein","dangerous,evil,people,world" +"Courage is resistance to fear, mastery of fear - not absence of fear.","Mark Twain","courage" +"If we couldn't laugh we would all go insane.","Robert Frost","laughter" +"You can have it all. Just not all at once.","Oprah Winfrey","dreams,life,time" +"The best thing to hold onto in life is each other.","Audrey Hepburn","inspirational" +"Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.","Steve Jobs","2740-likes" +"If A is a success in life, then A equals x plus y plus z. Work is x; y is play; and z is keeping your mouth shut","Albert Einstein","albert,einstein,equations,success" +"Black holes are where God divided by zero.","Albert Einstein","humor" +"If I’m honest I have to tell you I still read fairy-tales and I like them best of all.","Audrey Hepburn","fairy-tales" +"Learn from the mistakes of others. You can never live long enough to make them all yourself.","Groucho Marx","attributed-no-source" +"Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma - which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition.","Steve Jobs","courage,time,heart" +"You can only become truly accomplished at something you love. Don’t make money your goal. Instead pursue the things you love doing and then do them so well that people can’t take their eyes off of you.","Maya Angelou","2637-likes" +"Everyone is a moon, and has a dark side which he never shows to anybody.","Mark Twain","darkness,human-nature,moon" +"Change will not come if we wait for some other person, or if we wait for some other time. We are the ones we've been waiting for. We are the change that we seek.","Barack Obama","change,inspirational" +"It's not the size of the dog in the fight, it's the size of the fight in the dog.","Mark Twain","bravery,dog,famous,inspirational,valour" +"Kindness is a language which the deaf can hear and the blind can see.","Mark Twain","inspirational,kindness" +"There's nowhere you can be that isn't where you're meant to be...","John Lennon","beatles,destiny,fate,life" +"Never make someone a priority when all you are to them is an option.","Maya Angelou","2570-likes" +"Nothing in the world is more dangerous than sincere ignorance and conscientious stupidity.","Martin Luther King Jr.","ignorance" +"The ultimate measure of a man is not where he stands in moments of comfort and convenience, but where he stands at times of challenge and controversy.","Martin Luther King Jr.","challanges" +"If there is any one secret of success, it lies in the ability to get the other person's point of view and see things from that person's angle as well as from your own.","Henry Ford","ability,view,point" +"Forgive, O Lord, my little jokes on TheeAnd I'll forgive Thy great big one on me.","Robert Frost","humor,poetry,religion" +"Procrastination is one of the most common and deadliest of diseases and its toll on success and happiness is heavy.","Wayne Gretzky","happiness,heavy,diseases" +"Humor is mankind's greatest blessing.","Mark Twain","humor" +"I've lived through some terrible things in my life, some of which actually happened.","Mark Twain","humor" +"Tell me and I forget, teach me and I may remember, involve me and I learn.","Benjamin Franklin","learning,mentoring,parenting,teacher" +"The best way to cheer yourself is to cheer somebody else up.","Albert Einstein","2471-likes" +"Lack of direction, not lack of time, is the problem. We all have twenty-four hour days.","Zig Ziglar","attention,direction,focus,inspirational,motivational" +"The secret to humor is surprise.","Aristotle","humor,surprise" +"Name the greatest of all inventors. Accident.","Mark Twain","inventing-humor" +"Behind every beautiful thing, there's some kind of pain.","Bob Dylan","beautiful,behind,kind,of,pain,thing" +"Everything must be made as simple as possible. But not simpler.","Albert Einstein","einstein,paraphrased,science,systems" +"Humor is the most engaging cowardice.","Robert Frost","cowardice,engaging" +"Try to be a rainbow in someone's cloud.","Maya Angelou","cloud,rainbow" +"You believe in a book that has talking animals, wizards, witches, demons, sticks turning into snakes, burning bushes, food falling from the sky, people walking on water, and all sorts of magical, absurd and primitive stories, and you say that we are the ones that need help?","Mark Twain","books-bible" +"The best way to cheer yourself is to try to cheer someone else up.","Mark Twain","happiness" +"When you trip over love, it is easy to get up. But when you fall in love, it is impossible to stand again.","Albert Einstein","love" +"Being the richest man in the cemetery doesn't matter to me. Going to bed at night saying we've done something wonderful... that's what matters to me.","Steve Jobs","2356-likes" +"I never forget a face, but in your case I'll be glad to make an exception.","Groucho Marx","humor" +"You may encounter many defeats, but you must not be defeated. In fact, it may be necessary to encounter the defeats, so you can know who you are, what you can rise from, how you can still come out of it.","Maya Angelou","adversity,character,failure,perseverance" +"Parents can only give good advice or put them on the right paths, but the final forming of a person's character lies in their own hands.","Anne Frank","growing-up,innocence,inspirational,parenting,personal-responsibility,right-of-passage,self-determination,self-responsibility" +"Humor is reason gone mad.","Groucho Marx","reason,mad,gone" +"What is right is not always popular and what is popular is not always right.","Albert Einstein","2280-likes" +"Freedom lies in being bold.","Robert Frost","boldness,courage,freedom" +"Be thankful for what you have; you'll end up having more. If you concentrate on what you don't have, you will never, ever have enough","Oprah Winfrey","appreciation,contentment,dissatisfaction,life,perception,positivity,thankfulness" +"Education: the path from cocky ignorance to miserable uncertainty.","Mark Twain","education" +"If you would be loved, love, and be loveable.","Benjamin Franklin","loved" +"If I am not good to myself, how can I expect anyone else to be good to me?","Maya Angelou","2202-likes" +"It does not matter how slowly you go as long as you do not stop.","Confucius","education,inspirational,life,perseverance" +"Ask for what you want and be prepared to get it!","Maya Angelou","inspirational" +"You alone are enough. You have nothing to prove to anybody.","Maya Angelou","2179-likes" +"I was born with an enormous need for affection, and a terrible need to give it.","Audrey Hepburn","born,affection" +"The easy confidence with which I know another man's religion is folly teaches me to suspect that my own is also.","Mark Twain","humor,philosophy,religion" +"Adventure is worthwhile in itself.","Amelia Earhart","2126-likes" +"Intelligence plus character-that is the goal of true education.","Martin Luther King Jr.","education" +"If everyone demanded peace instead of another television set, then there'd be peace.","John Lennon","activism,beatles,materialism,peace,society,television" +"The pursuit of truth and beauty is a sphere of activity in which we are permitted to remain children all our lives.","Albert Einstein","wonder" +"In the middle of difficulty lies opportunity","Albert Einstein","2072-likes" +"The best way out is always through.","Robert Frost","best" +"Whoever is careless with the truth in small matters cannot be trusted with important matters","Albert Einstein","character,honesty,integrity" +"I believe in God, but not as one thing, not as an old man in the sky. I believe that what people call God is something in all of us. I believe that what Jesus and Mohammed and Buddha and all the rest said was right. It's just that the translations have gone wrong.","John Lennon","god,organized-religion,religion,spirituality" +"I believe in being strong when everything seems to be going wrong. I believe that happy girls are the prettiest girls. I believe that tomorrow is another day, and I believe in miracles","Audrey Hepburn","life" +"Men marry women with the hope they will never change. Women marry men with the hope they will change. Invariably they are both disappointed.","Albert Einstein","battle-of-the-sexes,gender-stereotypes,marriage,men-and-women" +"Stepping onto a brand-new path is difficult, but not more difficult than remaining in a situation, which is not nurturing to the whole woman.","Maya Angelou","change,inspirational,self-determination" +"Poetry is what gets lost in translation.","Robert Frost","poetry" +"You know you are on the road to success if you would do your job, and not be paid for it.","Oprah Winfrey","road,paid" +"The secret of life is honesty and fair dealing. If you can fake that, you've got it made.","Groucho Marx","humor,life" +"The desire to reach for the stars is ambitious. The desire to reach hearts is wise.","Maya Angelou","ambition,inspirational,wisdom" +"Peace cannot be kept by force; it can only be achieved by understanding.","Albert Einstein","force,peace" +"Half the world is composed of people who have something to say and can't, and the other half who have nothing to say and keep on saying it.","Robert Frost","new-england-wisdom" +"He who knows all the answers has not been asked all the questions.","Confucius","wisdom" +"The secret to getting ahead is getting started.","Mark Twain","starting,working" +"A question that sometimes drives me hazy: am I or are the others crazy?","Albert Einstein","crazy,question,thought-provoking" +"If I'm the people's poet, then I ought to be in people's hands - and, I hope, in their heart.","Maya Angelou","heart,hands,ought" +"Living is Easy with Eyes Closed.","John Lennon","beatles,blindness,ignorance,life" +"If you make a mistake and do not correct it, this is called a mistake.","Confucius","inspirational,mistake" +"Happiness depends upon ourselves.","Aristotle","happiness" +"Two roads diverged in a wood, and I -I took the one less traveled by,And that has made all the difference.","Robert Frost","choice,consequence,individuality,inspirational" +"You can't blame gravity for falling in love.","Albert Einstein","gravity,blame" +"All you need in this life is ignorance and confidence; then success is sure.","Mark Twain","humor,success" +"The best way to not feel hopeless is to get up and do something. Don’t wait for good things to happen to you. If you go out and make some good things happen, you will fill the world with hope, you will fill yourself with hope.","Barack Obama","determination,helping-others,hope,initiative,just-do-it,proactivity,service,volunteerism,work" +"Imagination is everything. It is the preview of life's coming attractions.","Albert Einstein","creativity,fantasy,imagination,inspirational" +"Any book that helps a child to form a habit of reading, to make reading one of his deep and continuing needs, is good for him.","Maya Angelou","books,inspirational,library" +"The highest use of capital is not to make more money, but to make money do more for the betterment of life.","Henry Ford","money,highest,betterment" +"Educating the mind without educating the heart is no education at all.","Aristotle","education,ethics" +"It's hard to beat a person who never gives up.","Babe Ruth","hard-work,inspiration,teamwork" +"Life is really simple, but we insist on making it complicated.","Confucius","simple,insist" +"Love is composed of a single soul inhabiting two bodies.","Aristotle","bodies,soul,single" +"There is probably a perverse pride in my administration... that we were going to do the right thing, even if short-term it was unpopular. And I think anybody who's occupied this office has to remember that success is determined by an intersection in policy and politics and that you can't be neglecting of marketing and P.R. and public opinion.","Barack Obama","politics,pride,marketing" +"It is the supreme art of the teacher to awaken joy in creative expression and knowledge.","Albert Einstein","teacher,knowledge,joy" +"I am not a teacher, but an awakener.","Robert Frost","carpe-diem,education,inspirational,learning,mentoring" +"Excellence is an art won by training and habituation. We do not act rightly because we have virtue or excellence, but we rather have those because we have acted rightly. We are what we repeatedly do. Excellence, then, is not an act but a habit.","Aristotle","training,excellence,act" +"No matter what happens, or how bad it seems today, life does go on, and it will be better tomorrow.","Maya Angelou","inspirational-quotes" +"Because paper has more patience than people.","Anne Frank","affirming,inspirational,uplifting" +"Politics is the art of looking for trouble, finding it everywhere, diagnosing it incorrectly and applying the wrong remedies.","Groucho Marx","politics,wrong,looking" +"Happiness makes up in height for what it lacks in length.","Robert Frost","happiness" +"Each person must live their life as a model for others.","Rosa Parks","model,others" +"If the facts don't fit the theory, change the facts.","Albert Einstein","facts,humor,science" +"The important thing is not to stop questioning. Curiosity has its own reason for existing.","Albert Einstein","curiosity,philosophy,wonder" +"What I know is, is that if you do work that you love, and the work fulfills you, the rest will come.","Oprah Winfrey","work,rest,fulfills" +"Eating is so intimate. It's very sensual. When you invite someone to sit at your table and you want to cook for them, you're inviting a person into your life.","Maya Angelou","food,eating,table" +"A clear conscience is the sure sign of a bad memory.","Mark Twain","conscience,humor,memory" +"I must be willing to give up what I am in order to become what I will be.","Albert Einstein","inspirational" +"I haven't any right to criticize books, and I don't do it except when I hate them. I often want to criticize Jane Austen, but her books madden me so that I can't conceal my frenzy from the reader; and therefore I have to stop every time I begin. Every time I read Pride and Prejudice I want to dig her up and beat her over the skull with her own shin-bone.","Mark Twain","austen,criticism,reading,writing" +"I hope the millions of people I've touched have the optimism and desire to share their goals and hard work and persevere with a positive attitude.","Michael Jordan","attitude,positive,work" +"There is no abstract art. You must always start with something. Afterward you can remove all traces of reality.","Pablo Picasso","reality,start,abstract" +"Love is a better master than duty.","Albert Einstein","love" +"He that can have patience can have what he will.","Benjamin Franklin","determination,inspirational,patience" +"When I die, I hope to go to Heaven, whatever the Hell that is.","Ayn Rand","death,hell,heaven" +"Death is no more than passing from one room into another. But there's a difference for me, you know. Because in that other room I shall be able to see.","Helen Keller","blindness,death,faith,inspirational,wisdom" +"On every front there are clear answers out there that can make this country stronger, but we're going to break through the fear and the frustration people are feeling. Our job is to make sure that even as we make progress, that we are also giving people a sense of hope and vision for the future.","Barack Obama","future,fear,progress" +"The biggest adventure you can ever take is to live the life of your dreams.","Oprah Winfrey","adventure,bravery,inspirational,life" +"Why do they always teach us that it's easy and evil to do what we want and that we need discipline to restrain ourselves? It's the hardest thing in the world--to do what we want. And it takes the greatest kind of courage. I mean, what we really want.","Ayn Rand","career,inspiration,life" +"No one really knows why they are alive until they know what they'd die for.","Martin Luther King Jr.","death,inspirational" +"A banker is a fellow who lends you his umbrella when the sun is shining, but wants it back the minute it begins to rain.","Mark Twain","bank,bankers,humor" +"Happiness is the meaning and the purpose of life, the whole aim and end of human existence.","Aristotle","happiness" +"A Penny Saved is a Penny Earned","Benjamin Franklin","funny,inspirational,money" +"If someone thinks that peace and love are just a cliche that must have been left behind in the 60s, that's a problem. Peace and love are eternal.","John Lennon","1960s,beatles,love,peace,sixties" +"It would be possible to describe everything scientifically, but it would make no sense; it would be without meaning, as if you described a Beethoven symphony as a variation of wave pressure.","Albert Einstein","art,cybernetics,science" +"Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma - which is living with the results of other people's thinking. Don't let the noise of other's opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.","Steve Jobs","death,life,r-i-p,steve" +"The most important thing is to enjoy your life - to be happy - it's all that matters.","Audrey Hepburn","happy,enjoy,matters" +"Those who are not looking for happiness are the most likely to find it, because those who are searching forget that the surest way to be happy is to seek happiness for others.","Martin Luther King Jr.","happiness" +"And God help Bruce Springsteen when they decide he's no longer God... They'll turn on him, and I hope he survives it.","John Lennon","god,help,turn" +"There's a world of difference between truth and facts. Facts can obscure truth.","Maya Angelou","truth" +"Excellence is never an accident. It is always the result of high intention, sincere effort, and intelligent execution; it represents the wise choice of many alternatives - choice, not chance, determines your destiny.","Aristotle","choice,inspirational" +"If a man is called to be a street sweeper, he should sweep streets even as a Michaelangelo painted, or Beethoven composed music or Shakespeare wrote poetry. He should sweep streets so well that all the hosts of heaven and earth will pause to say, 'Here lived a great street sweeper who did his job well.","Martin Luther King Jr.","excellence,inspirational" +"Once I knew only darkness and stillness... my life was without past or future... but a little word from the fingers of another fell into my hand that clutched at emptiness, and my heart leaped to the rapture of living.","Helen Keller","life,future,emptiness" +"In wine there is wisdom, in beer there is Freedom, in water there is bacteria.","Benjamin Franklin","drinking,humor" +"A man is a success if he gets up in the morning and gets to bed at night, and in between he does what he wants to do.","Bob Dylan","bob-dylan,music,success" +"I didn't have time to write a short letter, so I wrote a long one instead.","Mark Twain","humor" +"The smallest minority on earth is the individual. Those who deny individual rights cannot claim to be defenders of minorities.","Ayn Rand","freedom-of-thought,philosophy,politics,rights" +"The way a team plays as a whole determines its success. You may have the greatest bunch of individual stars in the world, but if they don't play together, the club won't be worth a dime.","Babe Ruth","sports,team,together" +"Those are my principles, and if you don't like them...well I have others.","Groucho Marx","humor" +"Home is the place where, when you have to go there, They have to take you in.","Robert Frost","inspirational-quotes" +"Many people die at twenty five and aren't buried until they are seventy five.","Benjamin Franklin","death,life,wordplay" +"Fear not death for the sooner we die, the longer we shall be immortal.","Benjamin Franklin","death" +"I never made one of my discoveries through the process of rational thinking","Albert Einstein","creativity,epiphany,humor,inspiration" +"Any emotion, if it is sincere, is involuntary.","Mark Twain","inspirational" +"I must have a prodigious amount of mind; it takes me as much as a week, sometimes, to make it up!","Mark Twain","decisions,humor,mind" +"The two most important days in your life are the day you are born and the day you find out why.","Mark Twain","birth,born,day,important,life,reasons-why,true" +"Once we accept our limits, we go beyond them.","Albert Einstein","inspirational,self-improvement,self-knowledge" +"Alone we can do so little; together we can do so much","Helen Keller","collaboration,life,teamwork" +"One morning I shot an elephant in my pajamas. How he got in my pajamas I'll never know.","Groucho Marx","humor" +"The best revenge is massive success.","Frank Sinatra","best,revenge,massive" +"My favorite things in life don't cost any money. It's really clear that the most precious resource we all have is time.","Steve Jobs","time,money,precious" +"We, the People, recognize that we have responsibilities as well as rights; that our destinies are bound together; that a freedom which only asks what's in it for me, a freedom without a commitment to others, a freedom without love or charity or duty or patriotism, is unworthy of our founding ideals, and those who died in their defense.","Barack Obama","patriotism,freedom,died" +"The rain to the wind said,You push and I'll pelt.'They so smote the garden bedThat the flowers actually knelt,And lay lodged--though not dead.I know how the flowers felt.","Robert Frost","poetry,rain" +"Our goals can only be reached through a vehicle of a plan, in which we must fervently believe, and upon which we must vigorously act. There is no other route to success.","Pablo Picasso","goals,plan,act" +"To perceive is to suffer.","Aristotle","empathy,life,suffer,understanding" +"The funniest people are the saddest ones","Confucius","funny,people,sad" +"I didn't fail the test, I just found 100 ways to do it wrong.","Benjamin Franklin","examinations,failure,humor" +"Your time is limited, so don't waste it living someone else's life.","Steve Jobs","life,life-and-living" +"Don't ever take a fence down until you know why it was put up.","Robert Frost","advice,caution,cautionary,inspirational" +"Life is a series of experiences, each one of which makes us bigger, even though sometimes it is hard to realize this. For the world was built to develop character, and we must learn that the setbacks and grieves which we endure help us in our marching onward.","Henry Ford","learning,setbacks" +"Government exists to protect us from each other. Where government has gone beyond its limits is in deciding to protect us from ourselves.","Ronald Reagan","freedom-of-choice,government,inspirational,political-philosophy,politics" +"Be slow in choosing a friend, slower in changing.","Benjamin Franklin","friend,slow,changing" +"If a man wants you, nothing can keep him away. If he doesn't want you, nothing can make him stay.","Oprah Winfrey","romance" +"Well, art is art, isn't it? Still, on the other hand, water is water! And east is east and west is west and if you take cranberries and stew them like applesauce they taste much more like prunes than rhubarb does. Now, uh... now you tell me what you know.","Groucho Marx","art,humor" +"The educated differ from the uneducated as much as the living differ from the dead.","Aristotle","education" +"When we remember we are all mad, the mysteries disappear and life stands explained.","Mark Twain","remember,mad,explained" +"I used to think anyone doing anything weird was weird. Now I know that it is the people that call others weird that are weird.","Paul McCartney","beatles,humor,music,nonjudgemental" +"I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.","Martin Luther King Jr.","character,dream,inspirational,prejudice,race" +"Imagination is the highest form of research.","Albert Einstein","inspiration" +"Wherever you go, go with all your heart.","Confucius","confucius,inspirational" +"Life is one grand, sweet song, so start the music.","Ronald Reagan","music,song,start" +"We must live together as brothers or perish together as fools.","Martin Luther King Jr.","brotherhood,inspirational,wisdom" +"If a black cat crosses your path, it signifies that the animal is going somewhere.","Groucho Marx","humor,superstition" +"Science investigates; religion interprets. Science gives man knowledge, which is power; religion gives man wisdom, which is control. Science deals mainly with facts; religion deals mainly with values. The two are not rivals.","Martin Luther King Jr.","religion,science" +"I heard a definition once: Happiness is health and a short memory! I wish I'd invented it, because it is very true.","Audrey Hepburn","happiness,inspirational" +"The most incomprehensible thing about the world is that it is at all comprehensible.","Albert Einstein","einstein,philosophy,science" +"I sustain myself with the love of family.","Maya Angelou","family,inspirational" +"Some people claim that marriage interferes with romance. There's no doubt about it. Anytime you have a romance, your wife is bound to interfere.","Groucho Marx","marriage,romance,sex" +"Learn the rules like a pro, so you can break them like an artist.","Pablo Picasso","art,creativity,motivational,picasso,rules,writing" +"I made my first white women friends in college; they loved me and were loyal to our friendship, but I understood, as they did, that they were white women and that whiteness mattered.","Alice Walker","women,college,loved" +"I've come to believe that each of us has a personal calling that's as unique as a fingerprint - and that the best way to succeed is to discover what you love and then find a way to offer it to others in the form of service, working hard, and also allowing the energy of the universe to lead you.","Oprah Winfrey","individuality,inspirational,success" +"Everyone here has the sense that right now is one of those moments when we are influencing the future.","Steve Jobs","future,moments" +"I trust that everything happens for a reason, even if we are not wise enough to see it.","Oprah Winfrey","inspirational" +"Anyone who stops learning is old, whether at twenty or eighty. Anyone who keeps learning stays young.","Henry Ford","education,lifelong-learning" +"All I can be is me- whoever that is.","Bob Dylan","bob-dylan,inspirational" +"The Bible has noble poetry in it... and some good morals and a wealth of obscenity, and upwards of a thousand lies.","Mark Twain","agnosticism,atheism,bible,christianity,mythology,truth" +"Only those who attempt the absurd can achieve the impossible.","Albert Einstein","achievement,inspirational,optimism" +"Limitless undying love which shines around me like a million suns it calls me on and on across the universe.","John Lennon","beatles,love,sun,universe" +"The people who make art their business are mostly imposters.","Pablo Picasso","business,mostly" +"First best is falling in love. Second best is being in love. Least best is falling out of love. But any of it is better than never having been in love.","Maya Angelou","falling-in-love,love,lovelessness" +"Breathe. Let go. And remind yourself that this very moment is the only one you know you have for sure.","Oprah Winfrey","life" +"I'm happy to be a writer - of prose, poetry, every kind of writing. Every person in the world who isn't a recluse, hermit or mute uses words. I know of no other art form that we always use.","Maya Angelou","poetry,happy,words" +"The dog is a gentleman; I hope to go to his heaven not man's.","Mark Twain","animals,dogs,heaven,inspirational,man,religion" +"Every strike brings me closer to the next home run.","Babe Ruth","baseball,perseverance,philosophy,sports" +"As my sufferings mounted I soon realized that there were two ways in which I could respond to my situation -- either to react with bitterness or seek to transform the suffering into a creative force. I decided to follow the latter course.","Martin Luther King Jr.","activism,healing,inspirational,justice,sacrifice" +"Don’t let the noise of others’ opinions drown out your own inner voice."[Stanford University commencement speech, 2005]","Steve Jobs","apple-computer-inc,identity,independence,inner-voice,life,steve-jobs" +"When we give cheerfully and accept gratefully, everyone is blessed.","Maya Angelou","charity,compassion,gratitude,helping-others,inspiration" +"Reading, after a certain age, diverts the mind too much from its creative pursuits. Any man who reads too much and uses his own brain too little falls into lazy habits of thinking.","Albert Einstein","reading,science" +"There are two kinds of teachers: the kind that fill you with so much quail shot that you can't move, and the kind that just gives you a little prod behind and you jump to the skies.","Robert Frost","inspirational,teachers" +"Men should think twice before making widowhood women's only path to power.","Gloria Steinem","death,feminism,men,murder,widowhood,women,womens-rights" +"To be a poet is a condition, not a profession.","Robert Frost","afflictions,on-writing,poetry" +"How many observe Christ's birthday! How few, His precepts!","Benjamin Franklin","christian-behavior,christmas,religion" +"He is free to evade reality, he is free to unfocus his mind and stumble blindly down any road he pleases, but not free to avoid the abyss he refuses to see.","Ayn Rand","inspirational" +"Memories of our lives, of our works and our deeds will continue in others.","Rosa Parks","memories,others" +"Do not worry about your difficulties in Mathematics. I can assure you mine are still greater.","Albert Einstein","inspirational" +"Life is either a great adventure or nothing.","Helen Keller","great,adventure" +"Hide not your talents, they for use were made,What's a sundial in the shade?","Benjamin Franklin","talent,wisdom,work" +"Student: Dr. Einstein, Aren't these the same questions as last year's [physics] final exam?Dr. Einstein: Yes; But this year the answers are different.","Albert Einstein","humor,science" +"You cannot open a book without learning something.","Confucius","books,learning,philosopher" +"It takes a very long time to become young.","Pablo Picasso","ignorance,innocence,knowledge,wisdom,youth" +"Without leaps of imagination or dreaming, we lose the excitement of possibilities. Dreaming, after all is a form of planning.","Gloria Steinem","dreaming,dreams,excitement,imagination,inspirational,planning,possibility" +"A Woman in harmony with her spirit is like a river flowing.She goes where she will without pretense and arrives at her destination prepared to be herself and only herself","Maya Angelou","inspirational" +"We can't help everyone, but everyone can help someone.","Ronald Reagan","help" +"Wisdom is not a product of schooling but of the lifelong attempt to acquire it.","Albert Einstein","education,knowledge-wisdom,learning,school,science,wisdom" +"Well done is better than well said.","Benjamin Franklin","inspirational" +"Anyone who says he can see through women is missing a lot.","Groucho Marx","funny,innuendo" +"What the superior man seeks is in himself; what the small man seeks is in others.","Confucius","individuality,inspiration,validation" +"Surround yourself only with people who are going to take you higher.","Oprah Winfrey","inspirational" +"Whoever is happy will make others happy too.","Anne Frank","happy,others,whoever" +"Sometimes it's not enough to know what things mean, sometimes you have to know what things don't mean.","Bob Dylan","understanding,wisdom" +"When you see a good person, think of becoming like her/him. When you see someone not so good, reflect on your own weak points.","Confucius","helpful,inspirational,introspection,karma,self-improvement" +"If we ever forget that we're one nation under God, then we will be one nation gone under.","Ronald Reagan","inspirational,religon,separation-of-church-and-state" +"Close your eyes and I'll kiss you, Tomorrow I'll miss you.","Paul McCartney","beatles,kiss,love,miss-you,music,song-lyrics,tomorrow" +"We all live with the objective of being happy; our lives are all different and yet the same.","Anne Frank","happiness,literature" +"the time is always right to do the right thing","Martin Luther King Jr.","inspirational" +"Rich people have small TVs and big libraries, and poor people have small libraries and big TVs.","Zig Ziglar","intelligence,success,wealth" +"Deliver me from writers who say the way they live doesn't matter. I'm not sure a bad person can write a good book. If art doesn't make us better, then what on earth is it for.","Alice Walker","art,bad,good,writing" +"I've been lucky. Opportunities don't often come along. So, when they do, you have to grab them.","Audrey Hepburn","inspirational" +"The truth is not for all men but only for those who seek it.","Ayn Rand","truth" +"God is a concept by which we measure our pain.","John Lennon","beatles,god,religion" +"How can I go forward when I don't know which way I'm facing?","John Lennon","life" +"Love is a promise, love is a souvenir, once given never forgotten, never let it disappear.","John Lennon","attributed-no-source,love" +"Two roads diverged in a wood and I - I took the one less traveled by, and that has made all the difference.","Robert Frost","roads,difference" +"I'm not afraid of death because I don't believe in it.It's just getting out of one car, and into another.","John Lennon","death,spirituality" +"If there is any religion that could respond to the needs of modern science, it would be Buddhism.","Albert Einstein","attributed,attributed-to-einstein-no-source,buddhism,religion,science,unsourced" +"Instead of cursing the darkness, light a candle.","Benjamin Franklin","inspirational,proverb" +"Freedom is never more than one generation away from extinction. We didn't pass it to our children in the bloodstream. It must be fought for, protected, and handed on for them to do the same, or one day we will spend our sunset years telling our children and our children's children what it was once like in the United States where men were free.","Ronald Reagan","freedom,inspirational,personal-freedom" +"I am always doing that which I can not do, in order that I may learn how to do it.","Pablo Picasso","inspirational" +"He who hath many friends hath none.","Aristotle","hath,none" +"When you encourage others, you in the process are encouraged because you're making a commitment and difference in that person's life. Encouragement really does make a difference.","Zig Ziglar","commitment,process" +"Few people are capable of expressing with equanimity opinions which differ from the prejudices of their social enviroment. Most people are incapable of forming such opinions."(Essay to Leo Baeck, 1953)","Albert Einstein","disagreement,dissent,equanimity,expressing,knowledge,opinions,prejudices,social,society,thought" +"If you live each day as it was your last, someday you'll most certainly be right","Steve Jobs","death,life,rip,steve" +"Happy girls are the prettiest","Audrey Hepburn","attractiveness,beauty,happiness" +"All great achievements require time.","Maya Angelou","inspirational,motivation" +"Some painters transform the sun into a yellow spot, others transform a yellow spot into the sun.","Pablo Picasso","sun,yellow,others" +"I want to thank you, Lord, for life and all that's in it. Thank you for the day and for the hour, and the minute.","Maya Angelou","inspirational" +"Eat a live frog first thing in the morning and nothing worse will happen to you the rest of the day.","Mark Twain","humor" +"On some positions, cowardice asks the question, is it expedient? And then expedience comes along and asks the question, is it politic? Vanity asks the question, is it popular? Conscience asks the question, is it right?There comes a time when one must take the position that is neither safe nor politic nor popular, but he must do it because conscience tells him it is right.","Martin Luther King Jr.","truth" +"I cannot imagine a God who rewards and punishes the objects of his creation, whose purposes are modeled after our own -- a God, in short, who is but a reflection of human frailty. Neither can I believe that the individual survives the death of his body, although feeble souls harbor such thoughts through fear or ridiculous egotisms.","Albert Einstein","god,rational,religion,thinking" +"Nothing will work unless you do.","Maya Angelou","inspirational" +"The heart can think of no devotionGreater than being shore to the ocean-Holding the curve of one position,Counting an endless repetition.","Robert Frost","devotion,love,poetry" +"Just give me a comfortable couch, a dog, a good book, and a woman. Then if you can get the dog to go somewhere and read the book, I might have a little fun.","Groucho Marx","dogs,humor,innuendo,naughty" +"If all printers were determined not to print anything till they were sure it would offend nobody, there would be very little printed.","Benjamin Franklin","books,censorship,reading" +"I love the song 'I Hope You Dance' by Lee Ann Womack. I was going to write that song, but someone beat me to it.","Maya Angelou","love,dance,song" +"The way to know life is to love many things.","Vincent Van Gogh","life" +"I believe in intuitions and inspirations...I sometimes FEEL that I am right. I do not KNOW that I am.","Albert Einstein","certainty,faith,intuition" +"Yes We Can!","Barack Obama","action,hope,positivity" +"I've had a lot of worries in my life, most of which never happened.","Mark Twain","inspirational,positive,worries" +"Never bend your head. Hold it high. Look the world straight in the eye.","Helen Keller","inspirational" +"I long to accomplish a great and noble task, but it is my chief duty to accomplish small tasks as if they were great and noble.","Helen Keller","inspirational" +"Life is more or less a lie, but then again, that's exactly the way we want it to be.","Bob Dylan","dylan,life,zen" +"The high-minded man must care more for the truth than for what people think.","Aristotle","truth" +"My religion consists of a humble admiration of the illimitable superior spirit who reveals himself in the slight details we are able to perceive with our frail and feeble mind.","Albert Einstein","god,religion,spirit,spirituality" +"It is not the failure of others to appreciate your abilities that should trouble you, but rather your failure to appreciate theirs.","Confucius","inspirational" +"The man of wisdom is never of two minds;the man of benevolence never worries;the man of courage is never afraid.","Confucius","wisdom" +"Success is the maximum utilization of the ability that you have.","Zig Ziglar","ability,maximum" +"I've learned that you shouldn't go through life with a catcher's mitt on both hands; you need to be able to throw some things back.","Maya Angelou","wisdom" +"If at first the idea is not absurd, then there is no hope for it.","Albert Einstein","absurd,absurdity,hope,idea" +"Love is the only force capable of transforming an enemy to a friend.","Martin Luther King Jr.","love" +"Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it’s worth it in the end because once you get there, you can move mountains.","Steve Jobs","complex,hard,simple,thinking,truth,wisdom,worth" +"The way out is through the door. Why is it that no one will use this method?","Confucius","tao,wisdom,zen" +"Stay hungry. Stay foolish.","Steve Jobs","inspirational" +"When you do something noble and beautiful and nobody noticed, do not be sad. For the sun every morning is a beautiful spectacle and yet most of the audience still sleeps.","John Lennon","beatles,beauty,life,nature,sadness" +"I have left orders to be awakened at any time during national emergency, even if I'm in a cabinet meeting.","Ronald Reagan","growing-older,humor,napping,politics" +"The tragedy of life is what dies inside a man while he lives.","Albert Einstein","inspirational,life" +"One thing I have learned in a long life: that all our science, measured against reality, is primitive and childlike -- and yet it is the most precious thing we have.","Albert Einstein","science" +"He not busy being born is busy dying.","Bob Dylan","inspirational,lyrics,music,self-discovery,songs" +"Earl Nightingale has inspired more people toward success and fortune than any other motivational speaker on the planet.","Zig Ziglar","inspired,planet,fortune" +"People don’t like to think, if one thinks, one must reach conclusions. Conclusions are not always pleasant.","Helen Keller","life,thinking" +"Life is a whim of several billion cells to be you for a while","Groucho Marx","humor" +"The first question which the priest and the Levite asked was: 'If I stop to help this man, what will happen to me?' But...the good Samaritan reversed the question: 'If I do not stop to help this man, what will happen to him?","Martin Luther King Jr.","love,neighbor,sacrifice,service" +"In all the world, there is no heart for me like yours.In all the world, there is no love for you like mine.","Maya Angelou","love,perfect-fit" +"Give a bowl of rice to a man and you will feed him for a day. Teach him how to grow his own rice and you will save his life.","Confucius","education,enduring-good,generosity,life,wise-advice,work" +"The Revolution introduced me to art, and in turn, art introduced me to the Revolution!","Albert Einstein","communism,democracy,freedom,history,hope,individualism,philosophy,politics,revolution,socialism" +"I have gained this by philosophy … I do without being ordered what some are constrained to do by their fear of the law.","Aristotle","law,morality,philosophy,secular-ethics,secular-morality" +"Intellectual growth should commence at birth and cease only at death.","Albert Einstein","inspirational,lifelong-learning" +"The hardest thing of all is to find a black cat in a dark room, especially if there is no cat.","Confucius","futility,knowledge,religion" +"Only the wisest and stupidest of men never change.","Confucius","wisdom" +"Part of me suspects that I'm a loser, and the other part of me thinks I'm God Almighty.","John Lennon","ego,god,life,loser" +"Sometimes life hits you in the head with a brick. Don't lose faith.","Steve Jobs","faith,brick,head" +"We know from daily life that we exist for other people first of all, for whose smiles and well-being our own happiness depends.","Albert Einstein","friendship,life,relationships" +"Don't find fault, find a remedy; anybody can complain","Henry Ford","common-sense,inspirational" +"Your success and happiness lies in you. Resolve to keep happy, and your joy and you shall form an invincible host against difficulties.","Helen Keller","new-year's,happiness" +"What I'm looking for is not out there, it is in me.","Helen Keller","self,truth" +"There is no limit to the amount of good you can do if you don't care who gets the credit.","Ronald Reagan","accomplishment,achievement,inspirational,misattributed,modesty,recognition" +"I was married by a judge. I should have asked for a jury.","Groucho Marx","humor,marriage" +"Even on the most solemn occasions I got away without wearing socks and hid that lack of civilization in high boots","Albert Einstein","fashion,humor" +"We dance round in a ring and suppose,But the Secret sits in the middle and knows.","Robert Frost","inspirational" +"The most beautiful thing we can experience is the mysterious. It is the source of all true art and all science. He to whom this emotion is a stranger, who can no longer pause to wonder and stand rapt in awe, is as good as dead: his eyes are closed.","Albert Einstein","art,awe,einstein,emotion,eyes,life,mysterious,reality,science,the-mysterious,truth,vision" +"The ideals which have always shone before me and filled me with joy are goodness, beauty, and truth.","Albert Einstein","beauty,ideas,kindness,truth" +"The arc of the moral universe is long, but it bends towards justice.","Martin Luther King Jr.","inspirational,justice,mlk" +"If I cannot do great things, I can do small things in a great way","Martin Luther King Jr.","excellence,success" +"You don't need anybody to tell you who you are or what you are. You are what you are!","John Lennon","be-yourself,inspirational,self-awareness,self-determination" +"The word 'God' is for me nothing more than the expression and product of human weaknesses, the Bible a collection of honorable, but still primitive legends which are nevertheless pretty childish. No interpretation, no matter how subtle, can (for me) change this.","Albert Einstein","bible,god,religion" +"You can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future.","Steve Jobs","design,inspirational,life-lessons" +"God is subtle but he is not malicious.","Albert Einstein","inspirational" +"To write well, express yourself like the common people, but think like a wise man.","Aristotle","inspirational,philosophy,writing" +"An individual has not started living until he can rise above the narrow confines of his individualistic concerns to the broader concerns of all humanity.","Martin Luther King Jr.","inspirational" +"The person who deserves most pity is a lonesome one on a rainy day who doesn't know how to read.","Benjamin Franklin","books,illiteracy,literature,pity,reading,words" +"No, this trick won't work... How on earth are you ever going to explain in terms of chemistry and physics so important a biological phenomenon as first love?","Albert Einstein","chemistry,first-love,love,physics" +"Homer has taught all other poets the art of telling lies skillfully.","Aristotle","homer,poets,lies" +"Let us live so that when we come to die even the undertaker will be sorry.","Mark Twain","inspirational" +"Next time I see you, remind me not to talk to you.","Groucho Marx","gibe,humor,insult" +"What is Man? Man is a noisome bacillus whom Our Heavenly Father created because he was disappointed in the monkey.","Mark Twain","creation,evolution,humor,mankind" +"Information is not knowledge.","Albert Einstein","information,knowledge" +"Literature is my Utopia","Helen Keller","books,literature,reading,words" +"I have looked in the mirror every morning and asked myself: "If today were the last day of my life, would I want to do what I am about to do today?"And whenever the answer has been "No"for too many days in a row, I know I need to change something.","Steve Jobs","change,life" +"We could never learn to be brave and patient if there were only joy in the world","Helen Keller","adversity,inspirational,personal-growth" +"Challenges are gifts that force us to search for a new center of gravity. Don't fight them. Just find a new way to stand.","Oprah Winfrey","philosophy" +"In the unlikely story that is America, there has never been anything false about hope.","Barack Obama","america,history,hope" +"Possessions, outward success, publicity, luxury - to me these have always been contemptible. I believe that a simple and unassuming manner of life is best for everyone, best for both the body and the mind.","Albert Einstein","belongings,simplicity,success,values" +"I believe that every single event in life happens in an opportunity to choose love over fear.","Oprah Winfrey","fear,love,opportunity" +"I'm not the smartest fellow in the world, but I can sure pick smart colleagues.","Franklin D. Roosevelt","funny,humor,politics,usa" +"Writing is the only thing that when I do it, I don't feel I should be doing something else.","Gloria Steinem","writing" +"Forget injuries, never forget kindnesses.","Confucius","life,principles" +"Happiness does not come from without, it comes from within","Helen Keller","happiness,life,love" +"A bend in the road is not the end of the road…Unless you fail to make the turn.","Helen Keller","change,life,perseverance,risk" +"Dancers are the athletes of God.","Albert Einstein","albert,life" +"You can never be wise and be in love at the same time.","Bob Dylan","bob-dylan,love" +"Room service? Send up a larger room."[A Night at the Opera]","Groucho Marx","hotel-rooms,hotels,humor,room-service" +"Under certain circumstances, profanity provides a relief denied even to prayer."[Mark Twain, a Biography]","Mark Twain","humor,prayer,profanity,relief,you-ll-completely-understand-why" +"Wit is educated insolence.","Aristotle","definitions,humor" +"Life isn't worth living, unless it is lived for someone else.","Albert Einstein","einstein,life" +"Everything is determined, the beginning as well as the end, by forces over which we have no control. It is determined for the insect, as well as for the star. Human beings, vegetables, or cosmic dust, we all dance to a mysterious tune, intoned in the distance by an invisible piper.","Albert Einstein","destiny,einstein,inspirational" +"Early to bed and early to rise makes a man healthy, wealthy, and wise.","Benjamin Franklin","inspirational" +"It is, in fact, nothing short of a miracle that the modern methods of instruction have not yet entirely strangled the holy curiosity of inquiry; for this delicate little plant, aside from stimulation, stands mainly in need of freedom. Without this it goes to wrack and ruin without fail.","Albert Einstein","creativity,education,learning,regimentation" +"Everything has its wonders, even darkness and silence, and I learn, whatever state I may be in, therein to be content","Helen Keller","life" +"I want to do it because I want to do it. Women must try to do things as men have tried. When they fail, their failure must be but a challenge to others.","Amelia Earhart","failure,success,women,work" +"I count him braver who overcomes his desires than him who overcomes his enemies.","Aristotle","ethics,philosophy,self-discovery" +"The reports of my death are greatly exaggerated.","Mark Twain","death,humor" +"Let us not seek to satisfy our thirst for freedom by drinking from the cup of bitterness and hatred.","Martin Luther King Jr.","communism,democracy,freedom,liberation,love,marxism,peace,radicalism,socialism,theology" +"A successful book is not made of what is in it, but what is left out of it.","Mark Twain","books,humor,on-writing,wit,writing" +"We ran as if to meet the moon.","Robert Frost","moon,poetry,robert-frost" +"We all know that Art is not truth. Art is a lie that makes us realize truth at least the truth that is given us to understand. The artist must know the manner whereby to convince others of the truthfulness of his lies.","Pablo Picasso","art,lies,truth" +"When I was younger, I could remember anything, whether it had happened or not; but my faculties are decaying now and soon I shall be so I cannot remember any but the things that never happened. It is sad to go to pieces like this but we all have to do it.","Mark Twain","aging,humor" +"I'm inspired by the people I meet in my travels--hearing their stories, seeing the hardships they overcome, their fundamental optimism and decency. I'm inspired by the love people have for their children. And I'm inspired by my own children, how full they make my heart. They make me want to work to make the world a little bit better. And they make me want to be a better man.","Barack Obama","family,hope,service" +"You must expect great things of yourself before you can do them.","Michael Jordan","inspirational,success" +"Many persons have a wrong idea of what constitutes true happiness. It is not attained through self-gratification but through fidelity to a worthy purpose.","Helen Keller","educator,inspirational" +"The way a crowShook down on meThe dust of snowFrom a hemlock treeHas given my heartA change of moodAnd saved some partOf a day I had rued.","Robert Frost","poetry" +"God is really only another artist. He invented the giraffe, the elephant and the cat. He has no real style, He just goes on trying other things.","Pablo Picasso","art,god" +"The thing the sixties did was to show us the possibilities and the responsibility that we all had. It wasn't the answer. It just gave us a glimpse of the possibility.","John Lennon","1960s,beatles,hope,possibility,responsibility" +"And were an epitaph to be my story I'd have a short one ready for my own. I would have written of me on my stone: I had a lover's quarrel with the world.","Robert Frost","life" +"When obstacles arise, you change your direction to reach your goal; you do not change your decision to get there.","Zig Ziglar","inspirational" +"Training is everything. The peach was once a bitter almond; cauliflower is nothing but cabbage with a college education.","Mark Twain","education,food" +"Love is like a virus. It can happen to anybody at any time.","Maya Angelou","love" +"Vision without execution is just hallucination.","Henry Ford","dreams,success" +"My life isn’t theories and formulae. It’s part instinct, part common sense. Logic is as good a word as any, and I’ve absorbed what logic I have from everything and everyone… from my mother, from training as a ballet dancer, from Vogue magazine, from the laws of life and health and nature.","Audrey Hepburn","audrey-hepburn,inspiration,life" +"Any customer can have a car painted any colour that he wants so long as it is black.","Henry Ford","black,customer,humor,model-t" +"Play is the highest form of research.","Albert Einstein","childhood,education" +"We can't become what we need to be by remaining what we are.","Oprah Winfrey","life" +"It is by the goodness of god that in our country we have those 3 unspeakably precious things: freedom of speech, freedom of conscience, and the prudence never to practice either of them.","Mark Twain","humor,politics" +"To those who are given much, much is expected.","Maya Angelou","inspirational-quotes" +"Books can not be killed by fire. People die, but books never die. No man and no force can abolish memory... In this war, we know, books are weapons. And it is a part of your dedication always to make them weapons for man's freedom.","Franklin D. Roosevelt","book-burning,books,censorship,freedom" +"Relationships are like Rome -- difficult to start out, incredible during the prosperity of the 'golden age', and unbearable during the fall. Then, a new kingdom will come along and the whole process will repeat itself until you come across a kingdom like Egypt... that thrives, and continues to flourish. This kingdom will become your best friend, your soul mate, and your love.","Helen Keller","love,relationship" +"Our society is run by insane people for insane objectives","John Lennon","truth" +"I know in my heart that man is good, that what is right will always eventually triumph, and there is purpose and worth to each and every life.","Ronald Reagan","inspirational" +"Before I speak, I have something important to say.","Groucho Marx","absurdist,humor" +"If you lose hope, somehow you lose the vitality that keeps moving, you lose that courage to be, that quality that helps you go on in spite of it all. And so today I still have a dream.","Martin Luther King Jr.","hope" +"Time flows away like the water in the river.","Confucius","wisdom" +"Self-esteem comes from being able to define the world in your own terms and refusing to abide by the judgments of others.","Oprah Winfrey","inspirational" +"An empty stomach is not a good political adviser.","Albert Einstein","humor,hunger,poverty" +"A foolish faith in authority is the worst enemy of truth.","Albert Einstein","dissent,independent-thought,science" +"My life has been one great big joke,A dance that's walked,A song that's spoke,I laugh so hard I almost choke,When I think about myself.","Maya Angelou","life" +"When red-headed people are above a certain social grade their hair is auburn.","Mark Twain","class,elitism,humor,redheads" +"A poem begins with a lump in the throat; a homesickness or a love sickness. It is a reaching-out toward expression; an effort to find fulfillment. A complete poem is one where an emotion has found its thought and the thought has found words.","Robert Frost","poetry,writing" +"Education breeds confidence. Confidence breeds hope. Hope breeds peace.","Confucius","education" +"Poetry puts starch in your backbone so you can stand, so you can compose your life.","Maya Angelou","poetry" +"It frightens me, the awful truth, of how sweet life can be...","Bob Dylan","fear,life,truth" +"Have you ever felt the longing for someone you could admire? For something, not to look down at, but up to?","Ayn Rand","achievement,admiration,atlas-shrugged,inspirational,love,objectivism" +"Politics is not a bad profession. If you succeed there are many rewards, if you disgrace yourself you can always write a book.","Ronald Reagan","humor,politics" +"Shall I teach you what knowledge?When you know a thing, say that you know it;when you do not know a thing,admit that you do not know it.That is knowledge","Confucius","knowledge" +"My best friend is the man who in wishing me well wishes it for my sake.","Aristotle","best,friend,wishes" +"Make today worth remembering.","Zig Ziglar","inspirational,motivational" +"I've heard that hard work never killed anyone, but I say why take the chance?","Ronald Reagan","humor,laziness,sloth,work" +"I was feeling insecure you might not love me anymore","John Lennon","insecure,insecurity,love" +"Democracy cannot succeed unless those who express their choice are prepared to choose wisely. The real safeguard of democracy, therefore, is education.","Franklin D. Roosevelt","education,government,political-philosophy,public-duty,voting" +"Life is very short, and there's no time for fussing and fighting my friends","John Lennon","inspirational" +"Happiness is not in the mere possession of money; it lies in the joy of achievement, in the thrill of creative effort.","Franklin D. Roosevelt","achievement,happiness,wealth,wisdom" +"Doing the best at this moment puts you in the best place for the mext moment","Oprah Winfrey","inspirational,life,success" +"The lack of money is the root of all evil.","Mark Twain","humor" +"The human spirit must prevail over technology.","Albert Einstein","humanity,science" +"Status quo, you know, is Latin for 'the mess we're in'.","Ronald Reagan","inspirational,latin,politics" +"If we bear all this suffering and if there are still Jews left, when it is over, then Jews, instead of being doomed, will be held up as an example.","Anne Frank","holocaust,inspirational,judaism" +"Teaching should be such that what is offered is perceived as a valuable gift and not as hard duty. Never regard study as duty but as the enviable opportunity to learn to know the liberating influence of beauty in the realm of the spirit for your own personal joy and to the profit of the community to which your later work belongs.","Albert Einstein","education" +"We'll meet at the theater tonight. I'll hold your seat 'til you get there. Once you get there; you're on your own.","Groucho Marx","humor" +"It is harder to crack prejudice than an atom.","Albert Einstein","humor,inspirational,science" +"I can accept anything, except what seems to be the easiest for most people: the half-way, the almost, the just-about, the in-between.","Ayn Rand","compromise,philosophy" +"A hospital bed is a parked taxi with the meter running.","Groucho Marx","funny" +"The best and most beautiful things in the world cannot be seen or even touched - they must be felt with the heart.","Helen Keller","best,beautiful,heart" +"No amount of experimentation can ever prove me right; a single experiment can prove me wrong.","Albert Einstein","science" +"I don't try to imagine a personal God; it suffices to stand in awe at the structure of the world, insofar as it allows our inadequate senses to appreciate it.","Albert Einstein","atheism,atheist,god,religion" +"Happiness is a state of activity.","Aristotle","activity,happiness" +"Although I am a typical loner in my daily life, my awareness of belonging to the invisible community of those who strive for truth, beauty, and justice has prevented me from feelings of isolation.","Albert Einstein","albert-einstein,einstein,inspirational,loner" +"We may have all come on different ships, but we're in the same boat now.","Martin Luther King Jr.","cultural,inspirational,spiritual" +"I believe that God is in me as the sun is in the colour and fragrance of a flower - the Light in my darkness, the Voice in my silence.","Helen Keller","inspirational" +"You see, wire telegraph is a kind of a very, very long cat. You pull his tail in New York and his head is meowing in Los Angeles. Do you understand this? And radio operates exactly the same way: you send signals here, they receive them there. The only difference is that there is no cat.","Albert Einstein","analogy,humor,science" +"Familiarity breeds contempt and children.","Mark Twain","humor" +"Learning is an ornament in prosperity, a refuge in adversity, and a provision in old age.","Aristotle","adversity,education,learning,old-age,prosperity" +"A lot of people have gone further than they thought they could because someone else thought they could","Zig Ziglar","inspirational" +"Life is a succesion of lessons which must be lived to be understood.","Helen Keller","lessons,life" +"There are no traffic jams on the extra mile.","Zig Ziglar","inspirational" +"You're gonna have to serve somebody; well, it may be the devil, or it may be the Lord, but you're gonna have to serve somebody...","Bob Dylan","christianity,faith,god" +"Small is the number of them that see with their own eyes and feel with their own hearts.","Albert Einstein","heart,inspirational" +"Act the way you'd like to be and soon you'll be the way you'd like to act.","Bob Dylan","action,change,improvement,misattributed-to-leonard-cohen,motivational,success" +"It may be true that the law cannot make a man love me, but it can stop him from lynching me, and I think that's pretty important.","Martin Luther King Jr.","law,life,lynchings" +"Happiness depends more on the inward disposition of mind than on outward circumstances.","Benjamin Franklin","inspirational" +"A big leather-bound volume makes an ideal razorstrap. A thing book is useful to stick under a table with a broken caster to steady it. A large, flat atlas can be used to cover a window with a broken pane. And a thick, old-fashioned heavy book with a clasp is the finest thing in the world to throw at a noisy cat.","Mark Twain","books,humor" +"No man's life, liberty, or property are safe while the legislature is in session.","Mark Twain","government,humor,politics" +"Don't say the old lady screamed. Bring her on and let her scream.","Mark Twain","on-writing,writing" +"Until justice rolls down like water and righteousness like a mighty stream.","Martin Luther King Jr.","america,freedom,human-rights,inspirational,justice,peace,pride,righteousness,stream,water" +"Four things to learn in life: To think clearly without hurry or confusion; To love everybody sincerely; To act in everything with the highest motives; To trust God unhesitatingly.","Helen Keller","inspirational" +"Strange is our situation here on Earth. Each of us comes for a short visit, not knowing why, yet sometimes seeming to divine a purpose. From the standpoint of daily life, however, there is one thing we do know: that man is here for the sake of other men - above all for those upon whose smiles and well-being our own happiness depends.","Albert Einstein","inspirational-quotes" +"Everything that is really great and inspiring is created by the individual who can labor in freedom.","Albert Einstein","mind" +"Courage is the price that life exacts for granting peace.","Amelia Earhart","bravery,courage,life,peace" +"If a man could have half of his wishes, he would double his troubles.","Benjamin Franklin","wisdom" +"In religion and politics people’s beliefs and convictions are in almost every case gotten at second-hand, and without examination, from authorities who have not themselves examined the questions at issue but have taken them at second-hand from other non-examiners, whose opinions about them were not worth a brass farthing.","Mark Twain","beliefs,politics,religion" +"What I’ve realized is that life doesn’t count for much unless you’re willing to do your small part to leave our children — all of our children — a better world. Any fool can have a child. That doesn’t make you a father. It’s the courage to raise a child that makes you a father.","Barack Obama","inspirational" +"A friend to all is a friend to none.","Aristotle","friend,none" +"It usually takes me two or three days to prepare an impromptu speech.","Mark Twain","humor,preparedness" +"I define nothing. Not beauty, not patriotism. I take each thing as it is, without prior rules about what it should be.","Bob Dylan","acceptance,bob,define,dylan,life" +"It does not matter how long you live, but how well you do it.","Martin Luther King Jr.","inspirational" +"It occurred to me by intuition, and music was the driving force behind that intuition. My discovery was the result of musical perception.","Albert Einstein","inspirational" +"You look at yourself and you accept yourself for who you are, and once you accept yourself for who you are you become a better person.","Oprah Winfrey","inspirational" +"Lots of people want to ride with you in the limo, but what you want is someone who will take the bus with you when the limo breaks down.","Oprah Winfrey","ride,bus,breaks" +"Who is wise? He that learns from everyone. Who is powerful? He that governs his passions. Who is rich? He that is content. Who is that? Nobody.","Benjamin Franklin","philosophy,wisdom" +"Paying alimony is like feeding hay to a dead horse.","Groucho Marx","divorce,funny" +"Occasionally in life there are those moments of unutterable fulfillment which cannot be completely explained by those symbols called words. Their meanings can only be articulated by the inaudible language of the heart.","Martin Luther King Jr.","ecstasy,euphoria,fulfillment,life,power-of-words" +"Learning without thought is labor lost; thought without learning is perilous.","Confucius","education,learning,thinking" +"I believe that Gandhi’s views were the most enlightened of all the political men in our time. We should strive to do things in his spirit: not to use violence in fighting for our cause, but by non-participation in anything you believe is evil.","Albert Einstein","causes,corporations,gandhi,truth,violence" +"The game of basketball has been everything to me. My place of refuge, place I've always gone where I needed comfort and peace. It's been the site of intense pain and the most intense feelings of joy and satisfaction. It's a relationship that has evolved over time, given me the greatest respect and love for the game.","Michael Jordan","sports,time,respect" +"I hate girls that giggle all the time... You hate any girl that David looks at.","Audrey Hepburn","humor" +"I believe in pink. I believe that laughing is the best calorie burner. I believe in kissing, kissing a lot. I believe in being strong when everything seems to be going wrong. I believe that happy girls are the prettiest girls. I believe that tomorrow is another day and I believe in miracles.","Audrey Hepburn","best,kissing,happy" +"You say I started out with practically nothing, but that isn't correct. We all start with all there is, it's how we use it that makes things possible.","Henry Ford","inspiration" +"Anyone who doesn't take truth seriously in small matters cannot be trusted in large ones either.","Albert Einstein","albert-einstein,truth" +"I wasn't saying whatever they're saying I was saying. I'm sorry I said it really. I never meant it to be a lousy anti-religious thing. I apologize if that will make you happy. I still don't know quite what I've done. I've tried to tell you what I did do but if you want me to apologize, if that will make you happy, then OK, I'm sorry.","John Lennon","apology,beatles,humor,humour,jesus,religion" +"Success is the doing, not the getting; in the trying, not the triumph. Success is a personal standard, reaching for the highest that is in us, becoming all that we can be. If we do our best, we are a success.","Zig Ziglar","doing,success" +"I have a great respect for incremental improvement, and I've done that sort of thing in my life, but I've always been attracted to the more revolutionary changes. I don't know why. Because they're harder. They're much more stressful emotionally. And you usually go through a period where everybody tells you that you've completely failed.","Steve Jobs","respect,great,changes" +"A bank is a place where they lend you an umbrella in fair weather and ask for it back when it begins to rain.","Robert Frost","humor,poetry" +"A society's competitive advantage will come not from how well its schools teach the multiplication and periodic tables, but from how well they stimulate imagination and creativity.","Albert Einstein","science" +"There are only a few notes. Just variations on a theme.","John Lennon","life,music" +"A man is accepted into a church for what he believes and he is turned out for what he knows.","Mark Twain","religion" +"It is this belief in a power larger than myself and other than myself which allows me to venture into the unknown and even the unknowable.","Maya Angelou","faith,inspirational" +"A man is never more truthful than when he acknowledges himself a liar.","Mark Twain","truth" +"What a wee little part of a person's life are his acts and his words! His real life is led in his head, and is known to none but himself.","Mark Twain","words,head,himself" +"Your success and happiness lie in you.","Helen Keller","happiness,inspirational-quotes,success" +"Ah, when to the heart of man Was it ever less than a treason To go with the drift of things, To yield with a grace to reason, And bow and accept the end Of a love or a season?","Robert Frost","love,poetry" +"Never allow the fear of striking out keep you from playing the game!","Babe Ruth","babe-ruth,baseball,cinderella-story,inspiration,motivation,quote,success" +"The whole secret of a successful life is to find out what is one's destiny to do, and then do it.","Henry Ford","success" +"The future doesn't belong to the light-hearted. It belongs to the brave.","Ronald Reagan","bravery,inspirational,reagan" +"An ounce of prevention is worth a pound of cure.","Benjamin Franklin","preparation,prevention,proverb,wisdom" +"Wishing to be friends is quick work, but friendship is a slow ripening fruit.","Aristotle","work,fruit,slow" +"One of the strongest motives that lead men to art and science is escape from everyday life with its painful crudity and hopeless dreariness, from the fetters of one's own ever-shifting desires. A finely tempered nature longs to escape from the personal life into the world of objective perception and thought.","Albert Einstein","art,life,science" +"Making a decision to write was a lot like deciding to jump into a frozen lake.","Maya Angelou","writing" +"America is too great for small dreams.","Ronald Reagan","inspirational" +"What I try to do is write. I may write for two weeks ‘the cat sat on the mat, that is that, not a rat,’.... And it might be just the most boring and awful stuff. But I try. When I’m writing, I write. And then it’s as if the muse is convinced that I’m serious and says, ‘Okay. Okay. I’ll come.","Maya Angelou","writing" +"And the only way to do great work is to love what you do.... Don't settle","Steve Jobs","inspirational" +"The Master said, “A true teacher is one who, keeping the past alive, is also able to understand the present.”(Analects 2.11)","Confucius","history,teachers,wisdom" +"I do not want the peace which passeth understanding, I want the understanding which bringeth peace.","Helen Keller","education,ispirational,learning,understanding" +"If books are not good company, where shall I find it?","Mark Twain","books" +"Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose.","Steve Jobs","death,hope,inspirational,life,motivatonal" +"I failed to communicate, that's why I chose to leave","Bob Dylan","life" +"What affects one in a major way, affects all in a minor way.","Martin Luther King Jr.","inspirational" +"Poetry is a way of taking life by the throat.","Robert Frost","life,poetry" +"…Christianity will go. It will vanish and shrink. I don't know what will go first, rock 'n' roll or Christianity. We're more popular than Jesus now. Jesus was all right, but his disciples were thick and ordinary. It's them twisting it that ruins it for me.","John Lennon","beatles,christianity,popular-culture,religion" +"Great spirits have always encountered opposition from mediocre minds. The mediocre mind is incapable of understanding the man who refuses to bow blindly to conventional prejudices and chooses instead to express his opinions courageously and honestly.","Albert Einstein","inspirational,opposition,wisdom" +"You better start swimming, or you'll sink like a stone. Because the Time's they are a-changing.","Bob Dylan","life,music" +"Mr. Right is coming, but he's in Africa and he's walking.","Oprah Winfrey","funny" +"That's what you want to do? Then nothing beats a trial but a failure. Give it everything you've got. I've told you many times, 'Cant do is like Dont Care.' Neither of them have a home.","Maya Angelou","inspirational" +"We are faced with the fact, my friends, that tomorrow is today. Procrastination is still the thief of time. Over the bleached bones and jumbled residues of numerous civilizations are written the pathetic words ‘Too Late’.","Martin Luther King Jr.","inspirational,political" +"I want all my senses engaged. Let me absorb the world's variety and uniqueness.","Maya Angelou","inspirational" +"Education: that which reveals to the wise, and conceals from the stupid, the vast limits of their knowledge.","Mark Twain","education" +"It is more shameful to distrust our friends than to be deceived by them.","Confucius","deceived,distrust,shameful" +"Don't be distracted by criticism. Remember ~ the only taste of success some people have is when they take a bite out of you.","Zig Ziglar","believe,inspiration,motivational,zig-ziglar" +"Freedom means the supremacy of human rights everywhere. Our support goes to those who struggle to gain those rights and keep them. Our strength is our unity of purpose. To that high concept there can be no end save victory.","Franklin D. Roosevelt","human-rights,truth" +"Poetry is finer and more philosophical than history; for poetry expresses the universal, and history only the particular.","Aristotle","poetry" +"No lake so still but it has its wave.No circle so perfect but that it has its blur.I would change things for you if I could; As I can't you must take them as they are.","Confucius","inspirational,life,philosophy" +"Like anybody, I would like to have a long life. Longevity has its place. But I'm not concerned about that now. I just want to do God's will.","Martin Luther King Jr.","foreboding,life" +"Rich People plan for three generationsPoor people plan for Saturday night","Gloria Steinem","class-distinction,inspirational" +"Never contract friendship with a man that is not better than thyself.","Confucius","contract,thyself" +"Each morning when I open my eyes I say to myself: I, not events, have the power to make me happy or unhappy today.","Groucho Marx","happiness,inspirational" +"The significant problems we have cannot be solved at the same level of thinking with which we created them.","Albert Einstein","inspirational,problems,science" +"I am overwhelmed by the grace and persistence of my people.","Maya Angelou","family,inspirational" +"To plant a garden is to believe in tomorrow.","Audrey Hepburn","hope,inspirational" +"youth is easily deceived because it is quick to hope.","Aristotle","deceit,gullibility,hope,wisdom,youth" +"As our circle of knowledge expands, so does the circumference of darkness surrounding it.","Albert Einstein","knowledge" +"It doesn't matter who you are, where you come from. The ability to triumph begins with you - always.","Oprah Winfrey","inspirational" +"Knowledge is merely brilliance in organization of ideas and not wisdom. The truly wise person goes beyond knowledge.","Confucius","wisdom" +"In the view of such harmony in the cosmos which I, with my limited human mind, am able to recognize, there are yet people who says there is no God. But what makes me really angry is that they quote me for support of such views. (The Expanded Quotable Einstein, Princeton University, page 214)","Albert Einstein","creation,god" +"The Truth is found when men (and Women) are free to pursue it.","Franklin D. Roosevelt","freedom,liberty,truth" +"Don't be trapped by dogma — which is living with the results of other people's thinking.","Steve Jobs","life,thinking" +"When You Cease To Exist, Then Who Will You Blame?","Bob Dylan","inspirational" +"A man's ethical behaviour should be based effectually on sympathy, education, and social ties and needs; no religious basis is necessary. Man would indeed be in a poor way if he had to be restrained by fear of punishment and hope of reward after death.","Albert Einstein","education,ethics,morality,needs,religion,sociality,sympathy" +"Segregation shaped me; education liberated me.","Maya Angelou","education,inspirational,learning,race" +"The gods too are fond of a joke.","Aristotle","god,humor,jokes,religion" +"A war of ideas can no more be won without books than a naval war can be won without ships. Books, like ships, have the toughest armor, the longest cruising range, and mount the most powerful guns.","Franklin D. Roosevelt","boats,books,ideas,sailing,ships" +"Take one cup of love, two cups of loyalty, three cups of forgiveness, four quarts of faith and one barrel of laughter. Take love and loyalty and mix them thoroughly with faith; blend with tenderness, kindness and understanding. Add friendship and hope. Sprinkle abundantly with laughter. Bake it with sunshine. Wrap it regularly with lots of hugs. Serve generous helpings daily.","Zig Ziglar","happiness,marriage" +"If I could give you information of my life it would be to show how a woman of very ordinary ability has been led by God in strange and unaccustomed paths to do in His service what He has done in her. And if I could tell you all, you would see how God has done all, and I nothing. I have worked hard, very hard, that is all; and I have never refused God anything.","Florence Nightingale","god,service,work" +"Life is about becoming more of who you really are....","Oprah Winfrey","inspirational" +"If God would have wanted us to live in a permissive society He would have given us Ten Suggestions and not Ten Commandments.","Zig Ziglar","religion" +"Go as far as you can see and you will see further.","Zig Ziglar","inspirational,motivation,success" +"Without continual growth and progress, such words as improvement, achievement, and success have no meaning.","Benjamin Franklin","growth,progress,words" +"To avoid being mistaken for a sellout, I chose my friends carefully. The more politically active black students. The foreign students. The Chicanos. The Marxist professors and structural feminists and punk-rock performance poets.","Barack Obama","black,students,active" +"Anyone who fights for the future, lives in it today.","Ayn Rand","idealism,philosophy" +"My philosophy, in essence, is the concept of man as a heroic being, with his own happiness as the moral purpose of his life, with productive achievement as his noblest activity, and reason as his only absolute.","Ayn Rand","philosophy" +"A tyrant must put on the appearance of uncommon devotion to religion. Subjects are less apprehensive of illegal treatment from a ruler whom they consider god-fearing and pious. On the other hand, they do less easily move against him, believing that he has the gods on his side.","Aristotle","morality,politics,religion" +"Curiosity is more important than knowledge.","Albert Einstein","curiosity,knowledge" +"I said to my children, 'I'm going to work and do everything that I can do to see that you get a good education. I don't ever want you to forget that there are millions of God's children who will not and cannot get a good education, and I don't want you feeling that you are better than they are. For you will never be what you ought to be until they are what they ought to be.","Martin Luther King Jr.","altruism,education,potential,religion" +"God made a beauteous garden With lovely flowers strown,But one straight, narrow pathway That was not overgrown.And to this beauteous garden He brought mankind to live,And said "To you, my children, These lovely flowers I give.Prune ye my vines and fig trees, With care my flowers tend,But keep the pathway open Your home is at the end."God's Garden","Robert Frost","frost,gardens,god" +"Herodotus says, "Very few things happen at the right time, and the rest do not happen at all: the conscientious historian will correct these defects.","Mark Twain","creativity,historians,history,truth" +"You will find the key to success under the alarm clock.","Benjamin Franklin","success" +"Character cannot be developed in ease and quiet. Only through experience of trial and suffering can the soul be strengthened, ambition inspired, and success achieved.","Helen Keller","strength,experience" +"The happiness you feel is in direct proportion to the love you give.","Oprah Winfrey","happiness,life,love" +"If one tries to navigate unknown waters one runs the risk of shipwreck","Albert Einstein","wisdom" +"You teach people how to treat you.","Oprah Winfrey","inspirational,oprah" +"Nothing exists but you. And you are but a thought.","Mark Twain","atheism,inspirational" +"It's sad if people think that's (homemaking) a dull existance, [but] you can't just buy an apartment and furnish it and walk away. It's the flowers you choose, the music you play, the smile you have waiting. I want it to be gay and cheerful, a haven in this troubled world. I don't want my husband and children to come home and find a rattled woman. Our era is already rattled enough, isn't it?","Audrey Hepburn","homemaking,inspirational,motherhood" +"They say that patriotism is the last refuge to which a scoundrel clings steal a little and they throw you in jail. Steal a lot and then they make you king.","Bob Dylan","patriotism,scoundrels,truth,wisdom" +"The test of any good fiction is that you should care something for the characters; the good to succeed, the bad to fail. The trouble with most fiction is that you want them all to land in hell together, as quickly as possible.","Mark Twain","writing" +"Wit is the sudden marriage of ideas which before their union were not perceived to have any relation.","Mark Twain","cleverness,writing" +"Learn as if you were not reaching your goal and as though you were scared of missing it","Confucius","confucious,inspirational,learning,life" +"Walking with a friend in the dark is better than walking alone in the light.","Helen Keller","alone,dark,light" +"For dear me, why abandon a beliefMerely because it ceases to be true","Robert Frost","faith,truth" +"The way to wealth is as plain as the way to market. It depends chiefly on two words, industry and frugality: that is, waste neither time nor money, but make the best use of both. Without industry and frugality nothing will do, and with them everything.","Benjamin Franklin","advice-for-daily-living,enterprise,frugality,success" +"Without feelings of respect, what is there to distinguish men from beasts?","Confucius","philosophical,understanding,wisdom" +"One should never use exclamation points in writing. It is like laughing at your own joke.","Mark Twain","advice,clever,exclamation-point,writing" +"Combinatory play seems to be the essential feature in productive thought.","Albert Einstein","education,learning,play" +"Every form of happiness if one, every desire is driven by the same motor--by our love for a single value, for the highest potentiality of our own existence--and every achievement is an expression of it.","Ayn Rand","galt,objectivism,philosophy,taggart" +"Economic power is exercised by means of a positive, by offering men a reward, an incentive, a payment, a value; political power is exercised by means of a negative, by the threat of punishment, injury, imprisonment, destruction. The businessman's tool is values; the bureaucrat's tool is fear.","Ayn Rand","businessmen,capitalism,force,government,money,philosophy,profit" +"That which is impenetrable to us really exists. Behind the secrets of nature remains something subtle, intangible, and inexplicable. Veneration for this force beyond anything that we can comprehend is my religion.","Albert Einstein","religion" +"he who will not economize will have to agonize","Confucius","frugality,ignorance,knowledge,suffering,wisdom" +"Art is not the application of a canon of beauty but what the instinct and the brain can conceive beyond any canon. When we love a woman we don't start measuring her limbs.","Pablo Picasso","love,beauty,woman" +"The best way to see Faith is to shut the eye of Reason.","Benjamin Franklin","wisdom" +"To do more for the world than the world does for you - that is success.","Henry Ford","success" +"It makes no difference where you go, there you are. And it makes no difference what you have, there’s always more to want. Until you are happy with who you are, you will never be happy because of what you have.","Zig Ziglar","grateful,happiness" +"The right to search for the truth implies also a duty; one must not conceal any part of what one has recognized to be the truth.","Albert Einstein","truth" +"When you have faults, do not fear to abandon them.","Confucius","advice,life,success" +"I find relief from the questions only when I concede that I am not obliged to know everything. I remind myself it is sufficient to know what I know, and that what I know, may not always be true.","Maya Angelou","death,letter-to-my-daughter" +"I confess to wincing every so often at a poorly chosen word, a mangled sentence, an expression of emotion that seems indulgent or overly practiced. I have the urge to cut the book by fifty pages or so, possessed as I am with a keener appreciation for brevity.","Barack Obama","writing" +"He who speaks without modesty will find it difficult to make his words good.","Confucius","inspirational-quotes" +"An attempt to achieve the good by force is like an attempt to provide a man with a picture gallery at the price of cutting out his eyes.","Ayn Rand","force,good,philosophy" +"Listen. Pay attention. Treasure every moment.","Oprah Winfrey","wisdom" +"It is a very grave mistake to think that the enjoyment of seeing and searching can be promoted by means of coercion and a sense of duty. To the contrary, I believe it would be possible to rob even a healthy beast of prey of its voraciousness, if it were possible, with the aid of a whip, to force the beast to devour continuously, even when not hungry.","Albert Einstein","education,learning" +"Deux choses sont infinies : l’Univers et la bêtise humaine. Mais, en ce qui concerne l’Univers, je n’en ai pas encore acquis la certitude absolue.","Albert Einstein","bêtise-humaine,einstein,french,humour,infini,philosophie,science,universe" +"La vie est une aventure audacieuse ou alors elle n'est rien.","Helen Keller","aventure,inspiration,vie" +"All pain is the same.","Oprah Winfrey","pain,wisdom" +"I couldn't tell fact from fiction,Or if the dream was trueMy only sure predictionIn this world was you.I'd touch your features inchly. Beard love and dared the cost, The sented spiel reeled me unreal And I found my senses lost.","Maya Angelou","inspiration,poetry" +"It is this mythical, or rather symbolic, content of the religious traditions which is likely to come into conflict with science. This occurs whenever this religious stock of ideas contains dogmatically fixed statements on subjects which belong in the domain of science.","Albert Einstein","religion,science" +"Try and penetrate with our limited means the secrets of nature and you will find that, behind all the descernible laws and connections, there remains something subtle, intangible and inexplicable. Veneration for this force beyond anything that we can comprehend is my religion. To that extent I am, in fact, religious.","Albert Einstein","science,spirituality" +"We have not the reverent feeling for the rainbow that the savage has, because we know how it is made. We have lost as much as we gained by prying into that matter.","Mark Twain","awe,science" +"If you're silent for a long time, people just arrive in your mind.","Alice Walker","characters,mind,people,silence,silent,writers,writing" +"I speak to the Black experience, but I am always talking about the human condition--about what we can endure, dream, fail at and survive.","Maya Angelou","writing" +"My best friend is the one who brings out the best in me.","Henry Ford","best,friend,brings" +"An inventor is a man who asks 'Why?' of the universe and lets nothing stand between the answer and his mind.","Ayn Rand","philosophy" +"But yield who will to their separation, My object in living is to uniteMy avocation and my vocationAs my two eyes make one in sight.","Robert Frost","goals,inspiration" +"A moment or an eternity—did it matter? Life, undefeated, existed and could exist.","Ayn Rand","life,philosophy" +"Faith is taking the first step even when you don't see the whole staircase.","Martin Luther King Jr.","faith" +"Oh juventud nunca dejes de pensar...","Albert Einstein","science" +"To study and constantly, is this not a pleasure? To have friends come from far away places, is this not a joy? If people do not recognize your worth, but this does not worry you, are you not a true gentleman?","Confucius","good-things,inspiration,life" +"In any compromise between food and poison, it is only death that can win. In any compromise between good and evil, it is only evil that can profit.","Ayn Rand","evil,good,philosophy" +"One more thing...","Steve Jobs","inspiration" +"Man is here for the sake of other men - above all for those upon whose smiles and well-being our own happiness depends.","Albert Einstein","happiness,purpose" +"And now I see the face of god, and I raise this god over the earth, this god whom men have sought since men came into being, this god who will grant them joy and peace and pride. This god, this one word: 'I.","Ayn Rand","individualism,philosophy" +"Definitions are the guardians of rationality, the first line of defense against the chaos of mental disintegration.","Ayn Rand","epistemology,philosophy,reason" +"The spread of evil is the symptom of a vacuum. Whenever evil wins, it is only by default: by the moral failure of those who evade the fact that there can be no compromise on basic principles.","Ayn Rand","evil,philosophy" +"A culture is made — or destroyed — by its articulate voices.","Ayn Rand","philosophy" +"The doorstep to the temple of wisdom is a knowledge of our own ignorance.","Benjamin Franklin","knowledge" +"First of all, let me assert my firm belief that the only thing we have to fear is fear itself - nameless, unreasoning, unjustified terror which paralyzes needed efforts to convert retreat into advance.","Franklin D. Roosevelt","fear,inspiration" +"Aristotle may be regarded as the cultural barometer of Western history. Whenever his influence dominated the scene, it paved the way for one of history's brilliant eras; whenever it fell, so did mankind.","Ayn Rand","aristotle,philosophy,reason" +"It is the kindness to take in a stranger when the levees break; the selflessness of workers who would rather cut their hours than see a friend lose their job which sees us through our darkest hours. It is the firefighter's courage to storm a stairway filled with smoke, but also a parent's willingness to nurture a child, that finally decides our fate.","Barack Obama","america,inauguration,inspiration" +"One today is worth two tomorrows.","Benjamin Franklin","today,worth,tomorrows" +"Your success and happiness lies in you. Resolve to keep happy, and your joy and you shall form an invicible host against difficulties.","Helen Keller","happiness,helen-keller,inspirational-life,life,success" +"But I don't know how to fight. All I know how to do is stay alive.","Alice Walker","faith,life,sad,western" +"I have an unshaken conviction that democracy can never be undermined if we maintain our library resources and a national intelligence capable of utilizing them."[Letter to Herbert Putnam; in: Waters, Edward N.: Herbert Putnam: the tallest little man in the world; Quarterly Journal of the Library of Congress 33:2 (April 1976), p. 171]","Franklin D. Roosevelt","democracy,education,libraries" +"Some people get an education without going to college. The rest get it after they get out.","Mark Twain","college,education" +"Whatever their future, at the dawn of their lives, men seek a noble vision of man's nature and of life's potential.","Ayn Rand","idealism,philosophy" +"Contrary to the ecologists, nature does not stand still and does not maintain the kind of equilibrium that guarantees the survival of any particular species - least of all the survival of her greatest and most fragile product: man.","Ayn Rand","environmentalism,man,philosophy" +"Games lubricate the body and mind.","Benjamin Franklin","body,games,invigorate,lubricate,mind,refresh,renew,replenish" +"In scientific thinking are always present elements of poetry. Science and music requires a thought homogeneous.","Albert Einstein","music,poetry,science" +"I would not think that philosophy and reason themselves will be man's guide in the foreseeable future; however, they will remain the most beautiful sanctuary they have always been for the select few.","Albert Einstein","philosophy,thought" +"Man is an end in himself.","Ayn Rand","individualism,life,objectivism,philosophy,success" +"If a man has not discovered something that he will die for, he isn't fit to live","Martin Luther King Jr.","inspirational-quotes" +"Fear is the Fatal killer of Desire.","Zig Ziglar","fear,inspiration,iuindia-com,marketing,motivational,rohitdaga" +"Nor is there wanting in the pressSome spirit to stand simply forth,Heroic in it nakedness,Against the uttermost of earth.The tale of earth's unhonored thingsSounds nobler there than 'neath the sun;And the mind whirls and the heart sings,And a shout greets the daring one.","Robert Frost","life-quotes,poetry,poets,quotes,robert-frost" +"Joy is the holy fire that keeps our purpose warm and our intelligence aglow.","Helen Keller","happiness,joy,purpose" +"Try not to become a person of success, but rather try to become a person of value.","Albert Einstein","success" +"People often say that motivation doesn't last. Well, neither does bathing - that's why we recommend it daily.","Zig Ziglar","daily,last,bathing" +"Find a beautiful piece of art. If you fall in love with Van Gogh or Matisse or John Oliver Killens, or if you fall love with the music of Coltrane, the music of Aretha Franklin, or the music of Chopin - find some beautiful art and admire it, and realize that that was created by human beings just like you, no more human, no less.","Maya Angelou","love,music,beautiful" +"The female is, as it were, a mutilated male, and the catamenia are semen, only not pure; for there is only one thing they have not in them, the principle of soul.","Aristotle","female,male,mutilated,soul" +"When I lose the sense of motivation and the sense to prove something as a basketball player, it's time for me to move away from the game.","Michael Jordan","time,basketball,game" +"The monotony and solitude of a quiet life stimulates the creative mind.","Albert Einstein","creative,solitude,quiet" +"Wenn du weißt, behaupte, dass du es weißt. Und wenn du etwas nicht weißt, gib zu, dass du es nicht weißt. Das ist Wissen.","Confucius","knowledge,wisdom" +"Let it be told to the future world that in the depth of winter, when nothing but hope and virtue could survive, that the city and the country, alarmed at one common danger, came forth to meet it.","Barack Obama","america,inauguration,inspiration" +"We will restore science to its rightful place and wield technology's wonders to raise health care's quality and lower its cost.","Barack Obama","inspirational,politics,science" +"Phantasie ist wichtiger als Wissen, denn Wissen ist begrenzt.","Albert Einstein","inspiration" +"If that which we have found is the corruption of solitude, then what can men wish for save corruption? If this is the great evil of being alone, than what is good and what is evil?","Ayn Rand","dystopian,philosophy" +"‎Teachers matter. So instead of bashing them, or defending the status quo, let’s offer schools a deal. Give them the resources to keep good teachers on the job, and reward the best ones. In return, grant schools flexibility: To teach with creativity and passion; to stop teaching to the test; and to replace teachers who just aren’t helping kids learn.","Barack Obama","education" +"If you accept the expectations of others, especially negative ones, then you never will change the outcome.","Michael Jordan","change,negative,accept" diff --git a/examples/quotes/backend/quotes.py b/examples/quotes/backend/quotes.py new file mode 100644 index 000000000..4492d5e7e --- /dev/null +++ b/examples/quotes/backend/quotes.py @@ -0,0 +1,179 @@ +import asyncio +import csv +import os +from time import time +from typing import Annotated + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel, Field, ValidationError +from sentence_transformers import SentenceTransformer + +from elasticsearch import NotFoundError +from elasticsearch.dsl.pydantic import AsyncBaseESModel +from elasticsearch import dsl + +model = SentenceTransformer("all-MiniLM-L6-v2") +dsl.async_connections.create_connection(hosts=[os.environ['ELASTICSEARCH_URL']]) + + +class Quote(AsyncBaseESModel): + quote: str + author: Annotated[str, dsl.Keyword()] + tags: Annotated[list[str], dsl.Keyword()] + embedding: Annotated[list[float], dsl.DenseVector()] = Field(init=False, default=[]) + + class Index: + name = 'quotes' + + +class Tag(BaseModel): + tag: str + count: int + + +class SearchRequest(BaseModel): + query: str + filters: list[str] + knn: bool + start: int + + +class SearchResponse(BaseModel): + quotes: list[Quote] + tags: list[Tag] + start: int + total: int + + +app = FastAPI( + title="Quotes API", + version="1.0.0", +) + + +@app.get("/api/quotes/{id}") +async def get_quote(id: str) -> Quote: + doc = None + try: + doc = await Quote._doc.get(id) + except NotFoundError: + pass + if not doc: + raise HTTPException(status_code=404, detail="Item not found") + return Quote.from_doc(doc) + + +@app.post("/api/quotes", status_code=201) +async def create_quote(req: Quote) -> Quote: + embed_quotes([req]) + doc = req.to_doc() + doc.meta.id = "" + await doc.save(refresh=True) + return Quote.from_doc(doc) + + +@app.put("/api/quotes/{id}") +async def update_quote(id: str, quote: Quote) -> Quote: + doc = None + try: + doc = await Quote._doc.get(id) + except NotFoundError: + pass + if not doc: + raise HTTPException(status_code=404, detail="Item not found") + if quote.quote: + embed_quotes([quote]) + doc.quote = quote.quote + doc.embedding = quote.embedding + if quote.author: + doc.author = quote.author + if quote.tags: + doc.tags = quote.tags + await doc.save(refresh=True) + return Quote.from_doc(doc) + + +@app.delete("/api/quotes/{id}", status_code=204) +async def delete_quote(id: str) -> None: + doc = None + try: + doc = await Quote._doc.get(id) + except NotFoundError: + pass + if not doc: + raise HTTPException(status_code=404, detail="Item not found") + await doc.delete(refresh=True) + + +@app.post('/api/search') +async def search_quotes(req: SearchRequest) -> SearchResponse: + s = Quote._doc.search() + if req.query == '': + s = s.query(dsl.query.MatchAll()) + elif req.knn: + query_vector = model.encode(req.query).tolist() + s = s.query(dsl.query.Knn(field=Quote._doc.embedding, query_vector=query_vector)) + else: + s = s.query(dsl.query.Match(quote=req.query)) + for tag in req.filters: + s = s.filter(dsl.query.Terms(tags=[tag])) + s.aggs.bucket('tags', dsl.aggs.Terms(field=Quote._doc.tags, size=100)) + + r = await s[req.start:req.start + 25].execute() + tags = [(tag.key, tag.doc_count) for tag in r.aggs.tags.buckets] + quotes = [Quote.from_doc(hit) for hit in r.hits] + total = r['hits'].total.value + + return SearchResponse( + quotes=quotes, + tags=[Tag(tag=t[0], count=t[1]) for t in tags], + start=req.start, + total=total + ) + + +def embed_quotes(quotes): + embeddings = model.encode([q.quote for q in quotes]) + for q, e in zip(quotes, embeddings): + q.embedding = e.tolist() + + +async def ingest_quotes(): + if await Quote._doc._index.exists(): + await Quote._doc._index.delete() + await Quote._doc.init() + + def ingest_progress(count, start): + elapsed = time() - start + print(f'\rIngested {count} quotes. ({count / elapsed:.0f}/sec)', end='') + + async def get_next_quote(): + quotes: list[Quote] = [] + with open('quotes.csv') as f: + reader = csv.DictReader(f) + count = 0 + start = time() + for row in reader: + q = Quote(quote=row['quote'], author=row['author'], + tags=row['tags'].split(',')) + quotes.append(q) + if len(quotes) == 512: + embed_quotes(quotes) + for q in quotes: + yield q.to_doc() + count += len(quotes) + ingest_progress(count, start) + quotes = [] + if len(quotes) > 0: + embed_quotes(quotes) + for q in quotes: + yield q.to_doc() + count += len(quotes) + ingest_progress(count, start) + + await Quote._doc.bulk(get_next_quote()) + print("\nIngest complete.") + + +if __name__ == "__main__": + asyncio.run(ingest_quotes()) diff --git a/examples/quotes/backend/requirements.txt b/examples/quotes/backend/requirements.txt new file mode 100644 index 000000000..40862ea54 --- /dev/null +++ b/examples/quotes/backend/requirements.txt @@ -0,0 +1,163 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile pyproject.toml +# +aiohappyeyeballs==2.6.1 + # via aiohttp +aiohttp==3.12.15 + # via elasticsearch +aiosignal==1.4.0 + # via aiohttp +annotated-types==0.7.0 + # via pydantic +anyio==4.11.0 + # via starlette +attrs==25.3.0 + # via aiohttp +certifi==2025.8.3 + # via + # elastic-transport + # requests +charset-normalizer==3.4.3 + # via requests +click==8.3.0 + # via uvicorn +elastic-transport==8.17.1 + # via elasticsearch +elasticsearch[async]==8.19.1 + # via quotes (pyproject.toml) +fastapi==0.117.1 + # via quotes (pyproject.toml) +filelock==3.19.1 + # via + # huggingface-hub + # torch + # transformers +frozenlist==1.7.0 + # via + # aiohttp + # aiosignal +fsspec==2025.9.0 + # via + # huggingface-hub + # torch +h11==0.16.0 + # via uvicorn +hf-xet==1.1.10 + # via huggingface-hub +huggingface-hub==0.35.0 + # via + # sentence-transformers + # tokenizers + # transformers +idna==3.10 + # via + # anyio + # requests + # yarl +jinja2==3.1.6 + # via torch +joblib==1.5.2 + # via scikit-learn +markupsafe==3.0.2 + # via jinja2 +mpmath==1.3.0 + # via sympy +multidict==6.6.4 + # via + # aiohttp + # yarl +networkx==3.5 + # via torch +numpy==2.3.3 + # via + # scikit-learn + # scipy + # transformers +orjson==3.11.3 + # via quotes (pyproject.toml) +packaging==25.0 + # via + # huggingface-hub + # transformers +pillow==11.3.0 + # via sentence-transformers +propcache==0.3.2 + # via + # aiohttp + # yarl +pydantic==2.11.9 + # via fastapi +pydantic-core==2.33.2 + # via pydantic +python-dateutil==2.9.0.post0 + # via elasticsearch +pyyaml==6.0.2 + # via + # huggingface-hub + # transformers +regex==2025.9.18 + # via transformers +requests==2.32.5 + # via + # huggingface-hub + # transformers +safetensors==0.6.2 + # via transformers +scikit-learn==1.7.2 + # via sentence-transformers +scipy==1.16.2 + # via + # scikit-learn + # sentence-transformers +sentence-transformers==5.1.1 + # via quotes (pyproject.toml) +six==1.17.0 + # via python-dateutil +sniffio==1.3.1 + # via anyio +starlette==0.48.0 + # via fastapi +sympy==1.14.0 + # via torch +threadpoolctl==3.6.0 + # via scikit-learn +tokenizers==0.22.1 + # via transformers +torch==2.8.0 + # via sentence-transformers +tqdm==4.67.1 + # via + # huggingface-hub + # sentence-transformers + # transformers +transformers==4.56.2 + # via sentence-transformers +typing-extensions==4.15.0 + # via + # aiosignal + # anyio + # elasticsearch + # fastapi + # huggingface-hub + # pydantic + # pydantic-core + # sentence-transformers + # starlette + # torch + # typing-inspection +typing-inspection==0.4.1 + # via pydantic +urllib3==2.5.0 + # via + # elastic-transport + # requests +uvicorn==0.36.0 + # via quotes (pyproject.toml) +yarl==1.20.1 + # via aiohttp + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/examples/quotes/eslint.config.js b/examples/quotes/eslint.config.js new file mode 100644 index 000000000..b19330b10 --- /dev/null +++ b/examples/quotes/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/examples/quotes/index.html b/examples/quotes/index.html new file mode 100644 index 000000000..283f6d8ef --- /dev/null +++ b/examples/quotes/index.html @@ -0,0 +1,13 @@ + + + + + + + Elasticsearch + Pydantic Demo + + +
+ + + diff --git a/examples/quotes/package-lock.json b/examples/quotes/package-lock.json new file mode 100644 index 000000000..9d7913b83 --- /dev/null +++ b/examples/quotes/package-lock.json @@ -0,0 +1,3756 @@ +{ + "name": "quotes", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "quotes", + "version": "0.0.0", + "hasInstallScript": true, + "dependencies": { + "boostrap": "^2.0.0", + "bootstrap": "^5.3.8", + "react": "^19.1.1", + "react-bootstrap": "^2.10.10", + "react-dom": "^19.1.1", + "react-router": "^7.9.2" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.13", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.3", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.4.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.44.0", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", + "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", + "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.9.4.tgz", + "integrity": "sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@popperjs/core": "^2.11.8", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.5.0", + "@types/warning": "^3.0.3", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.4", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/@restart/hooks": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.5.1.tgz", + "integrity": "sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.35.tgz", + "integrity": "sha512-slYrCpoxJUqzFDDNlvrOYRazQUNRvWPjXA17dAOISY3rDMxX6k8K4cj2H+hEYMHF81HO3uNd5rHVigAWRM5dSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.2.tgz", + "integrity": "sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.2.tgz", + "integrity": "sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.2.tgz", + "integrity": "sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.2.tgz", + "integrity": "sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.2.tgz", + "integrity": "sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.2.tgz", + "integrity": "sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.2.tgz", + "integrity": "sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.2.tgz", + "integrity": "sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.2.tgz", + "integrity": "sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.2.tgz", + "integrity": "sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.2.tgz", + "integrity": "sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.2.tgz", + "integrity": "sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.2.tgz", + "integrity": "sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.2.tgz", + "integrity": "sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.2.tgz", + "integrity": "sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.2.tgz", + "integrity": "sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.2.tgz", + "integrity": "sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.2.tgz", + "integrity": "sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.2.tgz", + "integrity": "sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.2.tgz", + "integrity": "sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.2.tgz", + "integrity": "sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.2.tgz", + "integrity": "sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.13", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz", + "integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz", + "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz", + "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/type-utils": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.44.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz", + "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz", + "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.44.1", + "@typescript-eslint/types": "^8.44.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", + "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz", + "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz", + "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", + "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz", + "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", + "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.3.tgz", + "integrity": "sha512-PFVHhosKkofGH0Yzrw1BipSedTH68BFF8ZWy1kfUpCtJcouXXY0+racG8sExw7hw0HoX36813ga5o3LTWZ4FUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.35", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz", + "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/boostrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/boostrap/-/boostrap-2.0.0.tgz", + "integrity": "sha512-JEeFMOweKeGXEM9rt95eaVISOkluG9aKcl0jQCETOVH9jynCZxuBZe2oWgcWJpj5wqYWZl625SnW7OgHT2Ineg==", + "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.", + "license": "ISC" + }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001743", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", + "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.223", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.223.tgz", + "integrity": "sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", + "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.36.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.21.tgz", + "integrity": "sha512-MWDWTtNC4voTcWDxXbdmBNe8b/TxfxRFUL6hXgKWJjN9c1AagYEmpiFWBWzDw+5H3SulWUe1pJKTnoSdmk88UA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "license": "MIT", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", + "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-bootstrap": { + "version": "2.10.10", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.10.tgz", + "integrity": "sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.7", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.9.4", + "@types/prop-types": "^15.7.12", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dom": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", + "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.2.tgz", + "integrity": "sha512-i2TPp4dgaqrOqiRGLZmqh2WXmbdFknUyiCRmSKs0hf6fWXkTKg5h56b+9F22NbGRAMxjYfqQnpi63egzD2SuZA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.52.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.2.tgz", + "integrity": "sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.2", + "@rollup/rollup-android-arm64": "4.52.2", + "@rollup/rollup-darwin-arm64": "4.52.2", + "@rollup/rollup-darwin-x64": "4.52.2", + "@rollup/rollup-freebsd-arm64": "4.52.2", + "@rollup/rollup-freebsd-x64": "4.52.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.2", + "@rollup/rollup-linux-arm-musleabihf": "4.52.2", + "@rollup/rollup-linux-arm64-gnu": "4.52.2", + "@rollup/rollup-linux-arm64-musl": "4.52.2", + "@rollup/rollup-linux-loong64-gnu": "4.52.2", + "@rollup/rollup-linux-ppc64-gnu": "4.52.2", + "@rollup/rollup-linux-riscv64-gnu": "4.52.2", + "@rollup/rollup-linux-riscv64-musl": "4.52.2", + "@rollup/rollup-linux-s390x-gnu": "4.52.2", + "@rollup/rollup-linux-x64-gnu": "4.52.2", + "@rollup/rollup-linux-x64-musl": "4.52.2", + "@rollup/rollup-openharmony-arm64": "4.52.2", + "@rollup/rollup-win32-arm64-msvc": "4.52.2", + "@rollup/rollup-win32-ia32-msvc": "4.52.2", + "@rollup/rollup-win32-x64-gnu": "4.52.2", + "@rollup/rollup-win32-x64-msvc": "4.52.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/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/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.1.tgz", + "integrity": "sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.44.1", + "@typescript-eslint/parser": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz", + "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "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", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.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 + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/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/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/examples/quotes/package.json b/examples/quotes/package.json new file mode 100644 index 000000000..75bbec010 --- /dev/null +++ b/examples/quotes/package.json @@ -0,0 +1,36 @@ +{ + "name": "quotes", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "postinstall": "cd backend && python -m venv .venv && .venv/bin/pip install -r requirements.txt", + "backend": "cd backend && .venv/bin/uvicorn --port 5000 --reload quotes:app", + "ingest": "cd backend && .venv/bin/python quotes.py" + }, + "dependencies": { + "boostrap": "^2.0.0", + "bootstrap": "^5.3.8", + "react": "^19.1.1", + "react-bootstrap": "^2.10.10", + "react-dom": "^19.1.1", + "react-router": "^7.9.2" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.13", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.3", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.4.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.44.0", + "vite": "^7.1.7" + } +} diff --git a/examples/quotes/public/.keep b/examples/quotes/public/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/examples/quotes/screenshot.png b/examples/quotes/screenshot.png new file mode 100644 index 000000000..7b546085c Binary files /dev/null and b/examples/quotes/screenshot.png differ diff --git a/examples/quotes/src/App.tsx b/examples/quotes/src/App.tsx new file mode 100644 index 000000000..5f886ac05 --- /dev/null +++ b/examples/quotes/src/App.tsx @@ -0,0 +1,172 @@ +import React, { useRef, useState, useEffect } from 'react'; +import Container from 'react-bootstrap/Container'; +import { NavLink } from 'react-router'; +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Form from 'react-bootstrap/Form'; +import Button from 'react-bootstrap/Button'; +import Spinner from 'react-bootstrap/Spinner'; +import Stack from 'react-bootstrap/Stack'; +import CloseButton from 'react-bootstrap/CloseButton'; +import ToggleButton from 'react-bootstrap/ToggleButton'; +import Pagination from 'react-bootstrap/Pagination'; +import type { Quote, Tag } from './models'; + +export default function App() { + const inputRef = useRef(null); + const [knn, setKnn] = useState(true); + const [query, setQuery] = useState(''); + const [filters, setFilters] = useState([]); + const [tags, setTags] = useState([]); + const [results, setResults] = useState(null); + const [start, setStart] = useState(0); + const [total, setTotal] = useState(0); + + useEffect(() => { + if (inputRef.current) { + inputRef.current.value = query; + } + }, [query]); + + const onSearch = (ev: React.FormEvent) => { + ev.preventDefault(); + setQuery(inputRef.current?.value || ''); + setStart(0); + }; + + const onResetQuery = () => { + setQuery(''); + setStart(0); + setTags(null); + setResults(null); + inputRef.current?.focus(); + }; + + const onResetFilters = () => { + setFilters([]); + setStart(0); + setTags(null); + setResults(null); + inputRef.current?.focus(); + }; + + const onFilter = ({tag, count}: Tag) => { + setFilters([...filters, tag]); + setStart(0); + setTags(null); + setResults(null); + }; + + useEffect(() => { + (async () => { + const response = await fetch('/api/search', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({query, filters, knn, start}), + }); + const data: {quotes: Quote[], tags: Tag[], start: number, total: number} = await response.json(); + setResults(data.quotes); + setTags(data.tags.filter(tag => !filters.includes(tag.tag))); + setStart(data.start); + setTotal(data.total); + window.scrollTo(0, 0); + })() + }, [query, filters, knn, start, total]); + + return ( + + +

Elasticsearch + Pydantic Demo

+
+ + + + setKnn(e.currentTarget.checked)}> + + + New Quote + +
+
+ + + <> + {filters != null && ( + <> + {filters.map(tag => ( +
+ » {tag} +
+ ))} + {(filters.length > 0) && ( + <> + +
+ + )} + + )} + {(tags === null) ? + + Loading... + + : + <> + {(tags.length === 0) ? +

No tags.

+ : + <> + {tags.map(({tag, count}) => ( +
+ ({count}) +
+ ))} + + } + + } + + + + {(results === null) ? + + Loading... + + : + <> + {(results.length === 0) ? +

No results. Sorry!

+ : + <> +

Showing results {start + 1}-{start + results.length} of {total}.

+ {results.map(({quote, author, tags, meta}, index) => ( +
+

+ {quote}{author} +
+ [Score: {meta.score}] {tags.map(tag => `#${tag}`).join(', ')} +
+ Edit +

+
+ ))} + + } + + {start > 0 && + <> + setStart(0)} /> + setStart(start - results.length)} /> + + } + {results.length > 0 && start + results.length < total && + setStart(start + results.length)} /> + } + + + } + +
+
+ ); +} diff --git a/examples/quotes/src/Quote.tsx b/examples/quotes/src/Quote.tsx new file mode 100644 index 000000000..6cde7a440 --- /dev/null +++ b/examples/quotes/src/Quote.tsx @@ -0,0 +1,104 @@ +import { useState, useEffect, useRef } from 'react'; +import type { MouseEvent } from 'react'; +import { useParams, NavLink, useNavigate } from 'react-router'; +import Container from 'react-bootstrap/Container'; +import Stack from 'react-bootstrap/Stack'; +import Form from 'react-bootstrap/Form'; +import Button from 'react-bootstrap/Button'; +import Toast from 'react-bootstrap/Toast'; +import ToastContainer from 'react-bootstrap/ToastContainer'; +import type { Quote } from './models'; + +export default function Quote() { + const [quote, setQuote] = useState(undefined); + const [status, setStatus] = useState(""); + const params = useParams(); + const navigate = useNavigate(); + const quoteField = useRef(null); + const authorField = useRef(null); + const tagsField = useRef(null); + + useEffect(() => { + (async () => { + const response = await fetch(`/api/quotes/${params.id}`); + const data = await response.json(); + setQuote(data); + })(); + }, []); + + const onSubmit = async (ev: MouseEvent) => { + ev.preventDefault(); + if (quote) { + quote.quote = quoteField.current?.value ?? ''; + quote.author = authorField.current?.value ?? ''; + quote.tags = (tagsField.current?.value ?? "").split(','); + let url = '/api/quotes'; + let method = 'POST'; + if (params.id !== 'new') { + url += `/${params.id}`; + method = 'PUT'; + } + const response = await fetch(url, { + method: method, + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(quote), + }); + if (response.status == 200 || response.status == 201) { + const data = await response.json(); + navigate(`/quotes/${data.meta.id}`); + } + else { + setStatus('Save error'); + } + } + }; + + const onDelete = async (ev: MouseEvent) => { + ev.preventDefault(); + const response = await fetch(`/api/quotes/${params.id}`, { + method: 'DELETE', + }); + if (response.status == 204) { + navigate('/'); + } + else { + setStatus('Delete error'); + } + }; + + return ( + +

Elasticsearch + Pydantic Demo

+
+ + setStatus('')} show={status != ''} delay={3000} autohide> + {status} + + + + Quote + + + + Author + + + + Tags + + + + + {params.id !== 'new' && + + } + Back + +
+
+ ); +} diff --git a/examples/quotes/src/index.css b/examples/quotes/src/index.css new file mode 100644 index 000000000..6ac8038d5 --- /dev/null +++ b/examples/quotes/src/index.css @@ -0,0 +1,55 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} + +.SearchForm { + margin-bottom: 25px; +} + +.Tags { + margin-top: 10px; +} + +.Results { + margin-top: 10px; +} + +.Results .Summary { + font-size: 0.9em; + font-style: italic; +} + +.Filter { + font-style: italic; +} + +.Tags button { + padding: 0px; +} + +.ResultQuote { + font-weight: bold; +} + +.ResultAuthor { +} + +.ResultScore { + font-size: 0.8em; +} + +.ResultTags { + font-size: 0.8em; + font-style: italic; +} + diff --git a/examples/quotes/src/main.tsx b/examples/quotes/src/main.tsx new file mode 100644 index 000000000..404bbe7d9 --- /dev/null +++ b/examples/quotes/src/main.tsx @@ -0,0 +1,24 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { createBrowserRouter, RouterProvider } from 'react-router'; +import 'bootstrap/dist/css/bootstrap.min.css'; +import './index.css' +import App from './App.tsx' +import Quote from './Quote.tsx' + +const router = createBrowserRouter([ + { + path: '/', + element: , + }, + { + path: '/quotes/:id', + element: , + }, +]); + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/examples/quotes/src/models.tsx b/examples/quotes/src/models.tsx new file mode 100644 index 000000000..e426b705c --- /dev/null +++ b/examples/quotes/src/models.tsx @@ -0,0 +1,16 @@ +export interface Meta { + id: string; + score: number; +} + +export interface Quote { + meta: Meta; + quote: string; + author: string; + tags: string[]; +}; + +export interface Tag { + tag: string; + count: number; +}; diff --git a/examples/quotes/tsconfig.app.json b/examples/quotes/tsconfig.app.json new file mode 100644 index 000000000..a9b5a59ca --- /dev/null +++ b/examples/quotes/tsconfig.app.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/examples/quotes/tsconfig.json b/examples/quotes/tsconfig.json new file mode 100644 index 000000000..1ffef600d --- /dev/null +++ b/examples/quotes/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/examples/quotes/tsconfig.node.json b/examples/quotes/tsconfig.node.json new file mode 100644 index 000000000..7a77bab3b --- /dev/null +++ b/examples/quotes/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": [], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/quotes/vite.config.ts b/examples/quotes/vite.config.ts new file mode 100644 index 000000000..c3c29c6b0 --- /dev/null +++ b/examples/quotes/vite.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + '/api': 'http://localhost:5000', + '/docs': 'http://localhost:5000', + '/redoc': 'http://localhost:5000', + '/openapi.json': 'http://localhost:5000', + }, + }, +}) diff --git a/noxfile.py b/noxfile.py index 73f3df3d5..ca7f028d2 100644 --- a/noxfile.py +++ b/noxfile.py @@ -90,6 +90,7 @@ def lint(session): "flake8", "black~=25.0", "mypy", + "pydantic", "isort~=6.0", "types-requests", "types-python-dateutil", diff --git a/pyproject.toml b/pyproject.toml index fe0a9ca6c..c12a5a9df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,7 @@ dev = [ "python-dateutil", "unasync", "pyyaml>=5.4", + "pydantic", "isort", "black", "twine", @@ -139,4 +140,5 @@ exclude_lines = [ ] [tool.mypy] +plugins = ["pydantic.mypy"] ignore_missing_imports = true diff --git a/test_elasticsearch/test_dsl/_async/test_document.py b/test_elasticsearch/test_dsl/_async/test_document.py index 8ac0fc887..c986e588e 100644 --- a/test_elasticsearch/test_dsl/_async/test_document.py +++ b/test_elasticsearch/test_dsl/_async/test_document.py @@ -27,8 +27,9 @@ import sys from datetime import datetime from hashlib import md5 -from typing import Any, ClassVar, Dict, List, Optional +from typing import Annotated, Any, ClassVar, Dict, List, Optional +import pydantic import pytest from pytest import raises @@ -36,6 +37,7 @@ AsyncDocument, Index, InnerDoc, + Keyword, M, Mapping, MetaField, @@ -47,6 +49,7 @@ ) from elasticsearch.dsl.document_base import InstrumentedField from elasticsearch.dsl.exceptions import IllegalOperation, ValidationException +from elasticsearch.dsl.pydantic import AsyncBaseESModel class MyInner(InnerDoc): @@ -678,118 +681,150 @@ class TypedDoc(AsyncDocument): ) i1: ClassVar i2: ClassVar[int] - - props = TypedDoc._doc_type.mapping.to_dict()["properties"] - assert props == { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, - "ob": { - "type": "object", - "properties": { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, + i3: str = mapped_field(exclude=True) + + class TypedDocAnnotated(AsyncDocument): + st: Annotated[str, "foo"] + dt: Annotated[Optional[datetime], "bar"] + li: Annotated[List[int], "baz"] + ob: Annotated[TypedInnerDoc, "qux"] + ns: Annotated[List[TypedInnerDoc], "quux"] + ip: Annotated[Optional[str], field.Ip()] + k1: Annotated[str, field.Keyword(required=True)] + k2: Annotated[M[str], field.Keyword()] + k3: Annotated[str, mapped_field(field.Keyword(), default="foo")] + k4: Annotated[M[Optional[str]], mapped_field(field.Keyword())] # type: ignore[misc] + s1: Annotated[Secret, SecretField()] + s2: Annotated[M[Secret], SecretField()] + s3: Annotated[Secret, mapped_field(SecretField())] # type: ignore[misc] + s4: Annotated[ + M[Optional[Secret]], + mapped_field(SecretField(), default_factory=lambda: "foo"), + ] + if sys.version_info[0] > 3 or ( + sys.version_info[0] == 3 and sys.version_info[1] >= 11 + ): + i1: Annotated[ClassVar, "classvar"] + i2: Annotated[ClassVar[int], "classvar"] + else: + i1: ClassVar + i2: ClassVar[int] + i3: Annotated[str, mapped_field(exclude=True)] + + for doc_class in [TypedDoc, TypedDocAnnotated]: + props = doc_class._doc_type.mapping.to_dict()["properties"] + assert props == { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + "ob": { + "type": "object", + "properties": { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + }, }, - }, - "ns": { - "type": "nested", - "properties": { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, + "ns": { + "type": "nested", + "properties": { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + }, }, - }, - "ip": {"type": "ip"}, - "k1": {"type": "keyword"}, - "k2": {"type": "keyword"}, - "k3": {"type": "keyword"}, - "k4": {"type": "keyword"}, - "s1": {"type": "text"}, - "s2": {"type": "text"}, - "s3": {"type": "text"}, - "s4": {"type": "text"}, - } + "ip": {"type": "ip"}, + "k1": {"type": "keyword"}, + "k2": {"type": "keyword"}, + "k3": {"type": "keyword"}, + "k4": {"type": "keyword"}, + "s1": {"type": "text"}, + "s2": {"type": "text"}, + "s3": {"type": "text"}, + "s4": {"type": "text"}, + } - TypedDoc.i1 = "foo" - TypedDoc.i2 = 123 + doc_class.i1 = "foo" + doc_class.i2 = 123 + doc_class.i3 = "bar" + + doc = doc_class() + assert doc.k3 == "foo" + assert doc.s4 == "foo" + with raises(ValidationException) as exc_info: + doc.full_clean() + assert set(exc_info.value.args[0].keys()) == { + "st", + "k1", + "k2", + "ob", + "s1", + "s2", + "s3", + } - doc = TypedDoc() - assert doc.k3 == "foo" - assert doc.s4 == "foo" - with raises(ValidationException) as exc_info: + assert doc_class.i1 == "foo" + assert doc_class.i2 == 123 + assert doc_class.i3 == "bar" + + doc.st = "s" + doc.li = [1, 2, 3] + doc.k1 = "k1" + doc.k2 = "k2" + doc.ob.st = "s" + doc.ob.li = [1] + doc.s1 = "s1" + doc.s2 = "s2" + doc.s3 = "s3" doc.full_clean() - assert set(exc_info.value.args[0].keys()) == { - "st", - "k1", - "k2", - "ob", - "s1", - "s2", - "s3", - } - assert TypedDoc.i1 == "foo" - assert TypedDoc.i2 == 123 - - doc.st = "s" - doc.li = [1, 2, 3] - doc.k1 = "k1" - doc.k2 = "k2" - doc.ob.st = "s" - doc.ob.li = [1] - doc.s1 = "s1" - doc.s2 = "s2" - doc.s3 = "s3" - doc.full_clean() + doc.ob = TypedInnerDoc(li=[1]) + with raises(ValidationException) as exc_info: + doc.full_clean() + assert set(exc_info.value.args[0].keys()) == {"ob"} + assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} - doc.ob = TypedInnerDoc(li=[1]) - with raises(ValidationException) as exc_info: - doc.full_clean() - assert set(exc_info.value.args[0].keys()) == {"ob"} - assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} + doc.ob.st = "s" + doc.ns.append(TypedInnerDoc(li=[1, 2])) + with raises(ValidationException) as exc_info: + doc.full_clean() - doc.ob.st = "s" - doc.ns.append(TypedInnerDoc(li=[1, 2])) - with raises(ValidationException) as exc_info: + doc.ns[0].st = "s" doc.full_clean() - doc.ns[0].st = "s" - doc.full_clean() - - doc.ip = "1.2.3.4" - n = datetime.now() - doc.dt = n - assert doc.to_dict() == { - "st": "s", - "li": [1, 2, 3], - "dt": n, - "ob": { + doc.ip = "1.2.3.4" + n = datetime.now() + doc.dt = n + assert doc.to_dict() == { "st": "s", - "li": [1], - }, - "ns": [ - { + "li": [1, 2, 3], + "dt": n, + "ob": { "st": "s", - "li": [1, 2], - } - ], - "ip": "1.2.3.4", - "k1": "k1", - "k2": "k2", - "k3": "foo", - "s1": "s1", - "s2": "s2", - "s3": "s3", - "s4": "foo", - } + "li": [1], + }, + "ns": [ + { + "st": "s", + "li": [1, 2], + } + ], + "ip": "1.2.3.4", + "k1": "k1", + "k2": "k2", + "k3": "foo", + "s1": "s1", + "s2": "s2", + "s3": "s3", + "s4": "foo", + } - s = TypedDoc.search().sort(TypedDoc.st, -TypedDoc.dt, +TypedDoc.ob.st) - s.aggs.bucket("terms_agg", "terms", field=TypedDoc.k1) - assert s.to_dict() == { - "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, - "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], - } + s = doc_class.search().sort(doc_class.st, -doc_class.dt, +doc_class.ob.st) + s.aggs.bucket("terms_agg", "terms", field=doc_class.k1) + assert s.to_dict() == { + "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, + "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], + } @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10") @@ -881,3 +916,107 @@ class Doc(AsyncDocument): Doc.ns.something with raises(AttributeError): Doc.ns.st.something + + +def test_pydantic_integration() -> None: + class Location(pydantic.BaseModel): + city: str + country: str + + class Address(pydantic.BaseModel): + street: str + location: Location + + class Phone(pydantic.BaseModel): + type: str + number: str + + class User(AsyncBaseESModel): + name: Annotated[str, Keyword()] = pydantic.Field(default="Unknown") + bio: str + age: int = pydantic.Field(strict=True, ge=0) + address: Address = pydantic.Field( + default=Address( + street="Unknown", location=Location(city="Unknown", country="Unknown") + ) + ) + phones: list[Phone] = pydantic.Field(default=[]) + + u = User( + name="foo", + bio="lorem ipsum", + age=30, + address=Address( + street="123 Main St.", + location=Location(city="San Francisco", country="USA"), + ), + ) + u.phones.append(Phone(type="Home", number="+12345678900")) + assert u.model_dump() == { + "name": "foo", + "bio": "lorem ipsum", + "age": 30, + "address": { + "street": "123 Main St.", + "location": { + "city": "San Francisco", + "country": "USA", + }, + }, + "phones": [ + { + "type": "Home", + "number": "+12345678900", + } + ], + "meta": { + "id": "", + "index": "", + "primary_term": 0, + "score": 0, + "seq_no": 0, + "version": 0, + }, + } + udoc = u.to_doc() + assert udoc.name == "foo" + assert udoc.bio == "lorem ipsum" + assert udoc.age == 30 + assert udoc.to_dict() == { + "name": "foo", + "bio": "lorem ipsum", + "age": 30, + "address": { + "street": "123 Main St.", + "location": { + "city": "San Francisco", + "country": "USA", + }, + }, + "phones": [ + { + "type": "Home", + "number": "+12345678900", + } + ], + } + + u2 = User.from_doc(udoc) + assert u == u2 + + with raises(pydantic.ValidationError): + _ = User() + + with raises(pydantic.ValidationError): + _ = User(name="foo", bio="lorem ipsum") + + with raises(pydantic.ValidationError): + _ = User(name="foo", bio="lorem ipsum", age=-10) + + u3 = User(bio="lorem ipsum", age=30) + assert u3.name == "Unknown" + assert u3.address.location.country == "Unknown" + assert u3.phones == [] + assert u3.to_doc().name == "Unknown" + assert u3.to_doc().address.location.country == "Unknown" + assert u3.to_doc().phones == [] diff --git a/test_elasticsearch/test_dsl/_sync/test_document.py b/test_elasticsearch/test_dsl/_sync/test_document.py index 05ad9d623..c4e0cc31a 100644 --- a/test_elasticsearch/test_dsl/_sync/test_document.py +++ b/test_elasticsearch/test_dsl/_sync/test_document.py @@ -27,8 +27,9 @@ import sys from datetime import datetime from hashlib import md5 -from typing import Any, ClassVar, Dict, List, Optional +from typing import Annotated, Any, ClassVar, Dict, List, Optional +import pydantic import pytest from pytest import raises @@ -36,6 +37,7 @@ Document, Index, InnerDoc, + Keyword, M, Mapping, MetaField, @@ -47,6 +49,7 @@ ) from elasticsearch.dsl.document_base import InstrumentedField from elasticsearch.dsl.exceptions import IllegalOperation, ValidationException +from elasticsearch.dsl.pydantic import BaseESModel class MyInner(InnerDoc): @@ -678,118 +681,150 @@ class TypedDoc(Document): ) i1: ClassVar i2: ClassVar[int] - - props = TypedDoc._doc_type.mapping.to_dict()["properties"] - assert props == { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, - "ob": { - "type": "object", - "properties": { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, + i3: str = mapped_field(exclude=True) + + class TypedDocAnnotated(Document): + st: Annotated[str, "foo"] + dt: Annotated[Optional[datetime], "bar"] + li: Annotated[List[int], "baz"] + ob: Annotated[TypedInnerDoc, "qux"] + ns: Annotated[List[TypedInnerDoc], "quux"] + ip: Annotated[Optional[str], field.Ip()] + k1: Annotated[str, field.Keyword(required=True)] + k2: Annotated[M[str], field.Keyword()] + k3: Annotated[str, mapped_field(field.Keyword(), default="foo")] + k4: Annotated[M[Optional[str]], mapped_field(field.Keyword())] # type: ignore[misc] + s1: Annotated[Secret, SecretField()] + s2: Annotated[M[Secret], SecretField()] + s3: Annotated[Secret, mapped_field(SecretField())] # type: ignore[misc] + s4: Annotated[ + M[Optional[Secret]], + mapped_field(SecretField(), default_factory=lambda: "foo"), + ] + if sys.version_info[0] > 3 or ( + sys.version_info[0] == 3 and sys.version_info[1] >= 11 + ): + i1: Annotated[ClassVar, "classvar"] + i2: Annotated[ClassVar[int], "classvar"] + else: + i1: ClassVar + i2: ClassVar[int] + i3: Annotated[str, mapped_field(exclude=True)] + + for doc_class in [TypedDoc, TypedDocAnnotated]: + props = doc_class._doc_type.mapping.to_dict()["properties"] + assert props == { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + "ob": { + "type": "object", + "properties": { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + }, }, - }, - "ns": { - "type": "nested", - "properties": { - "st": {"type": "text"}, - "dt": {"type": "date"}, - "li": {"type": "integer"}, + "ns": { + "type": "nested", + "properties": { + "st": {"type": "text"}, + "dt": {"type": "date"}, + "li": {"type": "integer"}, + }, }, - }, - "ip": {"type": "ip"}, - "k1": {"type": "keyword"}, - "k2": {"type": "keyword"}, - "k3": {"type": "keyword"}, - "k4": {"type": "keyword"}, - "s1": {"type": "text"}, - "s2": {"type": "text"}, - "s3": {"type": "text"}, - "s4": {"type": "text"}, - } + "ip": {"type": "ip"}, + "k1": {"type": "keyword"}, + "k2": {"type": "keyword"}, + "k3": {"type": "keyword"}, + "k4": {"type": "keyword"}, + "s1": {"type": "text"}, + "s2": {"type": "text"}, + "s3": {"type": "text"}, + "s4": {"type": "text"}, + } - TypedDoc.i1 = "foo" - TypedDoc.i2 = 123 + doc_class.i1 = "foo" + doc_class.i2 = 123 + doc_class.i3 = "bar" + + doc = doc_class() + assert doc.k3 == "foo" + assert doc.s4 == "foo" + with raises(ValidationException) as exc_info: + doc.full_clean() + assert set(exc_info.value.args[0].keys()) == { + "st", + "k1", + "k2", + "ob", + "s1", + "s2", + "s3", + } - doc = TypedDoc() - assert doc.k3 == "foo" - assert doc.s4 == "foo" - with raises(ValidationException) as exc_info: + assert doc_class.i1 == "foo" + assert doc_class.i2 == 123 + assert doc_class.i3 == "bar" + + doc.st = "s" + doc.li = [1, 2, 3] + doc.k1 = "k1" + doc.k2 = "k2" + doc.ob.st = "s" + doc.ob.li = [1] + doc.s1 = "s1" + doc.s2 = "s2" + doc.s3 = "s3" doc.full_clean() - assert set(exc_info.value.args[0].keys()) == { - "st", - "k1", - "k2", - "ob", - "s1", - "s2", - "s3", - } - assert TypedDoc.i1 == "foo" - assert TypedDoc.i2 == 123 - - doc.st = "s" - doc.li = [1, 2, 3] - doc.k1 = "k1" - doc.k2 = "k2" - doc.ob.st = "s" - doc.ob.li = [1] - doc.s1 = "s1" - doc.s2 = "s2" - doc.s3 = "s3" - doc.full_clean() + doc.ob = TypedInnerDoc(li=[1]) + with raises(ValidationException) as exc_info: + doc.full_clean() + assert set(exc_info.value.args[0].keys()) == {"ob"} + assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} - doc.ob = TypedInnerDoc(li=[1]) - with raises(ValidationException) as exc_info: - doc.full_clean() - assert set(exc_info.value.args[0].keys()) == {"ob"} - assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} + doc.ob.st = "s" + doc.ns.append(TypedInnerDoc(li=[1, 2])) + with raises(ValidationException) as exc_info: + doc.full_clean() - doc.ob.st = "s" - doc.ns.append(TypedInnerDoc(li=[1, 2])) - with raises(ValidationException) as exc_info: + doc.ns[0].st = "s" doc.full_clean() - doc.ns[0].st = "s" - doc.full_clean() - - doc.ip = "1.2.3.4" - n = datetime.now() - doc.dt = n - assert doc.to_dict() == { - "st": "s", - "li": [1, 2, 3], - "dt": n, - "ob": { + doc.ip = "1.2.3.4" + n = datetime.now() + doc.dt = n + assert doc.to_dict() == { "st": "s", - "li": [1], - }, - "ns": [ - { + "li": [1, 2, 3], + "dt": n, + "ob": { "st": "s", - "li": [1, 2], - } - ], - "ip": "1.2.3.4", - "k1": "k1", - "k2": "k2", - "k3": "foo", - "s1": "s1", - "s2": "s2", - "s3": "s3", - "s4": "foo", - } + "li": [1], + }, + "ns": [ + { + "st": "s", + "li": [1, 2], + } + ], + "ip": "1.2.3.4", + "k1": "k1", + "k2": "k2", + "k3": "foo", + "s1": "s1", + "s2": "s2", + "s3": "s3", + "s4": "foo", + } - s = TypedDoc.search().sort(TypedDoc.st, -TypedDoc.dt, +TypedDoc.ob.st) - s.aggs.bucket("terms_agg", "terms", field=TypedDoc.k1) - assert s.to_dict() == { - "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, - "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], - } + s = doc_class.search().sort(doc_class.st, -doc_class.dt, +doc_class.ob.st) + s.aggs.bucket("terms_agg", "terms", field=doc_class.k1) + assert s.to_dict() == { + "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, + "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], + } @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10") @@ -881,3 +916,107 @@ class Doc(Document): Doc.ns.something with raises(AttributeError): Doc.ns.st.something + + +def test_pydantic_integration() -> None: + class Location(pydantic.BaseModel): + city: str + country: str + + class Address(pydantic.BaseModel): + street: str + location: Location + + class Phone(pydantic.BaseModel): + type: str + number: str + + class User(BaseESModel): + name: Annotated[str, Keyword()] = pydantic.Field(default="Unknown") + bio: str + age: int = pydantic.Field(strict=True, ge=0) + address: Address = pydantic.Field( + default=Address( + street="Unknown", location=Location(city="Unknown", country="Unknown") + ) + ) + phones: list[Phone] = pydantic.Field(default=[]) + + u = User( + name="foo", + bio="lorem ipsum", + age=30, + address=Address( + street="123 Main St.", + location=Location(city="San Francisco", country="USA"), + ), + ) + u.phones.append(Phone(type="Home", number="+12345678900")) + assert u.model_dump() == { + "name": "foo", + "bio": "lorem ipsum", + "age": 30, + "address": { + "street": "123 Main St.", + "location": { + "city": "San Francisco", + "country": "USA", + }, + }, + "phones": [ + { + "type": "Home", + "number": "+12345678900", + } + ], + "meta": { + "id": "", + "index": "", + "primary_term": 0, + "score": 0, + "seq_no": 0, + "version": 0, + }, + } + udoc = u.to_doc() + assert udoc.name == "foo" + assert udoc.bio == "lorem ipsum" + assert udoc.age == 30 + assert udoc.to_dict() == { + "name": "foo", + "bio": "lorem ipsum", + "age": 30, + "address": { + "street": "123 Main St.", + "location": { + "city": "San Francisco", + "country": "USA", + }, + }, + "phones": [ + { + "type": "Home", + "number": "+12345678900", + } + ], + } + + u2 = User.from_doc(udoc) + assert u == u2 + + with raises(pydantic.ValidationError): + _ = User() + + with raises(pydantic.ValidationError): + _ = User(name="foo", bio="lorem ipsum") + + with raises(pydantic.ValidationError): + _ = User(name="foo", bio="lorem ipsum", age=-10) + + u3 = User(bio="lorem ipsum", age=30) + assert u3.name == "Unknown" + assert u3.address.location.country == "Unknown" + assert u3.phones == [] + assert u3.to_doc().name == "Unknown" + assert u3.to_doc().address.location.country == "Unknown" + assert u3.to_doc().phones == [] diff --git a/utils/run-unasync-dsl.py b/utils/run-unasync-dsl.py index 2d4e0f089..6fbfed293 100644 --- a/utils/run-unasync-dsl.py +++ b/utils/run-unasync-dsl.py @@ -62,6 +62,7 @@ def main(check=False): "AsyncMapping": "Mapping", "AsyncFacetedSearch": "FacetedSearch", "AsyncUsingType": "UsingType", + "AsyncBaseESModel": "BaseESModel", "async_connections": "connections", "async_scan": "scan", "async_simulate": "simulate",