PHPackages                             protonemedia/laravel-cross-eloquent-search - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. protonemedia/laravel-cross-eloquent-search

ActiveLibrary[Search &amp; Filtering](/categories/search)

protonemedia/laravel-cross-eloquent-search
==========================================

Laravel package to search through multiple Eloquent models. Supports pagination, eager loading relations, single/multiple columns, sorting and scoped queries.

3.7.0(2mo ago)1.1k500.7k—6.4%80[4 PRs](https://github.com/protonemedia/laravel-cross-eloquent-search/pulls)1MITPHPPHP ^8.2|^8.3|^8.4|^8.5CI passing

Since Jul 7Pushed 2mo ago11 watchersCompare

[ Source](https://github.com/protonemedia/laravel-cross-eloquent-search)[ Packagist](https://packagist.org/packages/protonemedia/laravel-cross-eloquent-search)[ Docs](https://github.com/protonemedia/laravel-cross-eloquent-search)[ GitHub Sponsors](https://github.com/pascalbaljet)[ RSS](/packages/protonemedia-laravel-cross-eloquent-search/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (51)Used By (1)

Laravel Cross Eloquent Search
=============================

[](#laravel-cross-eloquent-search)

[![Latest Version on Packagist](https://camo.githubusercontent.com/6446930a763b5bdd29a92c11161d777fa1fb7ec88050a693a3114f2abee0c88a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f70726f746f6e656d656469612f6c61726176656c2d63726f73732d656c6f7175656e742d7365617263682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/protonemedia/laravel-cross-eloquent-search)[![run-tests](https://github.com/protonemedia/laravel-cross-eloquent-search/workflows/run-tests/badge.svg)](https://github.com/protonemedia/laravel-cross-eloquent-search/workflows/run-tests/badge.svg)[![Total Downloads](https://camo.githubusercontent.com/636a00d8590a2f6bd09e458b289e3a564bcc72f67a66c3c38e9ae8b03a17baa5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70726f746f6e656d656469612f6c61726176656c2d63726f73732d656c6f7175656e742d7365617263682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/protonemedia/laravel-cross-eloquent-search)[![Buy us a tree](https://camo.githubusercontent.com/130148911f548b001b2ac68a32c0a06559977ca60ada3bf480c72ae4ea093175/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54726565776172652d2546302539462538432542332d6c69676874677265656e)](https://plant.treeware.earth/protonemedia/laravel-cross-eloquent-search)

This Laravel package allows you to search through multiple Eloquent models. It supports sorting, pagination, scoped queries, eager load relationships, and searching through single or multiple columns.

Sponsor Us
----------

[](#sponsor-us)

[![](https://camo.githubusercontent.com/b5348f68e9a1a6ff90432d75a6692be1d604b3320ce1fcabd4b1ef29668053c4/68747470733a2f2f696e657274696175692e636f6d2f76697369742d636172642e6a7067)](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-cross-eloquent-search)

❤️ We proudly support the community by developing Laravel packages and giving them away for free. If this package saves you time or if you're relying on it professionally, please consider [sponsoring the maintenance and development](https://github.com/sponsors/pascalbaljet) and check out our latest premium package: [Inertia Table](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-cross-eloquent-search). Keeping track of issues and pull requests takes time, but we're happy to help!

Requirements
------------

[](#requirements)

- PHP 8.2 or higher
- MySQL 8.0+, PostgreSQL 12+, or SQLite 3.8+
- Laravel 11.0+

Features
--------

[](#features)

- Search through one or more [Eloquent models](https://laravel.com/docs/master/eloquent).
- Support for cross-model [pagination](https://laravel.com/docs/master/pagination#introduction).
- Search through single or multiple columns.
- Search through (nested) relationships.
- Support for Full-Text Search, even through relationships.
- Order by (cross-model) columns or by relevance.
- Use [constraints](https://laravel.com/docs/master/eloquent#retrieving-models) and [scoped queries](https://laravel.com/docs/master/eloquent#query-scopes).
- [Eager load relationships](https://laravel.com/docs/master/eloquent-relationships#eager-loading) for each model.
- In-database [sorting](https://laravel.com/docs/master/queries#ordering-grouping-limit-and-offset) of the combined result.
- Works with MySQL, PostgreSQL, and SQLite.
- Zero third-party dependencies.

> **Driver Compatibility:** Features like Full-Text Search and SOUNDS LIKE use database-specific implementations. MySQL uses native full-text indexes, PostgreSQL uses `tsquery` (requiring the `pg_trgm` extension for similarity search), and SQLite uses LIKE-based alternatives. The package automatically detects your connection and uses the appropriate strategy.

### 📺 Want to watch an implementation of this package? Rewatch the live stream (skip to 13:44 for the good stuff):

[](#-want-to-watch-an-implementation-of-this-package-rewatch-the-live-stream-skip-to-1344-for-the-good-stuff-httpsyoutubewigaaqspgsa)

Blog Post
---------

[](#blog-post)

If you want to know more about this package's background, please read [the blog post](https://protone.media/blog/search-through-multiple-eloquent-models-with-our-latest-laravel-package).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require protonemedia/laravel-cross-eloquent-search
```

Upgrading from v2 to v3
-----------------------

[](#upgrading-from-v2-to-v3)

- The `get` method has been renamed to `search`.
- The `addWhen` method has been removed in favor of [`when`](#usage).
- By default, the results are sorted by the *updated* column, which is the `updated_at` column in most cases. If you don't use timestamps, it will now use the primary key by default.

Upgrading from v1 to v2
-----------------------

[](#upgrading-from-v1-to-v2)

- The `startWithWildcard` method has been renamed to `beginWithWildcard`.
- The default order column is now evaluated by the `getUpdatedAtColumn` method. Previously it was hard-coded to `updated_at`. You still can use [another column](#sorting) to order by.
- The `allowEmptySearchQuery` method and `EmptySearchQueryException` class have been removed, but you can still [get results without searching](#getting-results-without-searching).

Usage
-----

[](#usage)

Start your search query by adding one or more models to search through. Call the `add` method with the model's class name and the column you want to search through. Then call the `search` method with the search term, and you'll get a `\Illuminate\Database\Eloquent\Collection` instance with the results.

The results are sorted in ascending order by the *updated* column by default. In most cases, this column is `updated_at`. If you've [customized](https://laravel.com/docs/master/eloquent#timestamps) your model's `UPDATED_AT` constant, or overwritten the `getUpdatedAtColumn` method, this package will use the customized column. If you don't use timestamps at all, it will use the primary key by default. Of course, you can [order by another column](#sorting) as well.

```
use ProtoneMedia\LaravelCrossEloquentSearch\Search;

$results = Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->search('howto');
```

If you care about indentation, you can optionally use the `new` method on the facade:

```
Search::new()
    ->add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->search('howto');
```

There's also a `when` method to apply certain clauses based on another condition:

```
Search::new()
    ->when($user->isVerified(), fn($search) => $search->add(Post::class, 'title'))
    ->when($user->isAdmin(), fn($search) => $search->add(Video::class, 'title'))
    ->search('howto');
```

In addition, you can use the `tap` method to tap into the searcher instance:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->tap(function ($searcher) {
        Log::info('Search configuration', ['models' => $searcher->getModelsToSearchThrough()]);
    })
    ->search('laravel');
```

### Wildcards

[](#wildcards)

By default, we split up the search term, and each keyword will get a wildcard symbol to do partial matching. Practically, this means the search term `apple ios` will result in `apple%` and `ios%`. If you want a wildcard symbol to begin with as well, you can call the `beginWithWildcard` method. This will result in `%apple%` and `%ios%`.

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->beginWithWildcard()
    ->search('os');
```

*Note: in previous versions of this package, this method was called `startWithWildcard()`.*

If you want to disable the behaviour where a wildcard is appended to the terms, you should call the `endWithWildcard` method with `false`:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->beginWithWildcard()
    ->endWithWildcard(false)
    ->search('os');
```

### Exact Match

[](#exact-match)

If you want to perform exact matching without any wildcards, you can use the `exactMatch` method. This disables both beginning and ending wildcards and uses the exact equality operator (`=`) instead of the `LIKE` operator:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->exactMatch()
    ->search('Laravel');
```

In this example, only records with the exact title "Laravel" will be returned, not titles containing "Laravel" as a substring.

### Multi-word search

[](#multi-word-search)

Multi-word search is supported out of the box. Simply wrap your phrase in double quotes.

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->search('"macos big sur"');
```

You can disable the parsing of the search term by calling the `dontParseTerm` method, which gives you the same results as using double-quotes.

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->dontParseTerm()
    ->search('macos big sur');
```

### Sorting

[](#sorting)

If you want to sort the results by another column, you can pass that column to the `add` method as a third parameter. Call the `orderByDesc` method to sort the results in descending order.

```
Search::add(Post::class, 'title', 'published_at')
    ->add(Video::class, 'title', 'released_at')
    ->orderByDesc()
    ->search('learn');
```

You can call the `orderByRelevance` method to sort the results by the number of occurrences of the search terms. Imagine these two sentences:

- Apple introduces iPhone 13 and iPhone 13 mini
- Apple unveils new iPad mini with breakthrough performance in stunning new design

If you search for *Apple iPad*, the second sentence will come up first, as there are more matches of the search terms.

```
Search::add(Post::class, 'title')
    ->beginWithWildcard()
    ->orderByRelevance()
    ->search('Apple iPad');
```

Ordering by relevance is *not* supported if you're searching through (nested) relationships.

To sort the results by model type, you can use the `orderByModel` method by giving it your preferred order of the models:

```
Search::new()
    ->add(Comment::class, ['body'])
    ->add(Post::class, ['title'])
    ->add(Video::class, ['title', 'description'])
    ->orderByModel([
        Post::class, Video::class, Comment::class,
    ])
    ->search('Artisan School');
```

### Pagination

[](#pagination)

We highly recommend paginating your results. Call the `paginate` method before the `search` method, and you'll get an instance of `\Illuminate\Contracts\Pagination\LengthAwarePaginator` as a result. The `paginate` method takes three (optional) parameters to customize the paginator. These arguments are [the same](https://laravel.com/docs/master/pagination#introduction) as Laravel's database paginator.

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')

    ->paginate()
    // or
    ->paginate($perPage = 15, $pageName = 'page', $page = 1)

    ->search('build');
```

You may also use [simple pagination](https://laravel.com/docs/master/pagination#simple-pagination). This will return an instance of `\Illuminate\Contracts\Pagination\Paginator`, which is not length aware:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')

    ->simplePaginate()
    // or
    ->simplePaginate($perPage = 15, $pageName = 'page', $page = 1)

    ->search('build');
```

#### Query String Parameters

[](#query-string-parameters)

To retain query string parameters in pagination links, use the `withQueryString` method. Without arguments, it uses the current request's query string:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->paginate(15)
    ->withQueryString()  // Uses request()->query()
    ->search('build');
```

Or pass a custom array of parameters:

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->paginate(15)
    ->withQueryString(['filter' => 'active', 'sort' => 'date'])
    ->search('build');
```

### Constraints and scoped queries

[](#constraints-and-scoped-queries)

Instead of the class name, you can also pass an instance of the [Eloquent query builder](https://laravel.com/docs/master/eloquent#retrieving-models) to the `add` method. This allows you to add constraints to each model.

```
Search::add(Post::published(), 'title')
    ->add(Video::where('views', '>', 2500), 'title')
    ->search('compile');
```

### Multiple columns per model

[](#multiple-columns-per-model)

You can search through multiple columns by passing an array of columns as the second argument.

```
Search::add(Post::class, ['title', 'body'])
    ->add(Video::class, ['title', 'subtitle'])
    ->search('eloquent');
```

### Search through (nested) relationships

[](#search-through-nested-relationships)

You can search through (nested) relationships by using the *dot* notation:

```
Search::add(Post::class, ['comments.body'])
    ->add(Video::class, ['posts.user.biography'])
    ->search('solution');
```

### Full-Text Search

[](#full-text-search)

You can use the `addFullText` method to search using your database's native full-text search capabilities:

```
Search::new()
    ->add(Post::class, 'title')
    ->addFullText(Video::class, 'title', ['mode' => 'boolean'])
    ->addFullText(Blog::class, ['title', 'subtitle', 'body'], ['mode' => 'boolean'])
    ->search('framework -css');
```

If you want to search through relationships, you need to pass in an array where the array key contains the relation, while the value is an array of columns:

```
Search::new()
    ->addFullText(Page::class, [
        'posts' => ['title', 'body'],
        'sections' => ['title', 'subtitle', 'body'],
    ])
    ->search('framework -css');
```

### Sounds like

[](#sounds-like)

Search for terms that sound similar using the `soundsLike` method:

```
Search::new()
    ->add(Post::class, 'framework')
    ->add(Video::class, 'framework')
    ->soundsLike()
    ->search('larafel');
```

### Eager load relationships

[](#eager-load-relationships)

Eager loading relationships is fully supported as well.

```
Search::add(Post::with('comments'), 'title')
    ->add(Video::with('likes'), 'title')
    ->search('guitar');
```

### Getting results without searching

[](#getting-results-without-searching)

You call the `search` method without a term or with an empty term. In this case, you can discard the second argument of the `add` method. With the `orderBy` method, you can set the column to sort by (previously the third argument):

```
Search::add(Post::class)
    ->orderBy('published_at')
    ->add(Video::class)
    ->orderBy('released_at')
    ->search();
```

### Counting records

[](#counting-records)

You can count the number of results with the `count` method:

```
Search::add(Post::published(), 'title')
    ->add(Video::where('views', '>', 2500), 'title')
    ->count('compile');
```

### Model Identifier

[](#model-identifier)

You can use the `includeModelType` method to add the model type to the search result.

```
Search::add(Post::class, 'title')
    ->add(Video::class, 'title')
    ->includeModelType()
    ->paginate()
    ->search('foo');

// Example result with model identifier.
{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "video_id": null,
            "title": "foo",
            "published_at": null,
            "created_at": "2021-12-03T09:39:10.000000Z",
            "updated_at": "2021-12-03T09:39:10.000000Z",
            "type": "Post",
        },
        {
            "id": 1,
            "title": "foo",
            "subtitle": null,
            "published_at": null,
            "created_at": "2021-12-03T09:39:10.000000Z",
            "updated_at": "2021-12-03T09:39:10.000000Z",
            "type": "Video",
        },
    ],
    ...
}
```

By default, it uses the `type` key, but you can customize this by passing the key to the method.

You can also customize the `type` value by adding a public method `searchType()` to your model to override the default class base name.

```
class Video extends Model
{
    public function searchType()
    {
        return 'awesome_video';
    }
}

// Example result with searchType() method.
{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "video_id": null,
            "title": "foo",
            "published_at": null,
            "created_at": "2021-12-03T09:39:10.000000Z",
            "updated_at": "2021-12-03T09:39:10.000000Z",
            "type": "awesome_video",
        }
    ],
    ...
```

### Standalone parser

[](#standalone-parser)

You can use the parser with the `parseTerms` method:

```
$terms = Search::parseTerms('drums guitar');
```

You can also pass in a callback as a second argument to loop through each term:

```
Search::parseTerms('drums guitar', function($term, $key) {
    //
});
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information about what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Other Laravel packages
----------------------

[](#other-laravel-packages)

- [Inertia Modal](https://inertiaui.com/inertia-modal/docs/introduction): With Inertia Modal, you can easily open any route in a Modal or Slideover without having to change anything about your existing routes or controllers.

- [`Inertia Table`](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-cross-eloquent-search): The Ultimate Table for Inertia.js with built-in Query Builder.
- [`Laravel Blade On Demand`](https://github.com/protonemedia/laravel-blade-on-demand): Laravel package to compile Blade templates in memory.
- [`Laravel Eloquent Scope as Select`](https://github.com/protonemedia/laravel-eloquent-scope-as-select): Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes and constraints by adding them as a subquery.
- [`Laravel FFMpeg`](https://github.com/protonemedia/laravel-ffmpeg): This package provides an integration with FFmpeg for Laravel. The storage of the files is handled by Laravel's Filesystem.
- [`Laravel MinIO Testing Tools`](https://github.com/protonemedia/laravel-minio-testing-tools): Run your tests against a MinIO S3 server.
- [`Laravel Mixins`](https://github.com/protonemedia/laravel-mixins): A collection of Laravel goodies.
- [`Laravel Paddle`](https://github.com/protonemedia/laravel-paddle): Paddle.com API integration for Laravel with support for webhooks/events.
- [`Laravel Task Runner`](https://github.com/protonemedia/laravel-task-runner): Write Shell scripts like Blade Components and run them locally or on a remote server.
- [`Laravel Verify New Email`](https://github.com/protonemedia/laravel-verify-new-email): This package adds support for verifying new email addresses: when a user updates its email address, it won't replace the old one until the new one is verified.
- [`Laravel XSS Protection`](https://github.com/protonemedia/laravel-xss-protection): Laravel Middleware to protect your app against Cross-site scripting (XSS). It sanitizes request input, and it can sanitize Blade echo statements.

### Security

[](#security)

If you discover any security-related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Pascal Baljet](https://github.com/protonemedia)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

Treeware
--------

[](#treeware)

This package is [Treeware](https://treeware.earth). If you use it in production, we ask that you [**buy the world a tree**](https://plant.treeware.earth/pascalbaljetmedia/laravel-cross-eloquent-search) to thank us for our work. By contributing to the Treeware forest, you'll create employment for local families and restore wildlife habitats.

###  Health Score

70

—

ExcellentBetter than 100% of packages

Maintenance84

Actively maintained with recent releases

Popularity61

Solid adoption and visibility

Community30

Small or concentrated contributor base

Maturity86

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 80.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~46 days

Recently: every ~196 days

Total

45

Last Release

84d ago

Major Versions

0.3.0 → 1.0.02020-07-14

1.9.0 → 2.0.02021-01-29

2.7.1 → 3.x-dev2022-02-16

PHP version history (9 changes)0.1.0PHP ^7.4

1.5.0PHP ^7.4|^8.0

2.5.0PHP ^8.0|^8.1

3.1.0PHP ^8.0|^8.1|^8.2

3.2.0PHP ^8.1|^8.2

3.3.0PHP ^8.1|^8.2|^8.3

3.4.0PHP ^8.2|^8.3

3.5.0PHP ^8.2|^8.3|^8.4

3.7.0PHP ^8.2|^8.3|^8.4|^8.5

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8403149?v=4)[Pascal Baljet](/maintainers/pascalbaljet)[@pascalbaljet](https://github.com/pascalbaljet)

---

Top Contributors

[![pascalbaljet](https://avatars.githubusercontent.com/u/8403149?v=4)](https://github.com/pascalbaljet "pascalbaljet (85 commits)")[![realpascalbotjet](https://avatars.githubusercontent.com/u/262015488?v=4)](https://github.com/realpascalbotjet "realpascalbotjet (7 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![alissn](https://avatars.githubusercontent.com/u/26966142?v=4)](https://github.com/alissn "alissn (3 commits)")[![mewejo](https://avatars.githubusercontent.com/u/1097093?v=4)](https://github.com/mewejo "mewejo (1 commits)")[![mrkalmdn](https://avatars.githubusercontent.com/u/10385316?v=4)](https://github.com/mrkalmdn "mrkalmdn (1 commits)")[![SebKay](https://avatars.githubusercontent.com/u/1873695?v=4)](https://github.com/SebKay "SebKay (1 commits)")[![tushargugnani](https://avatars.githubusercontent.com/u/5244323?v=4)](https://github.com/tushargugnani "tushargugnani (1 commits)")[![bradyrenting](https://avatars.githubusercontent.com/u/14994117?v=4)](https://github.com/bradyrenting "bradyrenting (1 commits)")[![Daanra](https://avatars.githubusercontent.com/u/6588838?v=4)](https://github.com/Daanra "Daanra (1 commits)")[![gazben](https://avatars.githubusercontent.com/u/3780285?v=4)](https://github.com/gazben "gazben (1 commits)")

---

Tags

laravellaravel-packagemysqlphpsearchsearchingprotonemedialaravel-cross-eloquent-search

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/protonemedia-laravel-cross-eloquent-search/health.svg)

```
[![Health](https://phpackages.com/badges/protonemedia-laravel-cross-eloquent-search/health.svg)](https://phpackages.com/packages/protonemedia-laravel-cross-eloquent-search)
```

###  Alternatives

[mailerlite/laravel-elasticsearch

An easy way to use the official PHP ElasticSearch client in your Laravel applications.

934529.3k2](/packages/mailerlite-laravel-elasticsearch)[jeroen-g/explorer

Next-gen Elasticsearch driver for Laravel Scout.

397612.3k](/packages/jeroen-g-explorer)[swisnl/laravel-fulltext

Fulltext indexing and searching for Laravel

184104.5k6](/packages/swisnl-laravel-fulltext)[romanstruk/manticore-scout-engine

Laravel Manticore Scout Engine

4818.1k](/packages/romanstruk-manticore-scout-engine)[statamic-rad-pack/meilisearch

meilisearch search driver for Statamic

1661.7k](/packages/statamic-rad-pack-meilisearch)[internachi/blade-alpine-instantsearch

Algolia instant search as Blade/Alpine.js components

1940.9k](/packages/internachi-blade-alpine-instantsearch)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
