| sieve-connect(1) | sieve-connect(1) |
sieve-connect - کلاینت خط فرمانی managesieve
خلاصه دستور (SYNOPSIS)
sieve-connect [-s <hostname>] [-p <portspec>] [-u <user>] [a <authzid>]
[-m <authmech>] [-r realm] [-e execscript]
[... longopts ...]
sieve-connect [--localsieve <script>] [--remotesieve <script>]
[--debug] [--dumptlsinfo]
[--server <hostname>] [--port <portspec>] [--4|--6]
[--user <authentication_id>] [--authzid <authzid>]
[--realm <realm>] [--passwordfd <n>]
[--clientkey <file> --clientcert <file>]|[--clientkeycert <file>]
[--notlsverify|--nosslverify]
[--tlscertfingerprint|--sslcertfingerprint <dgsttype:digest>]
[--tlscapath <ca_directory>]|[--tlscafile <ca_file>]
[--tlshostname <hostname>]
[--noclearauth] [--noclearchan] [--clearchan]
[--authmech <mechanism>]
[--ignoreserverversion]
[--upload|--download|--list|--delete|--checkscript|--edit|
--activate|--deactivate]|[--exec <script>]
[--help|--man]
توضیحات (DESCRIPTION)
sieve-connect یک کلاینت برای پروتکل "MANAGESIEVE" است؛ پروتکلی مشخصشده در RFC که برای مدیریت و دستکاری اسکریپتهای "Sieve" در یک مخزن به کار میرود. به بیان سادهتر، sieve-connect به شما امکان میدهد تا فایلهای قوانین پالایش ایمیل خود را روی یک سرور ایمیل کنترل کنید.
sieve-connect میتواند با یک کنش (action) از خط فرمان فراخوانی شود تا اسکریپتنویسی عملیاتهای یکباره آسان گردد، میتواند با یک فایل اسکریپت تغذیه شود، یا میتوان آن را به حال خود گذاشت تا وارد یک حلقهٔ دستوری تعاملی شود؛ جایی که از تکمیل خودکار با کلید تب (در صورت در دسترس بودن ماژول پرل پشتیبان) و ناوبری پایهای در فایلسیستم محلی به سبک کلاینتهای "FTP" پشتیبانی میکند.
sieve-connect از بهکارگیری "TLS" از طریق دستور "STARTTLS"، از جمله احراز هویت از طریق گواهیهای کلاینت پشتیبانی میکند. "sieve-connect" همچنین از هر سازوکار "SASL" که کتابخانهٔ Authen::SASL::Perl شما فراهم کند پشتیبانی مینماید، مادامی که نیازی به لایههای حفاظتی SASL نداشته باشند.
در حالت تعاملی (Interactive)، دستور "help" در دسترس است. پارامترهای دستوری که حاوی کاراکتر "%" هستند بررسی میشوند تا مشخص شود آیا با %KEYWORD همخوانی دارند یا خیر، که در آن "KEYWORD" همواره با حروف بزرگ است. فهرست کلیدواژهها را میتوان با دستور "keywords" دریافت کرد و شامل مواردی نظیر %DATE، %USER و غیره است.
گزینهها (OPTIONS)
نامهای گزینهها میتوانند به صورت کوتاهترین پیشوند یکتا مشخص شوند.
نام پیشفرض اسکریپت sieve دوردست، همان نام اسکریپت sieve محلی در نظر گرفته میشود؛ بنابراین اگر فقط به یکی نیاز است، کافی است نام محلی را تعیین کنید. تعیین اینچنینی پیشفرضها یک تصمیم عامدانه بوده است تا کاربران را به تامل دربارهٔ نامها در فایلسیستم محلی وادارد. هیچ نام اسکریپت پیشفرضی وجود ندارد.
گزینهٔ --debug ردگیریهای عیبیابی را فعال میکند. گزینهٔ --debugsasl اطلاعات اشکالزدایی را از کتابخانهٔ SASL درخواست میکند. گزینهٔ --dumptlsinfo اطلاعات طرف مقابل (peer) در TLS (SSL) را نشان میدهد؛ اگر به همراه --debug مشخص شود، گواهی PEM سرور به عنوان ردگیری اشکالزدایی ارائه خواهد شد.
گزینهٔ --version اطلاعات نسخه را نمایش میدهد. هنگامی که با --debug ترکیب شود، نگارش وابستگیهای پیادهسازی را نشان خواهد داد. گزینههای --help و --man اطلاعات نحوهٔ استفاده را ارائه میدهند.
سرور میتواند یک نام میزبان یا نشانی IP (از نوع IPv4 یا IPv6) باشد.
اگر سروری از طریق --server مشخص شده باشد، اولویت خواهد داشت. اگر این گزینه وجود نداشته باشد، متغیر محیطی $IMAP_SERVER بررسی میشود و در صورتی که یک مسیر سوکت دامنه یونیکس (unix-domain socket) نباشد، با حذف هرگونه مشخصهٔ پورت مورد استفاده قرار میگیرد.
برای اعتبارسنجی TLS، این نام به صورت پیشفرض برای نامهای میزبان (هم برای SNI و هم اعتبارسنجی) استفاده میشود؛ در حال حاضر هیچ اطلاعاتی که از DNS به دست آمده باشد به عنوان شناسهٔ نام میزبانِ مورد اعتماد استفاده نمیشود. (با توجه به DNSSEC، این موضوع ممکن است در آینده تغییر کند). گزینهٔ --tlshostname میتواند برای بازنویسی و جایگزینی نام استفادهشده برای TLS به کار رود.
سپس، مگر آنکه --nosrv داده شده باشد، رکوردهای SRV بررسی میشوند تا یک سرور پیشفرض جستجو شود؛ اگر ماژول پرل Mozilla::PublicSuffix در دسترس باشد، این بررسیها برای هر سطحی از نام میزبان تا قبل از (و نه شامل) پسوند عمومی (public suffix) انجام میگیرد. اگر آن ماژول در دسترس نباشد، از یک روش تقریبی ساده استفاده میشود: تا زمانی که سه نقطه در نام میزبان وجود داشته باشد، رکوردهای SRV برای بخشی از نام میزبان که پس از نقطهٔ اول قرار دارد امتحان میشوند. اگر این روش مناسب نیست، Mozilla::PublicSuffix را نصب کنید.
اگر هیچ رکورد SRV که به یک سرویس با پروتکل 'sieve'، 'imaps' یا 'imap' اشاره کند یافت نشود، یا رکوردی پیدا شود که بگوید "چنین سرویسی در این دامنه وجود ندارد" (با داشتن مقصدی به صورت "."))، سرور پیشفرض نهایی localhost خواهد بود.
پورت میتواند هر مشخصهٔ پورت پرل باشد؛ مقدار پیشفرض sieve(4190) است. پورتی که از یک رکورد SRV به دست آید اولویت خواهد داشت. مشخصهٔ پورت در پرل، نامی را برای جستجو در پایگاه دادهٔ سرویسهای سیستم (/etc/services) ارائه میدهد که به دنبال آن درون پرانتز، یک مقدار پیشفرض میآید تا در صورت پیدا نشدن نام از آن استفاده شود. بنابراین، این مقدار پیشفرض مقداری مانند 2000 را از /etc/services اعمال خواهد کرد.
گزینههای --4 یا --6 میتوانند برای اجبار به استفاده از IPv4 یا IPv6 به کار روند.
به طور پیشفرض، سرور یک دامنه در نظر گرفته میشود که رکوردهای SRV برای آن جستجو میشوند؛ از --nosrv برای جلوگیری از جستجوی رکوردهای SRV استفاده کنید.
گزینهٔ --user مورد نیاز خواهد بود مگر اینکه روی یک سیستم یونیکس باشید که getpwuid() در آن در دسترس باشد و نام حساب Cyrus شما با نام حساب سیستمیتان مطابقت داشته باشد. از --authmech میتوان برای اجبار یک سازوکار احراز هویت خاص استفاده کرد. از --authzid میتوان برای درخواست مجوز جهت عمل کردن به عنوان شناسهٔ (id) مشخصشده استفاده نمود. --realm میتواند برای تلاش جهت ارسال اطلاعات قلمرو (realm) به سازوکار احراز هویت استفاده شود. اگر میخواهید گذرواژه را به صورت برنامهریزیشده ارائه دهید، از --passwordfd برای تعیین توصیفگر فایلی (معمولاً 0) که گذرواژه از آن خوانده میشود استفاده کنید. هر چیزی تا نویسهٔ خط جدید پیش از EOF به عنوان گذرواژه تلقی میشود، بنابراین میتواند حاوی خطوط جدید درونمتنی نیز باشد. گذرواژهها را در خط فرمان یا در محیط فرآیند ارائه ندهید.
مگر اینکه در زمان نصب یا بستهبندی تغییر یافته باشد، به طور پیشفرض گواهیهای مرجع صدور گواهی (CA) مربوط به SSL جستجو میشوند. تلاش نخست این است که به نوبت متغیرهای محیطی $SSL_CERT_DIR و $SSL_CERT_FILE بررسی شوند که نامهای پشتیبانیشده توسط کتابخانهٔ OpenSSL بوده و بنابراین اغلب توسط دستورات کلاینت نیز پشتیبانی میشوند. سپس، اگر دستور "version" از OpenSSL در دسترس باشد و خروجی "OPENSSLDIR" قابل تجزیه باشد و دایرکتوری "certs" در آن دایرکتوری وجود داشته باشد، آن مکان مورد استفاده قرار خواهد گرفت. در نهایت، فهرستی ثابت از مکانهای رایج جستجو شده و نخستین مکانی که وجود داشته باشد استفاده میشود. فراخوانی به همراه --debug جزئیات بیشتری را در طول مرحلهٔ "setup:" نشان خواهد داد.
در صورت مشخص شدن، گزینهٔ --tlscafile بر این پیشفرضها اولویت دارد و در غیر این صورت، گزینهٔ --tlscapath (چنانچه داده شده باشد) اولویت خواهد داشت. اولی فایلی منفرد حاوی گواهیها است و دومی یک دایرکتوری است.
از سوی دیگر، اگر تمایل دارید ریسک حملات فعال مرد میانی (man-in-the-middle) را بپذیرید و امکان دسترسی به گواهی مرجع صدور گواهی (CA) مربوطه را ندارید، میتوانید با گزینهٔ --notlsverify (که به صورت --nosslverify نیز نوشته میشود) سطح ایمنی خود را کاهش دهید.
اگر اعتبارسنجی درخواست شده باشد (حالت پیشفرض) اما TLS در دسترس نباشد، برنامه به ارتباطات ناامن و متنی آشکار (cleartext) پسگرد (fallback) نمیکند. از --clearchan برای تغییر این رفتار استفاده کنید، یا متغیر محیطی $SIEVECONNECT_INSECURE_CLEARTEXT_FALLBACK را با مقداری غیرخالی مقداردهی نمایید.
اگر نمیخواهید (تنها) به سامانههای CA متکی باشید، میتوانید با استفاده از گزینهٔ --tlscertfingerprint (که به صورت --sslcertfingerprint نیز نوشته میشود) یک اثر انگشت مورد انتظار برای گواهی سرور را صریحاً تنظیم کنید. اگر مایلید اعتبارسنجی CA را نادیده بگیرید، همچنان باید آن را صریحاً غیرفعال کنید (به موارد بالا مراجعه شود)، چرا که حالت پیشفرض، افزودن یک قید اضافی است (سنجاق کردن یا پینینگ، در محدودهٔ گواهیهای معتبر CA). این گزینه اثر انگشت گواهی X.509 (و نه اثر انگشت کلید عمومی) را همانگونه که توسط OpenSSL ارائه میشود مشخص میکند. بخش نخست مقدار باید نام یک الگوریتم مانند "sha256" یا "sha1" باشد؛ سپس یک دونقطه، و بعد از آن دادههای اثر انگشت با نمادگذاری هگزادسیمال معمول که با دونقطه از هم جدا شدهاند میآید. به عنوان نمونه: "--tlscertfingerprint sha256:24:B4:..28-more-fields..:A8:58"
برای احراز هویت با گواهی کلاینت SSL، یا میتوان از --clientkeycert برای ارجاع به فایلی که هم کلید و هم گواهی در آن موجودند استفاده کرد یا هر دو گزینهٔ --clientkey و --clientcert باید به فایلهای مربوطه اشاره نمایند. دادهها باید در قالب فایل PEM باشند.
گزینهٔ --noclearauth از بهکارگیری سازوکارهای احراز هویت متنآشکار (cleartext) جلوگیری میکند مگر اینکه توسط TLS محافظت شده باشند. گزینهٔ --noclearchan استفاده از یک لایهٔ محرمانگی را الزامی میکند؛ در حال حاضر فقط TLS پشتیبانی میشود.
به طور پیشفرض، قابلیت "VERSION" سرور برای پالایش و محدود کردن دستورات در دسترس استفاده میشود. از --ignoreserverversion برای جلوگیری از این کار استفاده نمایید.
گزینههای باقیمانده نشاندهندهٔ کنشها (actions) هستند. تنها و فقط یک کنش میتواند مشخص گردد. اگر هیچ کنشی تعیین نشده باشد، برنامه وارد حالت تعاملی میشود. در صورت مشخص شدن کنش exec، دستورات در عوض از اسکریپت خوانده میشوند.
- --upload یک اسکریپت را به سرور بارگذاری میکند.
- --download یک اسکریپت را از سرور بارگیری میکند.
- --delete اسکریپتی را از سرور حذف میکند.
- --checkscript از سرور میخواهد فایل محلی ارائهشده را اعتبارسنجی کند.
- --edit یک اسکریپت را بارگیری کرده، ویرایشگری را روی آن اجرا میکند، از سرور میخواهد نتایج را بررسی کند (و در صورت رد آن توسط سرور، پیشنهاد ویرایش مجدد میدهد) و در نهایت نتیجه را بارگذاری میکند.
- --activate اسکریپت دوردست مشخصشده را به عنوان اسکریپت فعال علامتگذاری میکند.
- --deactivate نشان فعال بودن را بدون فعال کردن یک جایگزین، از اسکریپت دوردست مشخصشده حذف میکند.
- --exec نام فایلی حاوی دستورها را میگیرد، گویی در حلقه معمول خواندن-ارزیابی-چاپ (REPL) وارد شده باشند.
توجه داشته باشید که --check و --edit به سروری نیاز دارند که قابلیت "VERSION" را اعلان کند؛ برای نادیده گرفتن این موضوع --ignoreserverversion را ببینید.
(اگر --server بهصراحت مشخص نشده باشد، میتواند برای سازگاری با sieveshell در انتهای خط فرمان ارائه شود.)
مثالها (EXAMPLES)
اتصال به یک سرور Sieve و ورود به حالت تعاملی، هنگامی که از پیش یک بلیت Kerberos دارید و GSSAPI/Kerberos در دسترس است:
$ sieve-connect --server imap.example.org ReadLine support enabled. >
انجام همان کار، اما با تنظیم $IMAP_SERVER در متغیرهای محیطی:
$ sieve-connect ReadLine support enabled. >
بارگذاری یک اسکریپت از دایرکتوری جاری، به همراه اعلان برای احراز هویت؛ توجه داشته باشید که اسکریپت فعال نخواهد شد (بارگذاری صرفاً آن را در دسترس قرار میدهد، و احتمالاً ابتدا سرور آن را از نظر وجود خطا بررسی کرده است):
$ sieve-connect --server imap.example.org --user fred@example.org \
--localsieve fred.siv --upload
Sieve/IMAP Password: [password here, not shown]
$
مشاهده جزئیات بیشتر از آنچه در پشت صحنه رخ میدهد:
$ sieve-connect --debug [ snip 30 or so lines ] >
استفاده از --passwordfd برای ارائه گذرواژه از طریق stdio به جای argv یا متغیرهای محیطی، جایی که ممکن است در فهرست فرایندها نمایان شود؛ این مثال پوستهای با پشتیبانی از "here-strings" مانند zsh یا bash را فرض میکند:
$ password='...' $ sieve-connect --authmech digest-md5 --passwordfd=5 5<<<"$password" ReadLine support enabled. >
محیط (ENVIRONMENT)
$IMAP_SERVER برای یک سرور IMAP پیشفرض.
$USERNAME و $LOGNAME در جایی که تابع "getpwuid()" در دسترس نیست.
$SSL_CERT_DIR و $SSL_CERT_FILE برای یافتن لنگرهای اعتماد پیشفرض مرجع صدور گواهی (CA).
$SIEVECONNECT_INSECURE_CLEARTEXT_FALLBACK برای حفظ رویه قدیمی و ناامن پیرامون بازگشت (fallback) از TLS به متن آشکار.
$VISUAL، وگرنه $EDITOR، برای عملیات ویرایش..SH "گزارش باگها (BUGS)" اگر پروتکل احراز هویت یک لایهٔ حفاظتی را مذاکره کند، اوضاع بهسرعت خراب خواهد شد. یک عامل تسکیندهنده این است که هنگام حفاظت تحت STARTTLS نباید هیچ لایهٔ حفاظتی مذاکره شود. فقط از TLS استفاده کنید!
هنگام فهرست کردن اسکریپتها، قالب بر پایهٔ خروجی خام کارساز است، با این فرض که کارساز برای نام اسکریپتها از رشتههای نقلقولشده استفاده میکند. خروجی فقط بر این اساس برگردانده میشود که رابط نسبتاً خوبی برای ارسال به یک برنامه است. اما یک کارساز میتواند استفاده از رشتههای لفظی را انتخاب کند، حتی با اینکه نتایج بهعنوان جداشده با شکست خط تعریف شدهاند -- این بدان معنا خواهد بود که برخی شکستهای خط ویژه هستند. امید است هیچ کارسازی این کار را انجام ندهد.
اگر sieve-connect بدون ارسال صریح گزینهٔ -4 نتواند به یک کارساز IPv4 متصل شود، با یک مشکل سازگاری در کتابخانهٔ پرل IO::Socket::INET6 مواجه شدهاید و باید آن را ارتقا دهید.
بیشتر پیادهسازیهای قدیمی از درگاه ۲۰۰۰ برای ManageSieve استفاده میکردند. RFC5804 درگاه ۴۱۹۰ را تخصیص میدهد. این ابزار از مشخصهٔ درگاه "sieve(4190)" بهعنوان درگاه پیشفرض استفاده میکند، به این معنی که ورودی /etc/services (یا جایگزین آن) برای "sieve" بهعنوان یک سرویس TCP اولویت دارد، اما اگر موجود نباشد، ۴۱۹۰ را بهعنوان پیشفرض در نظر خواهد گرفت. این تغییر بدین معناست که اگر هنوز از درگاه ۲۰۰۰ استفاده میکنید و ورودی /etc/services ندارید، بهروزرسانی به نگارش 0.75 این ابزار یا بالاتر از آن، فراخوانیهایی را که درگاهی را مشخص نکردهاند دچار مشکل خواهد کرد. مشخصات درگاه پیشفرض به بخش قابلپیکربندی توسط کاربر در بالای اسکریپت منتقل شده است و مدیران سیستم ممکن است بخواهند پیشفرض ارسالشده را بازنویسی کنند. شما میتوانید با انتشار رکوردهای SRV بر اساس RFC5804، از تمام این آشفتگی جلوگیری کنید.
ماژول پرل Net::DNS (در زمان نگارش این متن) از رکوردهای SRV با اولویتبندی وزنی پشتیبانی کامل ارائه نمیکند و من نیز هیچ تلاشی برای رفع این مشکل نکردهام؛ هر آنچه الگوریتم مرتبسازی پیشفرض برای SRV ارائه دهد، برای ترتیببندی استفاده میشود.
اگر کارسازی را مشخص نکنید و $IMAP_SERVER را در محیط صادر نکنید، در صورت نصب بودن ماژول پرل Mozilla::PublicSuffix سازوکار جستجو امنتر و دقیقتر خواهد بود. بهویژه اگر نام میزبان شما همان نام دامنهٔ شما نیز باشد و دامنهٔ والد توسط کسی اداره شود که به او اعتماد ندارید، از نصب نکردن آن ماژول پشیمان خواهید شد.
احتمالاً باید سر فرصت نشست و RFC نهایی را بررسی کرد تا مشخص شود آیا هنوز قابلیتی جا افتاده است یا خیر.
موارد غیرباگ (NON-BUGS)
در واقع از STARTTLS استفاده میکند. میتواند نامهای اسکریپت حاوی فاصلههای خالی را مدیریت کند. نویسنده برای تکمیل آزمایش آن، نیاز به دسترسی به کارسازی دارد که نویسههای نقلقول تعبیهشده را بهدرستی مدیریت کند.
تاریخچه (HISTORY)
sieve-connect بهعنوان یک نمونهٔ نمایشی برای فهرست رایانامهٔ "info-cyrus" در تاریخ 2006-11-14 نوشته شد. این یک اسکریپت «یک اقدام و خروج» برای اهداف اسکریپتنویسی بود. کد حلقهٔ فرمان (دو روز) بعد نوشته شد و عمداً طوری طراحی شد که با sieveshell سازگار باشد.
نگارشهای پیش از 0.85 در واقع هویت گواهی همتا را اعتبارسنجی نمیکردند، اگرچه این نویسنده احمقانه باور داشت که این کار انجام میشود. عدم تطابق بین API و انتظارات.
نگارشهای پیش از 0.88 در صورت عدم وجود STARTTLS، چنانچه اطلاعات CA بهصورت محلی پیکربندی شده بود و اعتبارسنجی درخواست میشد (پیشفرض)، بهطور پیشفرض به متن ساده پسگرد میکردند. امروزه این مورد دیگر برای ارتباطات کلاینت-سرور پذیرفته نیست؛ یا verify-and-require-TLS یا don't-verify-and-fallback-to-cleartext. این سیاست جدید رو به جلو است؛ از --clearchan برای اجازه دادن به پسگرد در عین تلاش برای اعتبارسنجی TLS (اما چرا؟) استفاده کنید، یا --notlsverify را برای صرفنظر از اعتبارسنجی به کار ببرید. یا $SIEVECONNECT_INSECURE_CLEARTEXT_FALLBACK را با مقداری غیرخالی در محیط اضافه کنید تا از رفتار ضمنی noclearchan-when-verify-enabled جلوگیری شود.
نویسندگان (AUTHORS)
Phil Pennock <phil-perl@spodhuis.org> مقصر است، سرورم (m'Lud).
یک فهرست اعلان کمترافیک برای انتشار نگارشهای جدید وجود دارد؛ رابط وب در http://mail.globnix.net/mailman/listinfo/sieve-connect-announce قرار دارد یا میتوانید یک رایانامه بفرستید: <mailto:sieve-connect-announce-request@spodhuis.org?subject=subscribe>
در دسترس بودن (AVAILABILITY)
نگارشها در http://people.spodhuis.org/phil.pennock/software در قالب یک tarball و یک امضای مجزای PGP مرتبط در دسترس قرار میگیرند. همهٔ نگارشها همیشه امضا شدهاند و همواره امضا خواهند شد. کلید امضا در مجموعهٔ قوی PGP قرار دارد (به این معنی که احتمال بیشتری وجود دارد تا بتوانید هویت مالک کلید را بررسی کنید). در گذشته، نگارشها با کلید 0x403043153903637F امضا میشدند. اگر این متن را از یک نگارش منتشرشده میخوانید، من نگارش جدیدی را پس از تغییر به کلید 0x4D1E900E14C1CC04 منتشر کردهام و انتظار دارم از این کلید 4096RSA استفاده شود، مگر در صورت بروز حادثهای اساسی.
کد منبع از طریق Git در دسترس است؛ مخزن رسمی و عمومی در حال حاضر https://github.com/philpennock/sieve-connect است و pull-requestها و گزارشهای باگ در آنجا پذیرفته میشوند..SH "پیشنیازها (PREREQUISITES)" Perl. Authen::SASL. IO::Socket::INET6. IO::Socket::SSL (حداقل نسخهٔ 1.14). Pod::Usage. Net::DNS برای جستجوی SRV. Pod::Simple::Text برای دستور man توکار (اختیاری). Term::ReadKey جهت دریافت گذرواژهها بدون بازتاب. ماژولهای گوناگون دیگر Perl که استاندارد فرض میشوند. Term::ReadLine حالت تعاملی را بهطور چشمگیری بهبود میبخشد. Term::ReadLine::Gnu با فراهم کردن امکان تکمیل خودکار (tab-completion) آن را بیشتر ارتقا خواهد داد. Mozilla::PublicSuffix به شدت توصیه میشود و امنیت را بهبود میبخشد.
تعاملپذیری (INTEROPERABILITY)
sieve-connect بهطور مرتب با کارساز timsieved توزیعشده همراه با کارساز Cyrus IMAP آزمایش میشود. آزمایشهای تعاملپذیری بیشتری در حال انجام است و موارد بیشتری نیز مورد نیاز است (از ارائهٔ حسابهای آزمایشی استقبال میشود!).
| 2019-03-29 | 0.90 |