یک بار برای همیشه، redux یا zustand
در این پست به مقایسه redux toolkit و zustand میپردازم. ابتدا توضیح هر کدوم رو میدم و ساختارها رو میگم سپس تفاوت ها و شباهت ها رو میگم. خوبی ها و بدی های هر دو رو میگم. تجربه خودم رو هم میگم.
توضیح redux toolkit و ساختارش:
از پترن slice استفاده میکنه. برای هر بخشی میتوانیم یک slice داشته باشیم. یک slice از استیت و یک سری توابع تشکیل میشه که بوسیله تابع ها، مقدار استیت اش رو تغییر میدیم. برای فراخوانی توابع باید اونا رو dispatch کنیم. هر جا هم که مقدار یک استیت رو خواستیم با selector میایم مقدارش رو میخونیم که از نظر reRender هم بهینه است.
کلا یک provider و store داره. (میتونه چند تا store و provider داشته باشه که توصیه نمیشه).
توضیح zustand و ساختارش:
از پترن خاصی استفاده نمیکند و دست ما کاملا باز است. به سادگی میتوانیم برای هر بخش یک store ایجاد کنیم و از آن استفاده کنیم. در یک store ما هم کلید هایی داریم که داخلش مقادیر رو نگه میداریم و هم توابع رو تعریف میکنیم و همه یک جا هستند (مثل کلید های یک ابجکت). با استفاده از توابع میتوانیم مقادیر استیت رو اپدیت کنیم و نیازی به dispatch کردن نداریم بلکه تنها آن تابع را صدا میزنیم و برای گرفتن مقدار یک استیت از selector استفاده میکنیم که از نظر reRender هم بهینه است.
از ساختار provider استفاده نمیکند و میتوانیم به راحتی چندین store برای هر بخش از برنامه خودمان داشته باشیم.
برای ssr هر کدام چگونه هستند؟
در کتابخانه redux toolkit هنگامی که داریم یک store را ایجاد میکنیم باید توی تابع createStore یک ابجکتی از مقادیر اولیه را بدهیم و اینگونه برای ssr مقدار دهی میشود.
در کتابخانه zustand باید یک provider و context ایجاد کرد و store زوشتند را در کل برنامه به اشتراک گذاشت تا بقیه کامپوننت ها بتوانند به آن دسترسی داشته باشند. حالا در لحظه ای که داره اون کانتکست ایجاد میشه و به اشتراک گذاشته میشه باید store رو با مقادیر اولیه بسازیم و تو کل برنامه به اشتراک بزاریم. (یه جورایی یک store ایجاد میکنیم برای استیت ها و توابع ای که توی ssr نیازش داریم)
خوبی های redux toolkit:
دارای ساختار قوی و نظام مند
استفاده خودکار از immer
عدم نیاز به کانفیگ خاص و نوشتن کد اضافه برای هندل کردن ssr
خوبی های zustand:
در تمام فایل ها میتوان از استیت و توابع استفاده کرد و آنها را صدا زد. (چون برخلاف redux از provider استفاده نمیکند)
قابلیت multiple store. میتوان برای هر بخش که بخواهیم یک store جداگانه ایجاد کنیم.
حجم بسیار پایین gzipped: کمتر از 1 کیلوبایت
سادگی بسیار زیاد و عدم نوشتن کدهای تکراری و رعایت ساختار (حجم کد کمتر => حجم باندل کمتر)
بدی های redux toolkit:
به store در فایل هایی دسترسی داریم که درون provider و به عنوان فرزندی از آن باشند و در خارج از provider به آن دسترسی نداریم. (بر خلاف zustand)
حجم زیادتر gzipped نسبت به zustand: حدود 15 کیلوبایت
تکرار کردن ساختار و نوشتن کدهای تکراری و import های useDispatch و رعایت پترن slice در نتیجه حجم کد بیشتر => حجم باندل بیشتر
بدی های zustand:
عدم ساختار و احتمال کثیفی کد هنگامی که کدها زیاد و زیادتر میشوند.
نیاز به هندل کردن ssr به صورت دستی و نوشتن provider برای آن.
@DevTwitter | <Mohammad Reza G./>
در این پست به مقایسه redux toolkit و zustand میپردازم. ابتدا توضیح هر کدوم رو میدم و ساختارها رو میگم سپس تفاوت ها و شباهت ها رو میگم. خوبی ها و بدی های هر دو رو میگم. تجربه خودم رو هم میگم.
توضیح redux toolkit و ساختارش:
از پترن slice استفاده میکنه. برای هر بخشی میتوانیم یک slice داشته باشیم. یک slice از استیت و یک سری توابع تشکیل میشه که بوسیله تابع ها، مقدار استیت اش رو تغییر میدیم. برای فراخوانی توابع باید اونا رو dispatch کنیم. هر جا هم که مقدار یک استیت رو خواستیم با selector میایم مقدارش رو میخونیم که از نظر reRender هم بهینه است.
کلا یک provider و store داره. (میتونه چند تا store و provider داشته باشه که توصیه نمیشه).
توضیح zustand و ساختارش:
از پترن خاصی استفاده نمیکند و دست ما کاملا باز است. به سادگی میتوانیم برای هر بخش یک store ایجاد کنیم و از آن استفاده کنیم. در یک store ما هم کلید هایی داریم که داخلش مقادیر رو نگه میداریم و هم توابع رو تعریف میکنیم و همه یک جا هستند (مثل کلید های یک ابجکت). با استفاده از توابع میتوانیم مقادیر استیت رو اپدیت کنیم و نیازی به dispatch کردن نداریم بلکه تنها آن تابع را صدا میزنیم و برای گرفتن مقدار یک استیت از selector استفاده میکنیم که از نظر reRender هم بهینه است.
از ساختار provider استفاده نمیکند و میتوانیم به راحتی چندین store برای هر بخش از برنامه خودمان داشته باشیم.
برای ssr هر کدام چگونه هستند؟
در کتابخانه redux toolkit هنگامی که داریم یک store را ایجاد میکنیم باید توی تابع createStore یک ابجکتی از مقادیر اولیه را بدهیم و اینگونه برای ssr مقدار دهی میشود.
در کتابخانه zustand باید یک provider و context ایجاد کرد و store زوشتند را در کل برنامه به اشتراک گذاشت تا بقیه کامپوننت ها بتوانند به آن دسترسی داشته باشند. حالا در لحظه ای که داره اون کانتکست ایجاد میشه و به اشتراک گذاشته میشه باید store رو با مقادیر اولیه بسازیم و تو کل برنامه به اشتراک بزاریم. (یه جورایی یک store ایجاد میکنیم برای استیت ها و توابع ای که توی ssr نیازش داریم)
خوبی های redux toolkit:
دارای ساختار قوی و نظام مند
استفاده خودکار از immer
عدم نیاز به کانفیگ خاص و نوشتن کد اضافه برای هندل کردن ssr
خوبی های zustand:
در تمام فایل ها میتوان از استیت و توابع استفاده کرد و آنها را صدا زد. (چون برخلاف redux از provider استفاده نمیکند)
قابلیت multiple store. میتوان برای هر بخش که بخواهیم یک store جداگانه ایجاد کنیم.
حجم بسیار پایین gzipped: کمتر از 1 کیلوبایت
سادگی بسیار زیاد و عدم نوشتن کدهای تکراری و رعایت ساختار (حجم کد کمتر => حجم باندل کمتر)
بدی های redux toolkit:
به store در فایل هایی دسترسی داریم که درون provider و به عنوان فرزندی از آن باشند و در خارج از provider به آن دسترسی نداریم. (بر خلاف zustand)
حجم زیادتر gzipped نسبت به zustand: حدود 15 کیلوبایت
تکرار کردن ساختار و نوشتن کدهای تکراری و import های useDispatch و رعایت پترن slice در نتیجه حجم کد بیشتر => حجم باندل بیشتر
بدی های zustand:
عدم ساختار و احتمال کثیفی کد هنگامی که کدها زیاد و زیادتر میشوند.
نیاز به هندل کردن ssr به صورت دستی و نوشتن provider برای آن.
@DevTwitter | <Mohammad Reza G./>
👍27❤3👎1
ما اغلب گرفتار محدودیتهای ذهنمون هستیم. اینو وقتی دیدم از پورت 1 هم میشه استفاده کرد فهمیدم
@DevTwitter | <M.Ali/>
@DevTwitter | <M.Ali/>
🤣168👍11❤5👎4
تو این سایت میتونید توزیع های مختلف لینوکس رو به صورت آنلاین اجرا کنید. برای انتخاب توزیع عالیه.
https://distrosea.com/
@DevTwitter | <Javad/>
https://distrosea.com/
@DevTwitter | <Javad/>
👍38👎6🔥5❤3
چطور در لینوکس جایگزینی برای برنامههای ویندوزی پیدا کنیم؟
اگه تازه اومدین روی لینوکس و دنبال برنامههایی میگردین که مشابه نرمافزارهای ویندوزیتون باشه، ممکنه یه ذره سردرگم بشین. اما نگران نباشید، یه راه خیلی ساده وجود داره،استفاده از سایت:
https://alternativeto.net/
@DevTwitter | <GeeDook/>
اگه تازه اومدین روی لینوکس و دنبال برنامههایی میگردین که مشابه نرمافزارهای ویندوزیتون باشه، ممکنه یه ذره سردرگم بشین. اما نگران نباشید، یه راه خیلی ساده وجود داره،استفاده از سایت:
https://alternativeto.net/
@DevTwitter | <GeeDook/>
👍44👎6🤣3
بچهها اگه میخواید یه مدرک رایگان راجع به Generative AI و LLM Agents از دانشگاه Berkeley بگیرید این دورهای که دارن برگزار میکنن رو شرکت کنید. فیلماش ضبط میشه رو یوتیوب میذارن.واسه هر جلسه یه آزمون داره، همهرو تموم کنید مدرکش رو میدن بهتون.
https://llmagents-learning.org/f24
@DevTwitter
https://llmagents-learning.org/f24
@DevTwitter
❤41👍8👎4🤣2
قبل اینکه بخواید هرکار وقت گیری انجام بدید یه چک کنید ببینید ابزار هوش مصنوعی براش هست یا نه. ازونجا که گوگل کردن این داستانم خودش کلی وقت میگیره، این دو تا وبسایت تو هر چی که فکرشو کنی، ابزار AI هلو برو تو گلوش رو لیست میکنه :)
futuretools.io
theresanaiforthat.com
@DevTwitter | <Shana/>
futuretools.io
theresanaiforthat.com
@DevTwitter | <Shana/>
👍39👎21❤4🔥3
امروز میخوام یه نکتهی ساده رو بهتون بگم: چطور میتونید سلامت باتری لپتاپتون رو در لینوکس بررسی کنید.
برای این کار، از ابزار upower استفاده میکنیم:
اول، این دستور رو بزنید تا لیست دستگاههای انرژی رو ببینید
upower --enumerate
بعد آدرس باتری رو پیدا کنید و این دستور رو بزنید
upower -i Battery address
با این کار میتونید درصد شارژ و وضعیت سلامت باتری رو ببینید.
@DevTwitter | <Firoozeh Daeizadeh/>
برای این کار، از ابزار upower استفاده میکنیم:
اول، این دستور رو بزنید تا لیست دستگاههای انرژی رو ببینید
upower --enumerate
بعد آدرس باتری رو پیدا کنید و این دستور رو بزنید
upower -i Battery address
با این کار میتونید درصد شارژ و وضعیت سلامت باتری رو ببینید.
@DevTwitter | <Firoozeh Daeizadeh/>
❤22🔥3👍2
استفاده از هوش مصنوعی دیگه تبدیل به یک "باید" شده و اگر استفاده نکنید، عقب میمونید.
سایت کورسرا به تازگی Specialization مختص مهندسان نرمافزار منتشر کرده که چطور به صورت بهینه در مراحل مختلف توسعه نرم افزار از هوش مصنوعی استفاده کنند، از دست ندید.
https://www.coursera.org/professional-certificates/generative-ai-for-software-development
@DevTwitter | <Reza Jafari/>
سایت کورسرا به تازگی Specialization مختص مهندسان نرمافزار منتشر کرده که چطور به صورت بهینه در مراحل مختلف توسعه نرم افزار از هوش مصنوعی استفاده کنند، از دست ندید.
https://www.coursera.org/professional-certificates/generative-ai-for-software-development
@DevTwitter | <Reza Jafari/>
👍31👎12❤2
لیست استانها و شهرهای ایران در یک فایل JSON!
اگه توی پروژههات نیاز به لیست کامل استانها و شهرهای ایران داری، این مخزن GitHub کلی به کارت میاد! یه فایل JSON مرتب و آماده داره که همه استانها و شهرهاشون رو برات لیست کرده.
https://gist.github.com/samanzamani/7ab3046ae1f94348d852bde959349f92
این دیتاها واقعاً برای پروژههای وب، اپلیکیشنهای موبایل و هر جایی که نیاز به موقعیتهای جغرافیایی داری، حسابی کار راهاندازن.
اگه پروژهای داری که به این نوع دیتا نیاز داره، حتماً یه سر بهش بزن و ازش استفاده کن!
@DevTwitter | <Shima Fallah/>
اگه توی پروژههات نیاز به لیست کامل استانها و شهرهای ایران داری، این مخزن GitHub کلی به کارت میاد! یه فایل JSON مرتب و آماده داره که همه استانها و شهرهاشون رو برات لیست کرده.
https://gist.github.com/samanzamani/7ab3046ae1f94348d852bde959349f92
این دیتاها واقعاً برای پروژههای وب، اپلیکیشنهای موبایل و هر جایی که نیاز به موقعیتهای جغرافیایی داری، حسابی کار راهاندازن.
اگه پروژهای داری که به این نوع دیتا نیاز داره، حتماً یه سر بهش بزن و ازش استفاده کن!
@DevTwitter | <Shima Fallah/>
👍58❤12🔥3👎2
این هم یک تجربه از رد شدن رزومه یک بنده خدا که خدای JS بوده، ولی تیمهای بررسی رزومه به دلیل گاو بودن او را رد کرده اند !
فردی یا تخصص بالای JS به دلیل قوی بودن در چند تیم مشغول به کار با AngularJS بوده است ، مثلا در 4 شرکت مجزا در سالهای گذشته - یعنی اصلا وقتی من و شما هنوز اسم AngularJS را نشنیده بودیم هم این بنده خدا با آن افتخار آفرینی می کرده است و تا 2-3 سال پیش هم در پروژه های خیلی بزرگ با آن کار میکرده است
در 2 سال اخیر هم یک نیروی کلیدی بوده برای کار با Angular
حضرات به دلیل عدم تسلط به Angular و فرض اینکه این فرد بیشتر به AngularJS تخصص دارد، او را رد کردند رفت پی کارش - خودش هم که آنجا نیست توضیح بدهد که، در 5 ثانیه رد میشه میره برای همیشه پی کارش !. اصلا Angular و AngularJS را کاملا دو چیز مجزا در حد تفاوت Java و مثلا #C می دانستند !!!!
حالا چطوری باید به اینها حالی میشد که این طرف اصلا از خدایان Front است ؟!
وقتی رزومه شما رد میشود، در اکثر اوقات این نشانه گاو بودن آنها است، نه گاو بودن شما
بیخودی نا امید نشوید - در اکثر اوقات شما اوکی هستید، طرف دیگر خر است !.
@DevTwitter | <Ali Kolahdoozan/>
فردی یا تخصص بالای JS به دلیل قوی بودن در چند تیم مشغول به کار با AngularJS بوده است ، مثلا در 4 شرکت مجزا در سالهای گذشته - یعنی اصلا وقتی من و شما هنوز اسم AngularJS را نشنیده بودیم هم این بنده خدا با آن افتخار آفرینی می کرده است و تا 2-3 سال پیش هم در پروژه های خیلی بزرگ با آن کار میکرده است
در 2 سال اخیر هم یک نیروی کلیدی بوده برای کار با Angular
حضرات به دلیل عدم تسلط به Angular و فرض اینکه این فرد بیشتر به AngularJS تخصص دارد، او را رد کردند رفت پی کارش - خودش هم که آنجا نیست توضیح بدهد که، در 5 ثانیه رد میشه میره برای همیشه پی کارش !. اصلا Angular و AngularJS را کاملا دو چیز مجزا در حد تفاوت Java و مثلا #C می دانستند !!!!
حالا چطوری باید به اینها حالی میشد که این طرف اصلا از خدایان Front است ؟!
وقتی رزومه شما رد میشود، در اکثر اوقات این نشانه گاو بودن آنها است، نه گاو بودن شما
بیخودی نا امید نشوید - در اکثر اوقات شما اوکی هستید، طرف دیگر خر است !.
@DevTwitter | <Ali Kolahdoozan/>
👍175🤣31👎8
یه وقتایی میشه که با حجم دیتای بالا سروکار داریم و سعی میکنیم تا جای ممکن کدمون رو بهینه کنیم ولی چیزی که گاهی وقتا از دستمون در میره که اون رو هم میتونیم بهینه تر کنیم مصرف حافظه هست.
فرض کن کوئری خودت رو تا جای ممکن بهینه کردی و میخوای دیتای نهایی که از دیتابیس گرفتی رو پردازش کنی ولی خب این دیتا هم میتونه منابع حافظه رو درگیر کنه اینجاس که Lazy Collection لاراول میاد وسط. فیچری که باهاش میتونی دیتای fetch شده رو دونه به دونه پردازش کنی و اینطوری حجم حافظه خیلی کمتری مصرف میشه.
اگه دوست داری بیشتر راجع به این فیچر ساده و خیلی کاربردی بدونی یه مقاله توی مدیوم منتشر کردم و با یه مثال ساده توضیح دادم که چطور کار میکنه. راستی خوشحال میشم بهم فیدبک بدی
https://farshadth.medium.com/optimizing-memory-usage-in-laravel-by-lazy-collections-71ea6346c9d8
@DevTwitter | <Farshad Tofighi/>
فرض کن کوئری خودت رو تا جای ممکن بهینه کردی و میخوای دیتای نهایی که از دیتابیس گرفتی رو پردازش کنی ولی خب این دیتا هم میتونه منابع حافظه رو درگیر کنه اینجاس که Lazy Collection لاراول میاد وسط. فیچری که باهاش میتونی دیتای fetch شده رو دونه به دونه پردازش کنی و اینطوری حجم حافظه خیلی کمتری مصرف میشه.
اگه دوست داری بیشتر راجع به این فیچر ساده و خیلی کاربردی بدونی یه مقاله توی مدیوم منتشر کردم و با یه مثال ساده توضیح دادم که چطور کار میکنه. راستی خوشحال میشم بهم فیدبک بدی
https://farshadth.medium.com/optimizing-memory-usage-in-laravel-by-lazy-collections-71ea6346c9d8
@DevTwitter | <Farshad Tofighi/>
👍24❤3🔥3🤣3
یه ریپازیتوری زدم که توش داکر فایل و کامپوز
(Flask-Gunicorn-Nginx reverse proxy)
رو قرار دادم. اگر توسعه دهنده Flask هستید میتونید از داکر فایل های این ریپازیتوری استفاده کنید
+ اگر احساس کردید میتونید بهترش کنید بی صبرانه منتظر PR های زیباتون هستم :)
https://github.com/free-programmers/flask-gunicorn-nginx
@DevTwitter | <Ali-Sharify/>
(Flask-Gunicorn-Nginx reverse proxy)
رو قرار دادم. اگر توسعه دهنده Flask هستید میتونید از داکر فایل های این ریپازیتوری استفاده کنید
+ اگر احساس کردید میتونید بهترش کنید بی صبرانه منتظر PR های زیباتون هستم :)
https://github.com/free-programmers/flask-gunicorn-nginx
@DevTwitter | <Ali-Sharify/>
👍21🔥3❤1
اگر می خواهید در مصاحبه های برنامه نویسی سوال های بک اند فرانت اند و انواع استک جواب دهید این اپلیکیشن ها در موبایلتان نصب و مطالعه کنید
javanoscript interview
Front-end interview
frontend QA interview
که سومی سوال جواب تمام زبان ها فریم ورک ها و تکنولوژی های،برنامه نویسی داره
حتی سومی من چک کردم مثلا postman bi و... هم داره
react.js interview
typenoscript Quiz
@DevTwitter | <Pooria AshkevarVakili/>
javanoscript interview
Front-end interview
frontend QA interview
که سومی سوال جواب تمام زبان ها فریم ورک ها و تکنولوژی های،برنامه نویسی داره
حتی سومی من چک کردم مثلا postman bi و... هم داره
react.js interview
typenoscript Quiz
@DevTwitter | <Pooria AshkevarVakili/>
🔥28👎5👍4🤣1
فریم ورک ویو جی اس ورژن 3.5 متشر کرد و در این ورژن یک سری قابلیت و بهبود های خوبی شاهد هستیم و در این پست به صورت کامل این تغییرات بررسی میکنیم.
https://code-news.com/p/vue-3-5-updates
@DevTwitter | <Code News/>
https://code-news.com/p/vue-3-5-updates
@DevTwitter | <Code News/>
👍21❤4🔥4👎3
اگه به برنامه نویسی RUST علاقمند هستید و دوست دارید باهاش کارهای redteam انجام بدید، این مخزن میتونه کمکتون کنه.
در این مخزن یسری تکنیکهایی که در تیم های قرمز یا توسعه ی بدافزار استفاده میشه، در زبان RUST پیاده سازی و آموزش داده شده.
https://github.com/Whitecat18/Rust-for-Malware-Development
@DevTwitter | <OnHexGroup/>
در این مخزن یسری تکنیکهایی که در تیم های قرمز یا توسعه ی بدافزار استفاده میشه، در زبان RUST پیاده سازی و آموزش داده شده.
https://github.com/Whitecat18/Rust-for-Malware-Development
@DevTwitter | <OnHexGroup/>
👍24👎7🤣5
This media is not supported in your browser
VIEW IN TELEGRAM
این ریپو یک search engine اپن سورس به اسم MindSearch هست که بر اساس فریمورک Multi-agent هست و قابل رقابت Perplexity Pro و SearchGPT. میتونید سیستم سرچ خودتون را لوکال و یا روی سرور خودتون دیپلوی کنید.
https://github.com/InternLM/MindSearch
@DevTwitter | <Mehdi Allahyari/>
https://github.com/InternLM/MindSearch
@DevTwitter | <Mehdi Allahyari/>
👍27🔥4👎1
👍124👎43🤣15🔥1
عه راستی ما برنامه نویسا درون گراییم، گپ نمیزنیم...
🤣228👎15👍11🔥5
چرا PHP نسبت به بقیه زبانها کندتر است و راهکار چیست؟ - قسمت اول
پی اچ پی در مقایسه با زبانهایی مثل GO کندتر است. دلیلش این است که هر درخواست PHP یک فرآیند جدید را شروع میکند. این فرآیند باید از ابتدا تجزیه و اجرا شود و سپس خاموش شود. یعنی هر پروسه به طور کامل بسته شده و از حافظه خارج میشود.
این یعنی PHP نمیتواند چیزی از پردازشهای قبلی را در حافظه نگه دارد و باید برای هر درخواست جدید از صفر شروع کند. نتیجه این کار، در تعداد درخواستهای بالا، عملکرد کندتر و مصرف بیشتر منابع سرور است. این روش را "Request-Response" مینامند.
اما راهکار برای وردپرس و PHP چی بود؟
برای حل این مشکل، از PHP-FPM استفاده شد. PHP-FPM باعث میشود که چند فرآیند PHP از قبل آماده به کار باشند. بنابراین، وقتی درخواست جدیدی میآید، دیگر لازم نیست PHP از صفر شروع کند. این فرآیندهای آماده به کار، درخواستها را سریعتر پردازش کرده و منابع سرور بهتر استفاده میشوند.
@DevTwitter | <Farhad Safari/>
پی اچ پی در مقایسه با زبانهایی مثل GO کندتر است. دلیلش این است که هر درخواست PHP یک فرآیند جدید را شروع میکند. این فرآیند باید از ابتدا تجزیه و اجرا شود و سپس خاموش شود. یعنی هر پروسه به طور کامل بسته شده و از حافظه خارج میشود.
این یعنی PHP نمیتواند چیزی از پردازشهای قبلی را در حافظه نگه دارد و باید برای هر درخواست جدید از صفر شروع کند. نتیجه این کار، در تعداد درخواستهای بالا، عملکرد کندتر و مصرف بیشتر منابع سرور است. این روش را "Request-Response" مینامند.
اما راهکار برای وردپرس و PHP چی بود؟
برای حل این مشکل، از PHP-FPM استفاده شد. PHP-FPM باعث میشود که چند فرآیند PHP از قبل آماده به کار باشند. بنابراین، وقتی درخواست جدیدی میآید، دیگر لازم نیست PHP از صفر شروع کند. این فرآیندهای آماده به کار، درخواستها را سریعتر پردازش کرده و منابع سرور بهتر استفاده میشوند.
@DevTwitter | <Farhad Safari/>
👍63🤣35👎8