![ظاهر برنامه](https://quera.org/qbox/view/CSjowTqHPD/purge-classnames-gif.gif)
امین تازه در دیجیکالا جذب شده و از آنجایی که خیلی به چالش های فنی علاقهمند است، بابک و فرزاد تصمیم گرفتهاند از او بخواهند راهحلی برای یک مشکل پیدا کند. به امین در یافتن راهحل کمک کنید.
# جزئیات پروژه
پروژهی اولیه را از [این لینک](/problemset/assignments/4367/download_problem_initial_project/136475/) دانلود کنید.
<details class="green">
<summary>
ساختار فایلهای پروژه
</summary>
```
purge-classnames
├── cypress
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── sample.spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ ├── commands.js
│ └── index.js
├── cypress.json
├── index.html
├── package.json
├── script.js
└── styles.css
```
</details>
امین باید تابعی با نام `purgeClassNames` پیادهسازی کنه که تعداد آرگومانهاش متغیر است. مثال:
```javascript
purgeClassNames('m-5', 'd-block', 'mr-5')
purgeClassNames('p-3', 'oy-12')
```
این تابع باید کلاسهای مشابه را بر اساس اولویت حذف کند، یعنی کلاسهایی که زودتر به تابع پاس داده شدهاند اولویت کمتری دارند. مثلاً خروجی مثال بالا باید بهصورت زیر باشد:
```javascript
purgeClassNames('m-5', 'd-block', 'm-12') === 'd-block m-12' // true
```
در مثال فوق، کلاس `m-5` با کلاس `m-12` جایگزین میشود، زیرا `m-12` دیرتر آمده و اولویت بیشتری دارد. کلاس `d-block` بدون هیچ تغییری به خروجی منتقل میشود.
## توضیح کلاسها
### کلاس `margin`
- کلاس `m-n`: مارجین از همهی جهات به اندازهی $n$
- کلاس `ml-n`: مارجین از چپ
- کلاس `mr-n`: مارجین از راست
- کلاس `mb-n`: مارجین از پایین
- کلاس `mt-n`: مارجین از بالا
- کلاس `my-n`: مارجین از بالا و پایین
- کلاس `mx-n`: مارجین از چپ و راست
در توضیحات بالا، $n$ میتواند هر عددی باشد. مثال:
`m-10` `mr-999` `mx-11`
#### چند نمونه تست کیس برای کلاس `margin`:
**ورودی ۱:**
```javascript
purgeClassNames('m-5', 'my-2')
```
**خروجی ۱:**
my-2 mx-5
*کلاس `m-5` میتواند به `my-5 mx-5` تجزیه شود. بنابراین `my-2` جایگزین `my-5` شده و خروجی برابر با `my-2 mx-5` خواهد بود.*
**ورودی ۲:**
```javascript
purgeClassNames('mx-3', 'mr-1')
```
**خروجی ۲:**
mr-1 ml-3
**ورودی ۳:**
```javascript
purgeClassNames('m-3', 'mt-1')
```
**خروجی ۳:**
mt-1 mx-3 mb-3
**نکته:** `m-n` میتواند به `mx-n` و `my-n` تجزیه شود. کلاس `mx-n` نیز میتواند به `mr-n` و `ml-n` تجزیه شود. به همین ترتیب، کلاس `my-n` نیز شامل `mt-n` و `mb-n` میشود. در این مثالها، $n$ هر عددی میتواند باشد.
### کلاس `padding`
قواعد کلاس `margin` برای این کلاس هم وجود دارند. مثال:
`pr-6` یا `p-5` یا `py-3` و...
### کلاس `display`
ساختار کلاس به صورت `d-OPTION` است که `OPTION` میتواند یکی از مقادیر زیر باشد:
- `flex`
- `inline`
- `inline-flex`
- `block`
- `inline-block`
مثال:
`d-block` `d-inline` `d-flex`
#### یک نمونه تست کیس برای کلاس `display`:
**ورودی:**
```javascript
purgeClassNames('d-block', 'd-flex')
```
**خروجی:**
d-flex
### کلاس `overflow`
ساختار کلاس `overflow` بهصورت زیر است:
- `overflow-OPTION` در تمامی جهات
- `overflow-y-OPTION` درجهت محور y
- `overflow-x-OPTION` در جهت محور x
در مثالهای بالا، `OPTION` میتواند یکی از مقادیر زیر باشد:
- `hidden`
- `visible`
- `scroll`
- `auto`
- `none`
#### چند نمونه تست کیس برای کلاس `overflow`:
**ورودی ۱:**
```javascript
purgeClassNames('overflow-auto', 'overflow-x-none')
```
**خروجی ۱:**
overflow-x-none overflow-y-auto
**ورودی ۲:**
```javascript
purgeClassNames('overflow-x-auto', 'overflow-y-auto')
```
**خروجی ۲:**
overflow-auto
**ورودی ۳:**
```javascript
purgeClassNames('overflow-x-visible', 'overflow-none')
```
**خروجی ۳:**
overflow-none
**نکته:** کلاس `overflow-OPTION` میتواند به کلاسهای `overflow-x-OPTION` و `overflow-y-OPTION` تجزیه شود.
### نقطه شکستها (*Breakpoints*)
نقطه شکستها اندازه های تعریف شدهای هستند که به ما این امکان را میدهند تا یک کلاس را فقط در یک اندازهی مشخص اعمال کنیم.
هر کلاس میتواند فقط در یک *breakpoint* خاص فعال باشد، برای مثال: `lg:mr-2` فقط در *breakpoint lg* فعال است. تمامی کلاس هایی که بالا معرفی شدند باید قابلیت استفاده با *breakpoints* را داشته باشند.
لیست نقطه شکست های موجود:
- `xs`
- `sm`
- `md`
- `lg`
#### چند نمونه تست کیس برای *breakpoints*:
**ورودی ۱:**
```javascript
purgeClassNames('m-5', 'lg:m-2')
```
**خروجی ۱:**
m-5 lg:m-2
همانطور که مشاهده میکنید، کلاسهایی که دارای *breakpoint* هستند، بر روی کلاس های معمولی اثری ندارند.
**ورودی ۲:**
```javascript
purgeClassNames('sm:m-5', 'lg:m-2')
```
**خروجی ۲:**
sm:m-5 lg:m-2
همانطور که مشاهده میکنید، *breakpoint* های متفاوت نیز بر روی یکدیگر تاثیر ندارند.
# نکات
- ترتیب کلاس های خروجی داده شده توسط تابع `purgeClassNames` اهمیتی ندارد.
- خروجی تابع `purgeClassNames` باید یک رشته شامل کلاسها باشد که با استفاده از فاصله (*space*) از هم جدا شدهاند.
- تضمین میشود که فقط و فقط یک کلاس به ازای هر آرگومان به تابع داده خواهد شد.
- دقت کنید که تعداد آرگومان های تابع متغیر خواهد بود.
- حداقل یک آرگومان به تابع پاس داده خواهد شد.
- اگر کلاسی به `purgeClassNames` داده شود که در لیست کلاسهای بالا تعریف نشده بود، شما باید آن کلاس را بدون تغییر و به صورت مستقیم به خروجی ارسال کنید.
- شما تنها مجاز به اعمال تغییرات در فایل `script.js` هستید.
# آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، فایل `script.js` را آپلود کنید.