PHP Logo PHP Composer のインストールと使い方

PHP ライブラリ(パッケージ)をプロジェクト単位に管理するツール Composer の使い方や Mac で Homebrew を使って Composer をインストールする方法の覚書です。version 2 へのアップグレード方法を追加しました。

Composer 公式サイト:https://getcomposer.org/

Composer Github:https://github.com/composer/composer

Composer 日本語訳:https://kohkimakimoto.github.io/

2020/10/24 にバージョン2(Composer 2.0)がリリースされています。

更新日:2022年03月11日

作成日:2020年03月09日

Composer のインストール

Mac の場合 Homebrew を使って簡単に Composer をインストールすることができます。

関連項目: Homebrew のインストールと使い方

Composer のインストールはローカルにインストールする方法とグローバルにインストールする方法の2通りがあります。

グローバルにインストールすると、パスが通っているので php コマンド経由ではなく直接 composer コマンドにアクセスできます。

  • ローカル(Locally):プロジェクト配下(プロジェクトごと)にインストールする方法
  • グローバル(Globally):好きな場所(/usr/local/bin/ などパスが通っている場所)にインストールする方法(またはインストール後にパスを通す)

Homebrew を使ってインストールするとグローバル(Globally)にインストールされます。

brew search でキーワードに composer を指定してフォーミュラを検索します。

$ brew search composer   return
==> Formulae
composer  # Composer のフォーミュラ

brew install を実行して composer をインストールします。

$ brew install composer   return
Updating Homebrew...
  ・・・省略(Homebrew のアップデートなど)・・・  
==> Downloading https://getcomposer.org/download/1.9.3/composer.phar
######################################################################## 100.0%
🍺  /usr/local/Cellar/composer/1.9.3: 3 files, 1.8MB, built in 7 seconds

composer コマンドを実行して Composer がインストールされたことを確認します。以下のようにバージョンやヘルプが表示されます。

$ composer   return
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.9.3 2020-02-04 12:58:49  # Composer のバージョン

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --profile                  Display timing and memory usage information
      --no-plugins               Whether to disable plugins.
  ・・・以下省略・・・

または単に -V オプションでバージョンのみを確認することもができます。

$ composer -V   return
Composer version 1.9.3 2020-02-04 12:58:49

Homebrew を使ってインストールすると Composer は /usr/local/Cellar/ にインストールされます。

# brew でインストールしたパッケージのインストール先
$ ls /usr/local/Cellar/  return
composer	libidn2		libunistring	webp
gettext		libpng		openssl@1.1	wget
jpeg		libtiff		tree

# tree コマンドで確認
$ tree /usr/local/Cellar/composer/  return
/usr/local/Cellar/composer/
└── 1.9.3
    ├── INSTALL_RECEIPT.json
    └── bin
        └── composer

2 directories, 2 files

Composer の基本的な使い方

Composer を使用するには composer.json というファイルを作成し、composer install コマンドなどでライブラリをインストールします。

composer.json

Composer を使うには、プロジェクトのディレクトリを作成(または既存のディレクトリを使用)し、以下のような composer.json というファイルを作成しディレクトリに配置します。

composer.json はインストールするライブラリの情報を JSON フォーマットで記述するファイルです(The composer.json Schema)。

composer.json は手動で作成してもいいですし、composer init コマンドで作成することもできます。また、composer require コマンドを使えば composer.json の作成とライブラリのインストールもまとめて行うことができます。

composer.json
{
  "require": {
    "パッケージ名": "バージョン"
  }
}

composer.json には以下の情報を指定します。

  • require キーでインストールするライブラリのパッケージ名とバージョン情報(制約)を定義。
  • 必要に応じてその他のキーを定義。

ライブラリのパッケージ名やバージョンの情報は Packagist というサイトで確認することができます。

以下はプロジェクトにロギングを行うためのライブラリ Monolog を導入する例です。

Composer のドキュメント(基本的な使い方 Basic usage)からの引用です。

composer.json の例
{
  "require": {
    "monolog/monolog": "1.0.*"  // "パッケージ名": "バージョン"
  }
}

複数のパッケージを指定することもできます。以下は PHPMailer と oauth2-google をまとめてインストールする場合の例です。

composer.json の例
{
    "require": {
        "phpmailer/phpmailer": "^6.1",
        "league/oauth2-google": "^3.0"
    }
}

【パッケージ名】

パッケージ名は「ベンダー名/プロジェクト名」のようにベンダー名とプロジェクト名で構成されています。上記の「monolog/monolog」の例のようにベンダー名とプロジェクト名が同じ場合もあります。

【バージョン】

バージョンには、パッケージの特定のバージョンやその範囲(制約)を指定することができます。

バージョンの範囲を指定すれば、composer update コマンドでアップデートをすると、指定した範囲の(最新の)バージョンに更新することができます。

バージョンの表記は「メジャーバージョン . マイナーバージョン . パッチ」のようになっています。

以下はバージョン(制約)の指定方法の例(一部)です。

バージョン制約の指定例 Writing Version Constraints
タイプ 意味
レンジ
  • >=1.0 (1.0 以上)
  • >=1.0 <2.0(1.0 以上 2.0 未満)
  • >=1.0 <1.1 || >=1.2(1.0 以上 1.1 未満 または 1.2 以上)
比較演算子(>, >=, <, <=, !=)を使って有効なバージョンの範囲を指定できます。カンマ区切りは論理積(AND)、パイプ | は論理和(OR)として扱われます。また、AND は OR より優先されます。
ハイフン
  • 1.0 - 2.0 は >=1.0.0 <2.1 と同等
  • 1.0.0 - 2.1.0 は >=1.0.0 <=2.1.0. と同等
ハイフンを使って範囲を指定することができます。右側に部分的なバージョンを指定した場合は、ワイルドカードとして扱われます。例えば、右側に 2.0 を指定すると 2.0.* と解釈されます。
ワイルドカード ワイルドカード(*)を使って範囲を指定することができます。1.0.* は >=1.0 <1.1 と同等です。
チルダ
  • ~1.2 は >=1.2 <2.0.0 と同等
  • ~1.2.3 は >=1.2.3 <1.3.0 と同等
チルダ(~)を使うと、指定した最後の桁のみの更新を許可することができます。
キャレット
  • ^1.2.3 は >=1.2.3 <2.0.0 と同等(1.2.3 以上の最新のバージョン。但し 2.0.0 未満)
  • バージョンが 1未満の場合: ^0.3 は >=0.3.0 <0.4.0 と扱われます
キャレット(^)を使うと後方互換性を維持する範囲で更新されます。

また、必要に応じて PHP のバージョンや extension を指定することもできます(Package links)。

composer.json
{
  "require" : {
    "php" : "^5.5 || ^7.0",
    "ext-mbstring": "*"
  }
}

ライブラリのインストール

composer.json を配置したプロジェクトのディレクトリで composer install コマンドを実行するとライブラリ(依存ファイル)をインストールすることができます。

$ cd path/to/project  return  #プロジェクトのディレクトリへ移動

$ composer install  return  #ライブラリをインストール
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing psr/log (1.1.2): Loading from cache
  - Installing monolog/monolog (1.25.3): Loading from cache
monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
・・・中略・・・
Writing lock file
Generating autoload files

インストールが完了すると、プロジェクトのディレクトリには composer.lock というファイルと vendor というディレクトリが追加されます。

vendor ディレクトリの中には autoload.php というファイルとそれに関連する composer ディレクトリ及びインストールしたライブラリ(この例の場合は monolog)が保存されています。

$ tree  return # tree コマンドで内容を確認
.
├── composer.json
├── composer.lock
└── vendor
    ├── autoload.php
    ├── composer
    │   ├── ClassLoader.php
    │   ├── LICENSE
    │   ├── autoload_classmap.php
    │   ├── autoload_namespaces.php
    │   ├── autoload_psr4.php
    │   ├── autoload_real.php
    │   ├── autoload_static.php
    │   └── installed.json
    ├── monolog
    │   └── monolog
    │       ├── CHANGELOG.md
    │       ├── LICENSE
    │       ├── README.md
    │       ├── composer.json
    │       └── src
    │           └── Monolog
    ・・・中略・・・

18 directories, 125 files
composer.lock

インストールが完了すると、Composer はインストールしたライブラリとそのバージョンの情報を composer.lock ファイルに記述(保存)し、その情報をもとにプロジェクトを特定のバージョンにロックします。

初めてインストールする(composer install コマンドを実行する)場合など、プロジェクト内に composer.lock ファイルが存在しない場合は Composer は composer.json の情報をもとにその最新バージョンのライブラリをインストールします。

既に composer.lock ファイルが存在する場合は、composer.lock に記述されているバージョンをインストールします。

以下は composer.lock の例です。この例の場合、composer.json のパッケージバージョンには 1.0.* と記述しているのでバージョン 1.0.2 がインストールされているのがわかります(11行目)。

composer.lock
{
  "_readme": [
    "This file locks the dependencies of your project to a known state",
    "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
    "This file is @generated automatically"
  ],
  "content-hash": "bef20e1ca06eac6c027a5bc95193a923",
  "packages": [
    {
      "name": "monolog/monolog",
      "version": "1.0.2",
      "source": {
          "type": "git",
          "url": "https://github.com/Seldaek/monolog.git",
          "reference": "b704c49a3051536f67f2d39f13568f74615b9922"
      },
      "dist": {
          "type": "zip",
          "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b704c49a3051536f67f2d39f13568f74615b9922",
          "reference": "b704c49a3051536f67f2d39f13568f74615b9922",
          "shasum": ""
      },
      "require": {
          "php": ">=5.3.0"
      },
      "type": "library",
      "autoload": {
          "psr-0": {
              "Monolog": "src/"
          }
      },
      ・・・以下省略・・・
}
ライブラリの更新

composer.lock が存在する場合、composer install コマンドを実行してもプロジェクトは特定のバージョンにロックされるので、ライブラリを更新(アップデート)するには composer update コマンドを実行します。

composer update コマンドは composer.json で指定したバージョン(の範囲)をもとに更新を実行し、composer.lock ファイルも更新します。

composer update コマンドの実行は composer.lock を削除して、composer install コマンドを実行するのと同じことになります。

特定のライブラリのみを更新する場合は、composer update コマンドに対象のライブラリを指定します。

以下は composer.json のバージョンを 1.0.* から 1.2.* に変更してからアップデートを実施した例です。

$ composer update monolog/monolog    return
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
  - Updating monolog/monolog (1.0.2 => 1.2.1): Downloading (100%)         
Writing lock file  # composer.lock ファイルも更新される
Generating autoload files
Packagist

Packagist というサイトには Composer でインストールできるパッケージが登録されています。このサイトでライブラリを検索して、そのパッケージ名やバージョンなどの情報を確認することができます。

以下は PHPMailer というライブラリを検索している例です。

当該ページではパッケージ名やバージョンなどを確認することができます。

ライブラリを使う / Autoloading

Composer はライブラリをインストールする際に vendor/autoload.php というファイルを生成し、オートローディング(自動読み込み)機能を提供してくれます(Autoloading)。

このため autoload.php を読み込ませるだけでインストールしたライブラリが使えるようになります。

以下はインストールした Monolog を使用するファイル test.php の例です。

以下の例では2行目で require と __DIR__ を使って autoload.php を読み込んでいます。

test.php
<?php 
require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

.
├── composer.json
├── composer.lock
├── test.php  # 上記のテスト用ファイル
└── vendor
    ├── autoload.php

以下は上記のファイル(test.php)を実行する例です。

$ php test.php   return

上記を実行すると、問題がなければカレントディレクトリに app.log という以下のような内容のファイルが生成されます。

app.log の例
[2020-03-09 01:50:19] name.WARNING: Foo [] []

コマンドライン

Composer にはいろいろなコマンドライン(サブコマンド)やそのオプションが用意されています。

composer コマンド(引数なし)を実行すると、オプションやサブコマンドを確認することができます。

以下は全てのコマンドで利用できるグローバルオプションの例です。

グローバルオプション(一部抜粋)
オプション 意味
--help (-h) ヘルプ情報を表示
--quiet (-q) メッセージを表示しない
--no-interaction (-n) インタラクティブな質問を表示しない
--version (-V) アプリケーションのバージョンを表示

以下は init サブコマンドのヘルプを表示する例です。

$ composer init -h  return
Usage:
  init [options]

Options:
      --name=NAME                Name of the package
      --description=DESCRIPTION  Description of package
      --author=AUTHOR            Author name of package
      --type[=TYPE]              Type of package (e.g. library, project, metapackage, composer-plugin)
      --homepage=HOMEPAGE        Homepage of package
      --require=REQUIRE          Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0" (multiple values allowed)
      ・・・中略・・・
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
以下省略

以下はコマンドの例です。

Command-line interface / Commands の例
コマンド 説明
composer install composer.json で指定されたバージョンのパッケージをインストールします。但し、composer.lock がある場合は、そこに指定してあるバージョンをインストールします。
composer update [パッケージ名] composer.json で指定されたバージョンをもとにパッケージを最新版に更新します。その際に composer.lock も更新します。パッケージ名を指定しないと、インストール済みのパッケージを全て更新します。
composer init 対話的に composer.json を生成します。パッケージのインストールも続けて実行することもできます。
composer require 新しいパッケージを composer.json に追加し、ライブラリをインストールします。

composer init

init サブコマンドを使うと対話的に入力して composer.json ファイルを作成することができます。また、対話的入力のオプションの選択でライブラリも続けてインストールすることもできます。

以下は my_project というディレクトリを作成して、composer init コマンドを使って対話的に composer.json を作成する例です。

対話的に入力していき、「Do you confirm generation?」で「yes」と入力して return を押すと composer.json が生成されます(54行目)

続く「Would you like to install dependencies now?」で「yes」と入力して return を押すとライブラリ(依存ファイル)がインストールされます。

※但し、この例の場合では Package name (11行目)で「monolog/monolog」と入力してしまうと「Root package 'monolog/monolog' cannot require itself in its composer.json」のようなエラーが表示され、インストールはされません。name と require は別の名前を指定する必要があるようです。

$ mkdir my_project  return # プロジェクトのディレクトリを作成

$ cd my_project/  return # プロジェクトのディレクトリへ移動

$ composer init  return # 対話的に composer.json を作成
                                
  Welcome to the Composer config generator  
                                            
This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [xxxxxx/my_project]: monolog/my_project   return # パッケージ名(任意の名前)を入力
Description []:   return
Author [, n to skip]: n  return # n を入力してスキップ
Minimum Stability []:   return
Package Type (e.g. library, project, metapackage, composer-plugin) []:   return
License []:   return

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? yes   return # yes を入力
Search for a package: monolog     return # 検索するライブラリ monolog を入力

Found 15 packages matching monolog # パッケージの候補が表示される

   [0] monolog/monolog 
   [1] symfony/monolog-bundle 
   [2] symfony/monolog-bridge 
   [3] easycorp/easy-log-handler 
   [4] bramus/monolog-colored-line-formatter 
   [5] maxbanton/cwh 
   [6] wazaari/monolog-mysql 
   [7] theorchard/monolog-cascade 
   [8] flynsarmy/slim-monolog 
   [9] tylercd100/lern 
  [10] inpsyde/wonolog 
  [11] rahimi/monolog-telegram 
  [12] mero/yii2-monolog 
  [13] logentries/logentries-monolog-handler 
  [14] kdyby/monolog 

Enter package # to add, or the complete package name if it is not listed: 0  return # 0 を入力
Enter the version constraint to require (or leave blank to use the latest version):1.2.*   return  #何も入力しなければ最新バージョン
Search for a package:   return
Would you like to define your dev dependencies (require-dev) interactively [yes]?   return
Search for a package:   return

{
    "name": "monolog/my_project",
    "require": {
        "monolog/monolog": "1.2.*"
    }
}

Do you confirm generation [yes]? yes  return # yes を入力(ファイルが生成される)
Would you like to install dependencies now [yes]? yes  return # yes を入力(インストールされる)
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing monolog/monolog (1.2.1): Loading from cache
   ・・・中略・・・
Writing lock file
Generating autoload files

インストールするライブラリの名前とバージョン(require の値)がわかっていて、require 以外を設定する必要がない場合はもっと簡単に composer.json を作成することができます。

以下は --require オプションにライブラリ名とバージョンを指定して、-n オプション(対話的にしない)を指定して composer.json を作成する例です。

--require オプションは「foo/bar:1.0.0」、「foo/bar=1.0.0」、「 "foo/bar 1.0.0"」のいずれかの書式で指定できます。(multiple values allowed)

$ composer init --require monolog/monolog:1.2.* -n return #composer.json を生成

$ composer install return # install コマンドでライブラリをインストール
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing monolog/monolog (1.2.1): Loading from cache
   ・・・中略・・・
Writing lock file
Generating autoload files

composer require

require サブコマンドは composer.json ファイルに新しいパッケージを追加し、ライブラリをインストールします。

composer.json ファイルが存在しない場合は新たに composer.json ファイルを作成します。

引数を指定しない場合は、パッケージを検索するかどうかを対話的に聞いてきます。

以下は空のディレクトリで require サブコマンドを引数無しで実行する例です。composer.json ファイルが生成され、ライブラリがインストールされます。

以下の例ではバージョンを指定していないので、最新のバージョンがインストールされます(13行目)。

$ composer require  return
Search for a package: monolog   return # 検索するライブラリ monolog を入力
Found 15 packages matching monolog
   [0] monolog/monolog 
   [1] symfony/monolog-bundle 
   [2] symfony/monolog-bridge 
   [3] easycorp/easy-log-handler 
   [4] bramus/monolog-colored-line-formatter 
   ・・・中略・・・
  [14] kdyby/monolog 

Enter package # to add, or the complete package name if it is not listed: 0  return # 0 を入力
Enter the version constraint to require (or leave blank to use the latest version):   return  #何も入力しない
Using version ^1.25 for monolog/monolog   #最新のバージョンが選択される
Search for a package:   return
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing psr/log (1.1.2): Loading from cache
  - Installing monolog/monolog (1.25.3): Loading from cache
monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
   ・・・中略・・・
Writing lock file
Generating autoload files

対話的にインストールしたくない場合は、引数に(require の)値を指定します。

以下を実行すると composer.json ファイルが作成されライブラリがインストールされます。

$ composer require "monolog/monolog:1.2.*"  return
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing monolog/monolog (1.2.1): Loading from cache
   ・・・中略・・・
Writing lock file
Generating autoload files

以下は PHPMailer をバージョンを指定せずにインストールする例です。

$ composer require phpmailer/phpmailer  return  # PHPMailer をインストール
Using version ^6.1 for phpmailer/phpmailer  # 最新のバージョンが適用される
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing phpmailer/phpmailer (v6.1.4): Loading from cache

Writing lock file
Generating autoload files 

関連ページ:PHPMailer の使い方

version 2 へのアップグレード

久しぶりに commposer を使ったら以下のような Warning が出ていて調べたところ、version 2 が 2020/10 に出ていました。

Warning from https://repo.packagist.org: You are using an outdated version of Composer. Composer 2 is now available and you should upgrade. See https://getcomposer.org/2

上記リンクで確認したところ、self-update コマンドでアップグレードできるようなので試しましたが、この環境の場合以下のようなエラー(zlib_decode(): data error)になりアップグレードできませんでした。

$ composer self-update
Updating to version 2.0.13 (stable channel).
   Downloading (100%)         
Failed to decode response: zlib_decode(): data error
Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info
Downloading (100%)         
                            
  [ErrorException]           
  zlib_decode(): data error  
                             

self-update [-r|--rollback] [--clean-backups] [--no-progress] [--update-keys] [--stable] [--preview] [--snapshot] [--set-channel-only] [--] [<version>]

調べたところ、このエラーの場合、clear-cache で改善するかもしれないとあったので以下を実行後、再度 self-update を実行しましたが同じエラーでアップグレードできませんでした。

$ composer clear-cache
Cache directory does not exist (cache-vcs-dir): 
Clearing cache (cache-repo-dir): /Users/foo/.composer/cache/repo
Clearing cache (cache-files-dir): /Users/foo/.composer/cache/files
Clearing cache (cache-dir): /Users/foo/.composer/cache
All caches cleared.

アンインストールして再インストール

この環境の場合、Mac の Homebrew を使ってインストールしているので、Homebrew を使ってアンインストール後、再インストールしました。

アンインストール・再インストールではなく、「brew upgrade composer」でアップグレードしても良かったかもしれません。

// フォーミュラ名の確認 → composer
$ brew list
composer	libidn2		libunistring	tree
gettext		libpng		nodebrew	webp
jpeg		libtiff		openssl@1.1	wget

// composer をアンインストール
$ brew uninstall composer
Uninstalling /usr/local/Cellar/composer/1.9.3... (3 files, 1.8MB)

// アンインストールされているかを確認
$ brew list
gettext		libpng		nodebrew	webp
jpeg		libtiff		openssl@1.1	wget
libidn2		libunistring	tree

// composer をインストール
$ brew install composer
Updating Homebrew...
==> Downloading https://ghcr.io/v2/homebrew/portable-ruby/portable-ruby/blobs/sha256:b065e5e3783954f3e65dxxxxx7ca51649bfcfa21b356b0dd70490f74c6bd86
######################################################################## 100.0%
==> Pouring portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
acl2                       haruhi-dl                  organize-tool

・・・中略・・・

==> Downloading https://getcomposer.org/download/2.0.13/composer.phar
######################################################################## 100.0%
🍺  /usr/local/Cellar/composer/2.0.13: 3 files, 2.1MB, built in 3 seconds
==> `brew cleanup` has not been run in 30 days, running now...

・・・中略・・・

Pruned 2 symbolic links from /usr/local

// composer のバージョンの確認
$ composer --version
Composer version 2.0.13 2021-04-27 13:11:08
~ $ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/