ম্যাটেরিয়াল 3 এক্সপ্রেসিভ হল মেটেরিয়াল ডিজাইনের পরবর্তী বিবর্তন। এতে আপডেটেড থিমিং, উপাদান এবং গতিশীল রঙের মতো ব্যক্তিগতকরণ বৈশিষ্ট্য অন্তর্ভুক্ত রয়েছে।
এই গাইডটি Wear Compose Material 2.5 (androidx.wear.compose) Jetpack লাইব্রেরি থেকে Wear Compose Material 3 (androidx.wear.compose.material3) জেটপ্যাক লাইব্রেরিতে অ্যাপের জন্য স্থানান্তরিত করার উপর দৃষ্টি নিবদ্ধ করে।
পন্থা
আপনার অ্যাপ কোড M2.5 থেকে M3 তে স্থানান্তর করার জন্য, কম্পোজ ম্যাটেরিয়াল মাইগ্রেশন ফোন নির্দেশিকাতে বর্ণিত একই পদ্ধতি অনুসরণ করুন, বিশেষ করে:
- আপনার দীর্ঘমেয়াদী একটি একক অ্যাপে M2.5 এবং M3 উভয়ই ব্যবহার করা উচিত নয়
- একটি পর্যায়ক্রমে পদ্ধতি গ্রহণ করুন
নির্ভরতা
M3 এর একটি পৃথক প্যাকেজ এবং M2.5 সংস্করণ রয়েছে:
M2.5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.6.0-alpha03")
Wear Compose Material 3 রিলিজ পৃষ্ঠায় সর্বশেষ M3 সংস্করণগুলি দেখুন৷
Wear Compose Foundation লাইব্রেরি সংস্করণ 1.6.0-alpha03 কিছু নতুন উপাদান প্রবর্তন করেছে যা উপাদান 3 উপাদানগুলির সাথে কাজ করার জন্য ডিজাইন করা হয়েছে। একইভাবে, Wear কম্পোজ নেভিগেশন লাইব্রেরি থেকে SwipeDismissableNavHost
Wear OS 6 (API লেভেল 36) বা তার উপরে চলাকালীন একটি আপডেট অ্যানিমেশন থাকে। Wear Compose Material 3 সংস্করণে আপডেট করার সময়, আমরা Wear Compose Foundation এবং নেভিগেশন লাইব্রেরি আপডেট করার পরামর্শ দিই:
implementation("androidx.wear.compose:compose-foundation:1.6.0-alpha03")
implementation("androidx.wear.compose:compose-navigation:1.6.0-alpha03")
থিম
M2.5 এবং M3 উভয় ক্ষেত্রেই, থিম কম্পোজেবলের নাম MaterialTheme
, কিন্তু আমদানি প্যাকেজ এবং পরামিতি ভিন্ন। M3-এ, Colors
প্যারামিটারের নাম পরিবর্তন করে ColorScheme
করা হয়েছে এবং পরিবর্তন বাস্তবায়নের জন্য MotionScheme
চালু করা হয়েছে।
M2.5
import androidx.wear.compose.material.MaterialTheme
MaterialTheme(
colors = AppColors,
typography = AppTypography,
shapes = AppShapes,
content = content
)
M3
import androidx.wear.compose.material3.MaterialTheme
MaterialTheme(
colorScheme = AppColorScheme,
typography = AppTypography,
shapes = AppShapes,
motionScheme = AppMotionScheme,
content = content
)
রঙ
M3 এ রঙের সিস্টেম M2.5 থেকে উল্লেখযোগ্যভাবে আলাদা। রঙের পরামিতিগুলির সংখ্যা বৃদ্ধি পেয়েছে, তাদের বিভিন্ন নাম রয়েছে এবং তারা M3 উপাদানগুলিতে ভিন্নভাবে ম্যাপ করেছে। রচনায়, এটি M2.5 Colors
ক্লাস, M3 ColorScheme
ক্লাস এবং সম্পর্কিত ফাংশনের ক্ষেত্রে প্রযোজ্য:
M2.5
import androidx.wear.compose.material.Colors
val appColorScheme: Colors = Colors(
// M2.5 Color parameters
)
M3
import androidx.wear.compose.material3.ColorScheme
val appColorScheme: ColorScheme = ColorScheme(
// M3 ColorScheme parameters
)
নিম্নলিখিত টেবিলটি M2.5 এবং M3 এর মধ্যে মূল পার্থক্যগুলি বর্ণনা করে:
M2.5 | M3 |
---|---|
| এর নাম পরিবর্তন করে |
13 রং | 28 রং |
N/A | নতুন গতিশীল রঙের থিমিং |
N/A | আরও প্রকাশের জন্য নতুন তৃতীয় রঙ |
ডায়নামিক কালার থিমিং
M3-এ একটি নতুন বৈশিষ্ট্য হল গতিশীল রঙের থিমিং । ব্যবহারকারীরা ঘড়ির মুখের রঙ পরিবর্তন করলে, UI-এর রং মেলে।
ডায়নামিক কালার স্কিম বাস্তবায়ন করতে dynamicColorScheme
কালার স্কিম ফাংশন ব্যবহার করুন এবং ডাইনামিক কালার স্কিম উপলব্ধ না হলে ফলব্যাক হিসাবে একটি defaultColorScheme
কালার স্কিম প্রদান করুন।
@Composable
fun myApp() {
val myColorScheme = myBrandColors()
val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}
টাইপোগ্রাফি
M3-তে টাইপোগ্রাফি সিস্টেম M2 থেকে আলাদা এবং এতে নিম্নলিখিত বৈশিষ্ট্যগুলি রয়েছে:
- নয়টি নতুন পাঠ্য শৈলী
- ফ্লেক্স ফন্ট, যা বিভিন্ন ওজন, প্রস্থ এবং গোলাকার জন্য টাইপ স্কেল কাস্টমাইজ করার অনুমতি দেয়
AnimatedText
, যা ফ্লেক্স ফন্ট ব্যবহার করে
M2.5
import androidx.wear.compose.material.Typography
val Typography = Typography(
// M2.5 TextStyle parameters
)
M3
import androidx.wear.compose.material3.Typography
val Typography = Typography(
// M3 TextStyle parameters
)
ফ্লেক্স ফন্ট
ফ্লেক্স ফন্ট ডিজাইনারদের নির্দিষ্ট আকারের জন্য প্রস্থ এবং ওজনের ধরন নির্দিষ্ট করতে দেয়।
পাঠ্য শৈলী
নিম্নলিখিত টেক্সটস্টাইলগুলি M3 এ উপলব্ধ। এই M3 বিভিন্ন উপাদান দ্বারা ডিফল্টরূপে নিযুক্ত করা হয়.
টাইপোগ্রাফি | টেক্সটস্টাইল |
---|---|
প্রদর্শন | ডিসপ্লে বড়, ডিসপ্লে মিডিয়াম, ডিসপ্লে ছোট |
শিরোনাম | শিরোনাম বড়, শিরোনাম মাঝারি, শিরোনাম ছোট |
লেবেল | লেবেল বড়, লেবেল মাঝারি, লেবেল ছোট |
শরীর | বডি লার্জ, বডি মাঝারি, বডি স্মল, বডি এক্সট্রা স্মল |
সংখ্যা | সংখ্যার অতিরিক্ত বড়, সংখ্যার বড়, সংখ্যার মাঝারি, সংখ্যার ছোট, সংখ্যার অতিরিক্ত ছোট |
অর্ক | arcLarge, arcMedium, arcSmall |
আকৃতি
M3 এর আকৃতির সিস্টেম M2 থেকে আলাদা। আকৃতির প্যারামিটারের সংখ্যা বেড়েছে, তাদের নাম ভিন্নভাবে রাখা হয়েছে, এবং তারা M3 উপাদানে ভিন্নভাবে ম্যাপ করেছে। নিম্নলিখিত আকারের আকার উপলব্ধ:
- অতিরিক্ত-ছোট
- ছোট
- মাঝারি
- বড়
- অতিরিক্ত-বড়
কম্পোজে, এটি M2 Shapes
ক্লাস এবং M3 Shapes
ক্লাসের ক্ষেত্রে প্রযোজ্য:
M2.5
import androidx.wear.compose.material.Shapes
val Shapes = Shapes(
// M2.5 Shapes parameters
)
M3
import androidx.wear.compose.material3.Shapes
val Shapes = Shapes(
// M3 Shapes parameters
)
সূচনা বিন্দু হিসাবে রচনাতে উপাদান 2 থেকে উপাদান 3 থেকে মাইগ্রেট থেকে আকারের প্যারামিটার ম্যাপিং ব্যবহার করুন।
আকার morphing
M3 শেপ মর্ফিং প্রবর্তন করে: মিথস্ক্রিয়াগুলির প্রতিক্রিয়া হিসাবে আকারগুলি এখন morph করে৷
শেপ মর্ফিং আচরণ বেশ কয়েকটি বৃত্তাকার বোতামের পরিবর্তন হিসাবে উপলব্ধ, নিম্নলিখিত বোতামগুলির তালিকা দেখুন যা শেপ মরফিং সমর্থন করে:
বোতাম | শেপ মর্ফিং ফাংশন |
---|---|
| IconButtonDefaults.animatedShape() টিপে আইকন বোতাম অ্যানিমেট করে |
| IconToggleButtonDefaults.animatedShape() টিপে আইকন টগল বোতামটি অ্যানিমেট করে এবং IconToggleButtonDefaults.variantAnimatedShapes() টিপে আইকন টগল বোতামটি অ্যানিমেট করে এবং চেক/আনচেক করুন |
| TextButtonDefaults.animatedShape() টেক্সট বোতাম অ্যানিমেট করে |
| TextToggleButtonDefaults.animatedShapes() প্রেসে টেক্সট টগলকে অ্যানিমেট করে এবং TextToggleButtonDefaults.variantAnimatedShapes() প্রেসে টেক্সট টগলকে অ্যানিমেট করে এবং চেক/আনচেক করে |
উপাদান এবং বিন্যাস
M2.5 থেকে বেশিরভাগ উপাদান এবং লেআউট M3 এ উপলব্ধ। যাইহোক, কিছু M3 উপাদান এবং লেআউট M2.5 এ বিদ্যমান ছিল না। তদ্ব্যতীত, কিছু M3 উপাদানের M2.5-এ তাদের সমতুল্য উপাদানগুলির চেয়ে বেশি বৈচিত্র্য রয়েছে।
যদিও কিছু উপাদানের জন্য বিশেষ বিবেচনার প্রয়োজন হয়, নিম্নলিখিত ফাংশন ম্যাপিংগুলি একটি সূচনা বিন্দু হিসাবে সুপারিশ করা হয়:
এখানে সমস্ত উপাদান 3 উপাদানগুলির একটি সম্পূর্ণ তালিকা রয়েছে:
উপাদান 3 | উপাদান 2.5 সমতুল্য উপাদান (যদি M3 এ নতুন না হয়) |
---|---|
নতুন | |
নতুন | |
android.wear.compose.material.Scaffold ( androidx.wear.compose.material3.ScreenScaffold সহ) | |
নতুন | |
একটি চেকবক্স টগল নিয়ন্ত্রণ সহ androidx.wear.compose.material.ToggleChip | |
androidx.wear.compose.material.Chip (শুধুমাত্র যখন কোন ব্যাকগ্রাউন্ড প্রয়োজন হয় না) | |
নতুন | |
নতুন | |
নতুন | |
androidx.wear.compose.material.Chip যখন একটি টোনাল বোতাম ব্যাকগ্রাউন্ড প্রয়োজন হয় | |
নতুন | |
নতুন | |
নতুন | |
নতুন | |
নতুন | |
একটি রেডিও বোতাম টগল নিয়ন্ত্রণ সহ androidx.wear.compose.material.ToggleChip | |
android.wear.compose.material.Scaffold ( androidx.wear.compose material3.AppScaffold সহ) | |
androidx.wear.compose.material3.SegmentedCircularProgressIndicator | নতুন |
androidx.wear.compose.material.SwipeToRevealCard এবং androidx.wear.compose.material.SwipeToRevealChip | |
একটি সুইচ টগল নিয়ন্ত্রণ সহ androidx.wear.compose.material.ToggleChip | |
নতুন |
এবং পরিশেষে Wear Compose Foundation লাইব্রেরি থেকে কিছু প্রাসঙ্গিক উপাদানের একটি তালিকা, প্রথমে 1.6.0-alpha03 সংস্করণে প্রবর্তিত হয়েছে:
Wear Compose Foundation 1.6.0-alpha03 | |
---|---|
একটি অ্যাপ্লিকেশনে কম্পোজেবল টীকা করতে, কম্পোজিশনের সক্রিয় অংশের ট্র্যাক রাখতে এবং ফোকাস সমন্বয় করতে ব্যবহৃত হয়। | |
একটি অনুভূমিকভাবে স্ক্রলিং পেজার, যা Wear-নির্দিষ্ট বর্ধিতকরণ সহ কম্পোজ ফাউন্ডেশন উপাদানগুলিতে তৈরি করা হয়েছে কার্যক্ষমতা উন্নত করতে এবং Wear OS নির্দেশিকা মেনে চলা। | |
একটি উল্লম্বভাবে স্ক্রলিং পেজার, পরিধান-নির্দিষ্ট বর্ধিতকরণ সহ কম্পোজ ফাউন্ডেশন উপাদানগুলির উপর তৈরি করা হয়েছে কার্যক্ষমতা উন্নত করতে এবং Wear OS নির্দেশিকা মেনে চলা। | |
প্রতিটি আইটেমে স্ক্রোল ট্রান্সফর্ম প্রভাব যুক্ত করতে | |
বোতাম
M3 এর বোতামগুলি M2.5 থেকে আলাদা। M2.5 চিপটি বোতাম দ্বারা প্রতিস্থাপিত হয়েছে। Button
বাস্তবায়ন Text
maxLines
এবং textAlign
জন্য ডিফল্ট মান প্রদান করে। সেই ডিফল্ট মানগুলি Text
উপাদানে ওভাররাইড করা যেতে পারে।
M2.5
import androidx.wear.compose.material.Chip
//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)
M3
import androidx.wear.compose.material3.Button
//M3 Buttons
Button(...)
CompactButton(...)
IconButton(...)
TextButton(...)
M3 এছাড়াও নতুন বোতাম বৈচিত্র অন্তর্ভুক্ত. কম্পোজ ম্যাটেরিয়াল 3 এপিআই রেফারেন্স ওভারভিউতে সেগুলি দেখুন।
M3 একটি নতুন বোতাম প্রবর্তন করেছে: EdgeButton
। EdgeButton
4টি ভিন্ন আকারে পাওয়া যায়: অতিরিক্ত ছোট, ছোট, মাঝারি এবং বড়। EdgeButton
বাস্তবায়ন maxLines
জন্য একটি ডিফল্ট মান প্রদান করে যা কাস্টমাইজ করা যেতে পারে তার উপর নির্ভর করে।
আপনি যদি TransformingLazyColumn
এবং ScalingLazyColumn
ব্যবহার করেন, তাহলে EdgeButton
টিকে ScreenScaffold
এ পাস করুন যাতে এটি রূপান্তরিত হয়, স্ক্রোলিং এর মাধ্যমে এর আকৃতি পরিবর্তন করে। ScreenScaffold
এবং TransformingLazyColumn
সাথে EdgeButton
কিভাবে ব্যবহার করবেন তা পরীক্ষা করতে নিম্নলিখিত কোডটি দেখুন।
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ScreenScaffold
ScreenScaffold(
scrollState = state,
contentPadding = contentPadding,
edgeButton = {
EdgeButton(...)
}
){ contentPadding ->
TransformingLazyColumn(state = state, contentPadding = contentPadding,){
// additional code here
}
}
ভারা
M3-এ স্ক্যাফোল্ড M2.5 থেকে আলাদা। M3 এ, AppScaffold
এবং নতুন ScreenScaffold
composable স্ক্যাফোল্ড প্রতিস্থাপন করেছে। AppScaffold
এবং ScreenScaffold
একটি স্ক্রিনের কাঠামো তৈরি করে এবং ScrollIndicator
এবং TimeText
উপাদানগুলির স্থানান্তর সমন্বয় করে।
AppScaffold
TimeText
মতো স্ট্যাটিক স্ক্রীন উপাদানগুলিকে সোয়াইপ-টু-খারিজ করার মতো অ্যাপ-মধ্যস্থ ট্রানজিশনের সময় দৃশ্যমান থাকার অনুমতি দেয়। এটি প্রধান অ্যাপ্লিকেশন সামগ্রীর জন্য একটি স্লট প্রদান করে, যা সাধারণত একটি নেভিগেশন উপাদান যেমন SwipeDismissableNavHost
দ্বারা সরবরাহ করা হবে
আপনি কার্যকলাপের জন্য একটি AppScaffold
ঘোষণা করুন এবং প্রতিটি স্ক্রিনের জন্য একটি ScreenScaffold
ব্যবহার করুন৷
M2.5
import androidx.wear.compose.material.Scaffold
Scaffold {...}
M3
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list" ) { composable("message_list") { MessageList(onMessageClick = { id -> navController.navigate("message_detail/$id") }) } composable("message_detail/{id}") { MessageDetail(id = it.arguments?.getString("id")!!) } } } } // Implementation of one of the screens in the navigation @Composable fun MessageDetail(id: String) { // .. Screen level content goes here val scrollState = rememberTransformingLazyColumnState() val padding = rememberResponsiveColumnPadding( first = ColumnItemType.BodyText ) ScreenScaffold( scrollState = scrollState, contentPadding = padding ) { scaffoldPaddingValues -> // Screen content goes here // ...
আপনি যদি HorizontalPagerIndicator সহ একটি HorizontalPager
ব্যবহার করেন, আপনি HorizontalPagerScaffold
এ স্থানান্তর করতে পারেন। HorizontalPagerScaffold
একটি AppScaffold
এর মধ্যে স্থাপন করা হয়েছে। AppScaffold
এবং HorizontalPagerScaffold
একটি পেজারের কাঠামো তৈরি করে এবং HorizontalPageIndicator
এবং TimeText
উপাদানগুলির স্থানান্তর সমন্বয় করে।
HorizontalPagerScaffold
ডিফল্টরূপে স্ক্রিনের কেন্দ্র-প্রান্তে HorizontalPageIndicator
প্রদর্শন করে এবং Pager
পেজ করা হচ্ছে কিনা সে অনুসারে TimeText
এবং HorizontalPageIndicator
দেখানো এবং লুকানোর স্থানাঙ্ক, এটি PagerState
দ্বারা নির্ধারিত হয়।
এছাড়াও একটি নতুন AnimatedPage
উপাদান রয়েছে, যা একটি পেজারের মধ্যে একটি পৃষ্ঠাকে তার অবস্থানের উপর ভিত্তি করে একটি স্কেলিং এবং স্ক্রিম প্রভাব সহ অ্যানিমেট করে।
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.BodyText, ) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth() ) { Text(text = "Pager sample") } } item { if (page == 0) { Text(text = "Page #$page. Swipe right") } else{ Text(text = "Page #$page. Swipe left and right") } } } } } } } }
অবশেষে, M3 একটি VerticalPagerScaffold
প্রবর্তন করে যা HorizontalPagerScaffold
এর মতো একই প্যাটার্ন অনুসরণ করে:
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.VerticalPager
import androidx.wear.compose.foundation.pager.rememberPagerState
AppScaffold {
val pagerState = rememberPagerState(pageCount = { 10 })
VerticalPagerScaffold(pagerState = pagerState) {
VerticalPager(
state = pagerState
) { page ->
AnimatedPage(pageIndex = page, pagerState = pagerState){
ScreenScaffold {
…
}
}
স্থানধারক
M2.5 এবং M3 এর মধ্যে কিছু API পরিবর্তন আছে। Placeholder.PlaceholderDefaults
এখন দুটি মডিফায়ার প্রদান করে:
-
Modifier.placeholder
, যা এখনও লোড করা হয়নি এমন বিষয়বস্তুর পরিবর্তে আঁকা হয়েছে - একটি স্থানধারক শিমার প্রভাব
Modifier.placeholderShimmer
যা একটি স্থানধারক শিমার প্রভাব প্রদান করে যা ডেটা লোড হওয়ার জন্য অপেক্ষা করার সময় একটি অ্যানিমেশন লুপে চলে।
Placeholder
উপাদানে অতিরিক্ত পরিবর্তনের জন্য নিম্নলিখিত টেবিলটি দেখুন।
M2.5 | M3 |
---|---|
| অপসারণ করা হয়েছে |
| অপসারণ করা হয়েছে |
| নাম পরিবর্তন করা হয়েছে |
| অপসারণ করা হয়েছে |
| অপসারণ করা হয়েছে |
| অপসারণ করা হয়েছে |
| অপসারণ করা হয়েছে |
সোয়াইপDismissableNavHost
SwipeDismissableNavHost
হল wear.compose.navigation
এর অংশ। যখন এই উপাদানটি M3 এর সাথে ব্যবহার করা হয়, তখন M3 MaterialTheme LocalSwipeToDismissBackgroundScrimColor
এবং LocalSwipeToDismissContentScrimColor
আপডেট করে।
ট্রান্সফর্মিং লেজিকলাম
TransformingLazyColumn
হল wear.compose.lazy.foundation
এর অংশ এবং স্ক্রল করার সময় তালিকার আইটেমগুলিতে অ্যানিমেশনগুলিকে স্কেলিং এবং মরফ করার জন্য সমর্থন যোগ করে, ব্যবহারকারীর অভিজ্ঞতা বৃদ্ধি করে৷
একইভাবে ScalingLazyColumn
এর মতো, এটি একটি TransformingLazyColumnState
তৈরি করতে rememberTransformingLazyColumnState()
প্রদান করে যা কম্পোজিশন জুড়ে মনে রাখা হয়।
স্কেলিং এবং morphing অ্যানিমেশন যোগ করার জন্য, প্রতিটি তালিকা আইটেম নিম্নলিখিত যোগ করুন:
-
Modifier.transformedHeight
, যা আপনাকে একটিTransformationSpec
ব্যবহার করে আইটেমগুলির রূপান্তরিত উচ্চতা গণনা করতে দেয়, আপনি আরও কাস্টমাইজেশনের প্রয়োজন না হলে আপনিrememberTransformationSpec()
ব্যবহার করতে পারেন। - একটি
SurfaceTransformation
val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.Button, ) val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
দরকারী লিঙ্ক
রচনায় M2.5 থেকে M3 তে স্থানান্তরিত করার বিষয়ে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন৷