You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/ur/7-bank-project/2-forms/README.md

26 KiB

بینکنگ ایپ بنائیں حصہ 2: لاگ ان اور رجسٹریشن فارم بنائیں

لیکچر سے پہلے کا کوئز

لیکچر سے پہلے کا کوئز

تعارف

تقریباً تمام جدید ویب ایپس میں آپ ایک اکاؤنٹ بنا سکتے ہیں تاکہ آپ کے پاس اپنی ذاتی جگہ ہو۔ چونکہ ایک ہی وقت میں کئی صارفین ویب ایپ تک رسائی حاصل کر سکتے ہیں، اس لیے آپ کو ایک ایسا نظام درکار ہوتا ہے جو ہر صارف کا ذاتی ڈیٹا الگ سے محفوظ کرے اور یہ منتخب کرے کہ کون سی معلومات دکھائی جائیں۔ ہم صارف کی شناخت کو محفوظ طریقے سے منظم کرنے کا احاطہ نہیں کریں گے کیونکہ یہ ایک وسیع موضوع ہے، لیکن ہم یہ یقینی بنائیں گے کہ ہر صارف ہماری ایپ پر ایک (یا زیادہ) بینک اکاؤنٹ بنا سکے۔

اس حصے میں ہم HTML فارم استعمال کریں گے تاکہ اپنی ویب ایپ میں لاگ ان اور رجسٹریشن شامل کریں۔ ہم دیکھیں گے کہ ڈیٹا کو سرور API پر پروگرام کے ذریعے کیسے بھیجا جائے، اور آخر میں صارف کے ان پٹ کے لیے بنیادی توثیق کے اصول کیسے متعین کیے جائیں۔

پیشگی شرائط

آپ کو اس سبق کے لیے ویب ایپ کے HTML ٹیمپلیٹس اور روٹنگ مکمل کرنے کی ضرورت ہے۔ آپ کو Node.js انسٹال کرنے اور سرور API کو مقامی طور پر چلانے کی بھی ضرورت ہے تاکہ آپ اکاؤنٹس بنانے کے لیے ڈیٹا بھیج سکیں۔

نوٹ کریں آپ کے پاس ایک ہی وقت میں دو ٹرمینلز چل رہے ہوں گے جیسا کہ نیچے درج ہے:

  1. مرکزی بینک ایپ کے لیے جو ہم نے HTML ٹیمپلیٹس اور روٹنگ سبق میں بنائی تھی۔
  2. بینک ایپ سرور API کے لیے جو ہم نے اوپر سیٹ اپ کیا۔

سبق کے باقی حصے کے ساتھ چلنے کے لیے آپ کو دونوں سرورز کو چلانا ہوگا۔ یہ مختلف پورٹس (پورٹ 3000 اور پورٹ 5000) پر سن رہے ہیں، اس لیے سب کچھ ٹھیک کام کرنا چاہیے۔

آپ یہ کمانڈ ٹرمینل میں چلا کر چیک کر سکتے ہیں کہ سرور صحیح طریقے سے چل رہا ہے:

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

فارم اور کنٹرولز

<form> عنصر HTML دستاویز کے ایک حصے کو انکیپسولیٹ کرتا ہے جہاں صارف انٹرایکٹو کنٹرولز کے ساتھ ڈیٹا داخل اور جمع کر سکتا ہے۔ فارم کے اندر مختلف قسم کے یوزر انٹرفیس (UI) کنٹرولز استعمال کیے جا سکتے ہیں، جن میں سب سے عام <input> اور <button> عناصر ہیں۔

<input> کے مختلف اقسام ہیں، مثلاً صارف کا یوزر نیم داخل کرنے کے لیے آپ یہ استعمال کر سکتے ہیں:

<input id="username" name="username" type="text">

name ایٹریبیوٹ اس پراپرٹی کے نام کے طور پر استعمال ہوگا جب فارم کا ڈیٹا بھیجا جائے گا۔ id ایٹریبیوٹ <label> کو فارم کنٹرول کے ساتھ منسلک کرنے کے لیے استعمال ہوتا ہے۔

<input> اقسام اور دیگر فارم کنٹرولز کی مکمل فہرست دیکھیں تاکہ آپ کو ان تمام نیٹو UI عناصر کا اندازہ ہو جو آپ اپنے UI بناتے وقت استعمال کر سکتے ہیں۔

نوٹ کریں کہ <input> ایک خالی عنصر ہے جس پر آپ کو اختتامی ٹیگ شامل نہیں کرنا چاہیے۔ آپ خود بند ہونے والے <input/> نوٹیشن کا استعمال کر سکتے ہیں، لیکن یہ ضروری نہیں ہے۔

فارم کے اندر <button> عنصر تھوڑا خاص ہے۔ اگر آپ اس کا type ایٹریبیوٹ مخصوص نہیں کرتے، تو یہ دبانے پر خود بخود فارم کا ڈیٹا سرور پر بھیج دے گا۔ یہاں ممکنہ type ویلیوز ہیں:

  • submit: فارم کے اندر ڈیفالٹ، بٹن فارم جمع کرانے کی کارروائی کو متحرک کرتا ہے۔
  • reset: بٹن تمام فارم کنٹرولز کو ان کی ابتدائی قدروں پر ری سیٹ کرتا ہے۔
  • button: بٹن دبانے پر کوئی ڈیفالٹ رویہ تفویض نہ کریں۔ آپ پھر جاوا اسکرپٹ کا استعمال کرتے ہوئے اس پر اپنی مرضی کی کارروائیاں تفویض کر سکتے ہیں۔

کام

آئیے login ٹیمپلیٹ میں ایک فارم شامل کرکے شروع کرتے ہیں۔ ہمیں ایک یوزر نیم فیلڈ اور ایک لاگ ان بٹن کی ضرورت ہوگی۔

<template id="login">
  <h1>Bank App</h1>
  <section>
    <h2>Login</h2>
    <form id="loginForm">
      <label for="username">Username</label>
      <input id="username" name="user" type="text">
      <button>Login</button>
    </form>
  </section>
</template>

اگر آپ قریب سے دیکھیں تو آپ نوٹ کر سکتے ہیں کہ ہم نے یہاں ایک <label> عنصر بھی شامل کیا ہے۔ <label> عناصر UI کنٹرولز کو نام دینے کے لیے استعمال کیے جاتے ہیں، جیسے کہ ہمارا یوزر نیم فیلڈ۔ لیبلز آپ کے فارم کی پڑھنے کی صلاحیت کے لیے اہم ہیں، لیکن اضافی فوائد کے ساتھ بھی آتے ہیں:

  • لیبل کو فارم کنٹرول کے ساتھ منسلک کرنے سے، یہ معاون ٹیکنالوجیز استعمال کرنے والے صارفین (جیسے اسکرین ریڈر) کو یہ سمجھنے میں مدد دیتا ہے کہ ان سے کس ڈیٹا کی توقع کی جا رہی ہے۔
  • آپ لیبل پر کلک کر سکتے ہیں تاکہ براہ راست متعلقہ ان پٹ پر فوکس ڈال سکیں، جو ٹچ اسکرین والے آلات پر پہنچنا آسان بناتا ہے۔

ویب پر رسائی ایک بہت اہم موضوع ہے جسے اکثر نظر انداز کیا جاتا ہے۔ سیمینٹک HTML عناصر کی بدولت، اگر آپ ان کا صحیح استعمال کریں تو قابل رسائی مواد بنانا مشکل نہیں ہے۔ آپ رسائی کے بارے میں مزید پڑھ سکتے ہیں تاکہ عام غلطیوں سے بچ سکیں اور ایک ذمہ دار ڈویلپر بن سکیں۔

اب ہم رجسٹریشن کے لیے دوسرا فارم شامل کریں گے، بالکل پچھلے والے کے نیچے:

<hr/>
<h2>Register</h2>
<form id="registerForm">
  <label for="user">Username</label>
  <input id="user" name="user" type="text">
  <label for="currency">Currency</label>
  <input id="currency" name="currency" type="text" value="$">
  <label for="description">Description</label>
  <input id="description" name="description" type="text">
  <label for="balance">Current balance</label>
  <input id="balance" name="balance" type="number" value="0">
  <button>Register</button>
</form>

value ایٹریبیوٹ کا استعمال کرتے ہوئے ہم کسی دیے گئے ان پٹ کے لیے ڈیفالٹ ویلیو متعین کر سکتے ہیں۔ یہ بھی نوٹ کریں کہ balance کے لیے ان پٹ میں number قسم ہے۔ کیا یہ دوسرے ان پٹس سے مختلف نظر آتا ہے؟ اس کے ساتھ تعامل کرنے کی کوشش کریں۔

کیا آپ صرف کی بورڈ کا استعمال کرتے ہوئے فارم کو نیویگیٹ اور ان کے ساتھ تعامل کر سکتے ہیں؟ آپ یہ کیسے کریں گے؟

سرور پر ڈیٹا بھیجنا

اب جب کہ ہمارے پاس ایک فعال UI ہے، اگلا مرحلہ ڈیٹا کو سرور پر بھیجنا ہے۔ آئیے اپنے موجودہ کوڈ کا استعمال کرتے ہوئے ایک فوری ٹیسٹ کریں: کیا ہوتا ہے اگر آپ لاگ ان یا رجسٹر بٹن پر کلک کریں؟

کیا آپ نے اپنے براؤزر کے URL سیکشن میں تبدیلی دیکھی؟

رجسٹر بٹن پر کلک کرنے کے بعد براؤزر کے URL میں تبدیلی کا اسکرین شاٹ

<form> کے لیے ڈیفالٹ ایکشن یہ ہے کہ فارم کو موجودہ سرور URL پر GET طریقہ کا استعمال کرتے ہوئے جمع کرایا جائے، فارم کا ڈیٹا براہ راست URL میں شامل کرتے ہوئے۔ تاہم، اس طریقے میں کچھ خامیاں ہیں:

  • بھیجے گئے ڈیٹا کا سائز بہت محدود ہے (تقریباً 2000 حروف)
  • ڈیٹا URL میں براہ راست نظر آتا ہے (پاس ورڈز کے لیے اچھا نہیں)
  • یہ فائل اپ لوڈز کے ساتھ کام نہیں کرتا

اسی لیے آپ اسے POST طریقہ استعمال کرنے کے لیے تبدیل کر سکتے ہیں، جو HTTP درخواست کے باڈی میں فارم کا ڈیٹا سرور پر بھیجتا ہے، بغیر پچھلی حدود کے۔

اگرچہ ڈیٹا بھیجنے کے لیے POST سب سے زیادہ عام طور پر استعمال ہونے والا طریقہ ہے، کچھ مخصوص منظرناموں میں GET طریقہ استعمال کرنا بہتر ہوتا ہے، جیسے کہ سرچ فیلڈ کو نافذ کرتے وقت۔

کام

رجسٹریشن فارم میں action اور method پراپرٹیز شامل کریں:

<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">

اب اپنے نام کے ساتھ ایک نیا اکاؤنٹ رجسٹر کرنے کی کوشش کریں۔ رجسٹر بٹن پر کلک کرنے کے بعد آپ کو کچھ اس طرح نظر آنا چاہیے:

ایک براؤزر ونڈو جس کا پتہ localhost:5000/api/accounts ہے، جس میں صارف کے ڈیٹا کے ساتھ JSON اسٹرنگ دکھائی دے رہی ہے

اگر سب کچھ ٹھیک ہو جائے تو سرور آپ کی درخواست کا جواب ایک JSON جواب کے ساتھ دے گا جس میں بنایا گیا اکاؤنٹ ڈیٹا ہوگا۔

دوبارہ اسی نام کے ساتھ رجسٹر کرنے کی کوشش کریں۔ کیا ہوتا ہے؟

صفحہ ری لوڈ کیے بغیر ڈیٹا بھیجنا

جیسا کہ آپ نے شاید محسوس کیا، اس طریقے کے ساتھ ایک معمولی مسئلہ ہے جو ہم نے ابھی استعمال کیا: فارم جمع کراتے وقت، ہم اپنی ایپ سے باہر نکل جاتے ہیں اور براؤزر سرور کے URL پر ری ڈائریکٹ ہو جاتا ہے۔ ہم اپنی ویب ایپ کے ساتھ تمام صفحہ ری لوڈز سے بچنے کی کوشش کر رہے ہیں، کیونکہ ہم ایک سنگل پیج ایپلیکیشن (SPA) بنا رہے ہیں۔

صفحہ ری لوڈ کیے بغیر فارم کا ڈیٹا سرور پر بھیجنے کے لیے، ہمیں جاوا اسکرپٹ کوڈ استعمال کرنا ہوگا۔ <form> عنصر کے action پراپرٹی میں URL ڈالنے کے بجائے، آپ javascript: سٹرنگ کے ساتھ کسی بھی جاوا اسکرپٹ کوڈ کو استعمال کر سکتے ہیں تاکہ ایک حسب ضرورت کارروائی انجام دی جا سکے۔ اس کا استعمال کرنے کا مطلب یہ بھی ہے کہ آپ کو کچھ کاموں کو نافذ کرنا ہوگا جو پہلے براؤزر خود بخود کرتا تھا:

  • فارم کا ڈیٹا حاصل کریں
  • فارم کے ڈیٹا کو مناسب فارمیٹ میں تبدیل اور انکوڈ کریں
  • HTTP درخواست بنائیں اور اسے سرور پر بھیجیں

کام

رجسٹریشن فارم کے action کو تبدیل کریں:

<form id="registerForm" action="javascript:register()">

app.js کھولیں اور register نامی ایک نیا فنکشن شامل کریں:

function register() {
  const registerForm = document.getElementById('registerForm');
  const formData = new FormData(registerForm);
  const data = Object.fromEntries(formData);
  const jsonData = JSON.stringify(data);
}

یہاں ہم getElementById() کا استعمال کرتے ہوئے فارم عنصر کو حاصل کرتے ہیں اور FormData ہیلپر کا استعمال کرتے ہیں تاکہ فارم کنٹرولز سے قدروں کو کلیدی/ویلیو جوڑوں کے سیٹ کے طور پر نکالا جا سکے۔ پھر ہم ڈیٹا کو ایک باقاعدہ آبجیکٹ میں تبدیل کرتے ہیں Object.fromEntries() کا استعمال کرتے ہوئے اور آخر میں ڈیٹا کو JSON میں سیریلائز کرتے ہیں، جو ویب پر ڈیٹا کے تبادلے کے لیے عام طور پر استعمال ہونے والا فارمیٹ ہے۔

ڈیٹا اب سرور پر بھیجنے کے لیے تیار ہے۔ createAccount نامی ایک نیا فنکشن بنائیں:

async function createAccount(account) {
  try {
    const response = await fetch('//localhost:5000/api/accounts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: account
    });
    return await response.json();
  } catch (error) {
    return { error: error.message || 'Unknown error' };
  }
}

یہ فنکشن کیا کر رہا ہے؟ سب سے پہلے، یہاں async کلیدی لفظ پر توجہ دیں۔ اس کا مطلب ہے کہ فنکشن میں ایسا کوڈ شامل ہے جو غیر متزامن طور پر عمل کرے گا۔ await کلیدی لفظ کے ساتھ استعمال ہونے پر، یہ غیر متزامن کوڈ کے عمل کا انتظار کرنے کی اجازت دیتا ہے - جیسے یہاں سرور کے جواب کا انتظار کرنا - اس سے پہلے کہ آگے بڑھا جائے۔

fetch() API کا استعمال کرتے ہوئے ہم JSON ڈیٹا سرور پر بھیجتے ہیں۔ یہ طریقہ 2 پیرامیٹرز لیتا ہے:

  • سرور کا URL، اس لیے ہم یہاں //localhost:5000/api/accounts واپس ڈال دیتے ہیں۔
  • درخواست کی ترتیبات۔ یہیں پر ہم طریقہ POST پر سیٹ کرتے ہیں اور درخواست کے لیے body فراہم کرتے ہیں۔ چونکہ ہم سرور پر JSON ڈیٹا بھیج رہے ہیں، ہمیں Content-Type ہیڈر کو application/json پر سیٹ کرنے کی بھی ضرورت ہے تاکہ سرور کو معلوم ہو کہ مواد کو کیسے سمجھنا ہے۔

چونکہ سرور درخواست کا جواب JSON کے ساتھ دے گا، ہم await response.json() کا استعمال کرتے ہوئے JSON مواد کو پارس کر سکتے ہیں اور نتیجے میں آنے والے آبجیکٹ کو واپس کر سکتے ہیں۔ نوٹ کریں کہ یہ طریقہ غیر متزامن ہے، اس لیے ہم یہاں await کلیدی لفظ استعمال کرتے ہیں تاکہ یہ یقینی بنایا جا سکے کہ پارسنگ کے دوران ہونے والی کوئی بھی غلطیاں بھی پکڑی جائیں۔

اب register فنکشن میں کچھ کوڈ شامل کریں تاکہ createAccount() کو کال کریں:

const result = await createAccount(jsonData);

چونکہ ہم یہاں await کلیدی لفظ استعمال کرتے ہیں، ہمیں register فنکشن سے پہلے async کلیدی لفظ شامل کرنے کی ضرورت ہے:

async function register() {

آخر میں، نتیجہ چیک کرنے کے لیے کچھ لاگز شامل کریں۔ حتمی فنکشن اس طرح نظر آنا چاہیے:

async function register() {
  const registerForm = document.getElementById('registerForm');
  const formData = new FormData(registerForm);
  const jsonData = JSON.stringify(Object.fromEntries(formData));
  const result = await createAccount(jsonData);

  if (result.error) {
    return console.log('An error occurred:', result.error);
  }

  console.log('Account created!', result);
}

یہ تھوڑا طویل تھا لیکن ہم وہاں پہنچ گئے! اگر آپ اپنے براؤزر ڈویلپر ٹولز کھولیں، اور ایک نیا اکاؤنٹ رجسٹر کرنے کی کوشش کریں، تو آپ کو ویب صفحہ پر کوئی تبدیلی نظر نہیں آنی چاہیے لیکن کنسول میں ایک پیغام ظاہر ہوگا جو اس بات کی تصدیق کرے گا کہ سب کچھ کام کر رہا ہے۔

براؤزر کنسول میں لاگ پیغام دکھانے والے اسکرین شاٹ

کیا آپ کو لگتا ہے کہ ڈیٹا سرور پر محفوظ طریقے سے بھیجا جا رہا ہے؟ اگر کوئی درخواست کو روکنے کے قابل ہو تو کیا ہوگا؟ آپ HTTPS کے بارے میں پڑھ سکتے ہیں تاکہ محفوظ ڈیٹا کمیونیکیشن کے بارے میں مزید جان سکیں۔

ڈیٹا کی توثیق

اگر آپ یوزر نیم سیٹ کیے بغیر نیا اکاؤنٹ رجسٹر کرنے کی کوشش کریں، تو آپ دیکھ سکتے ہیں کہ سرور ایک غلطی واپس کرتا ہے جس کا اسٹیٹس کوڈ 400 (غلط درخواست) ہے۔

سرور کو ڈیٹا بھیجنے سے پہلے یہ ایک اچھی مشق ہے کہ فارم ڈیٹا کی توثیق کریں تاکہ یہ یقینی بنایا جا سکے کہ آپ ایک درست درخواست بھیج رہے ہیں۔ HTML5 فارم کنٹرولز مختلف ایٹریبیوٹس کا استعمال کرتے ہوئے بلٹ ان توثیق فراہم کرتے ہیں:

  • required: فیلڈ کو بھرنا ضروری ہے ورنہ فارم جمع نہیں کیا جا سکتا۔
  • minlength اور maxlength: ٹیکسٹ فیلڈز میں حروف کی کم از کم اور زیادہ سے زیادہ تعداد کی وضاحت کرتا ہے۔
  • min اور max: عددی فیلڈ کی کم از کم اور زیادہ سے زیادہ ویلیو کی وضاحت کرتا ہے۔
  • type: متوقع ڈیٹا کی قسم کی وضاحت کرتا ہے، جیسے number, email, file یا دیگر بلٹ ان اقسام۔ یہ ایٹریبیوٹ فارم کنٹرول کی بصری رینڈرنگ کو بھی تبدیل کر سکتا ہے۔
  • pattern: ایک ریگولر ایکسپریشن پیٹرن کی وضاحت کرنے کی اجازت دیتا ہے تاکہ یہ جانچا جا سکے کہ داخل کردہ ڈیٹا درست ہے یا نہیں۔ آپ اپنے فارم کنٹرولز کی ظاہری شکل کو اس بات پر منحصر کرتے ہوئے حسب ضرورت بنا سکتے ہیں کہ وہ درست ہیں یا نہیں، :valid اور :invalid CSS پیسوڈو کلاسز کا استعمال کرتے ہوئے۔

کام

ایک درست نیا اکاؤنٹ بنانے کے لیے دو ضروری فیلڈز ہیں: یوزر نیم اور کرنسی، جبکہ باقی فیلڈز اختیاری ہیں۔ فارم کے HTML کو اپ ڈیٹ کریں، required ایٹریبیوٹ اور فیلڈ کے لیبل میں متن استعمال کرتے ہوئے:

<label for="user">Username (required)</label>
<input id="user" name="user" type="text" required>
...
<label for="currency">Currency (required)</label>
<input id="currency" name="currency" type="text" value="$" required>

اگرچہ اس خاص سرور امپلیمنٹیشن میں فیلڈز کی زیادہ سے زیادہ لمبائی پر کوئی خاص حد مقرر نہیں کی گئی ہے، لیکن یہ ہمیشہ ایک اچھا عمل ہے کہ کسی بھی یوزر کے ٹیکسٹ انٹری کے لیے مناسب حد مقرر کی جائے۔

ٹیکسٹ فیلڈز میں maxlength ایٹریبیوٹ شامل کریں:

<input id="user" name="user" type="text" maxlength="20" required>
...
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
...
<input id="description" name="description" type="text" maxlength="100">

اب اگر آپ Register بٹن دبائیں اور کوئی فیلڈ ہماری مقرر کردہ ویلیڈیشن رولز کا احترام نہ کرے، تو آپ کو کچھ اس طرح کا پیغام نظر آئے گا:

فارم جمع کرانے کی کوشش کرتے وقت ویلیڈیشن ایرر دکھانے والا اسکرین شاٹ

ایسی ویلیڈیشن جو ڈیٹا سرور کو بھیجنے سے پہلے کی جاتی ہے، اسے کلائنٹ سائیڈ ویلیڈیشن کہا جاتا ہے۔ لیکن نوٹ کریں کہ تمام چیکس ڈیٹا بھیجے بغیر کرنا ہمیشہ ممکن نہیں ہوتا۔ مثال کے طور پر، ہم یہاں یہ چیک نہیں کر سکتے کہ آیا پہلے سے ہی اسی یوزر نیم کے ساتھ کوئی اکاؤنٹ موجود ہے یا نہیں، بغیر سرور کو درخواست بھیجے۔ اضافی ویلیڈیشن جو سرور پر کی جاتی ہے، اسے سرور سائیڈ ویلیڈیشن کہا جاتا ہے۔

عام طور پر دونوں کو نافذ کرنا ضروری ہوتا ہے، اور کلائنٹ سائیڈ ویلیڈیشن یوزر کو فوری فیڈبیک دے کر یوزر کے تجربے کو بہتر بناتی ہے، جبکہ سرور سائیڈ ویلیڈیشن یہ یقینی بناتی ہے کہ آپ جو یوزر ڈیٹا استعمال کر رہے ہیں وہ درست اور محفوظ ہے۔


🚀 چیلنج

HTML میں ایک ایرر میسج دکھائیں اگر یوزر پہلے سے موجود ہو۔

یہاں ایک مثال ہے کہ تھوڑی سی اسٹائلنگ کے بعد فائنل لاگ ان پیج کیسا دکھائی دے سکتا ہے:

CSS اسٹائلز شامل کرنے کے بعد لاگ ان پیج کا اسکرین شاٹ

لیکچر کے بعد کا کوئز

لیکچر کے بعد کا کوئز

جائزہ اور خود مطالعہ

ڈیولپرز فارم بنانے کے حوالے سے بہت تخلیقی ہو گئے ہیں، خاص طور پر ویلیڈیشن حکمت عملیوں کے بارے میں۔ مختلف فارم فلو کے بارے میں جاننے کے لیے CodePen دیکھیں؛ کیا آپ کچھ دلچسپ اور متاثر کن فارم تلاش کر سکتے ہیں؟

اسائنمنٹ

اپنے بینک ایپ کو اسٹائل کریں


ڈسکلیمر:
یہ دستاویز AI ترجمہ سروس Co-op Translator کا استعمال کرتے ہوئے ترجمہ کی گئی ہے۔ ہم درستگی کے لیے کوشش کرتے ہیں، لیکن براہ کرم آگاہ رہیں کہ خودکار ترجمے میں غلطیاں یا غیر درستیاں ہو سکتی ہیں۔ اصل دستاویز کو اس کی اصل زبان میں مستند ذریعہ سمجھا جانا چاہیے۔ اہم معلومات کے لیے، پیشہ ور انسانی ترجمہ کی سفارش کی جاتی ہے۔ ہم اس ترجمے کے استعمال سے پیدا ہونے والی کسی بھی غلط فہمی یا غلط تشریح کے ذمہ دار نہیں ہیں۔