Deskripsi
Catatan: API ini tidak digunakan lagi. Sebagai gantinya, lihat declarativeNetRequest API. Gunakan chrome.declarativeWebRequest API untuk mencegat, memblokir, atau mengubah permintaan yang sedang berlangsung. Solusi ini jauh lebih cepat daripada chrome.webRequest API karena Anda dapat mendaftarkan aturan yang dievaluasi di browser, bukan di mesin JavaScript, sehingga mengurangi latensi bolak-balik dan memungkinkan efisiensi yang lebih tinggi.
Izin
declarativeWebRequestAnda harus mendeklarasikan "deklaratifWebRequest" izin di manifes ekstensi untuk menggunakan izin ini API, beserta izin host.
{
  "name": "My extension",
  ...
  "permissions": [
    "declarativeWebRequest",
    "*://*/*"
  ],
  ...
}
Ketersediaan
Manifes
Perhatikan bahwa jenis tindakan tidak sensitif tertentu tidak memerlukan izin host:
- CancelRequest
- IgnoreRules
- RedirectToEmptyDocument
- RedirectToTransparentImage
Tindakan SendMessageToExtension() memerlukan izin host untuk setiap host yang permintaan jaringannya
yang Anda inginkan untuk memicu pesan.
Semua tindakan lainnya memerlukan izin host untuk semua URL.
Misalnya, jika "https://*.google.com/*" adalah satu-satunya izin host yang dimiliki ekstensi,
ekstensi dapat menyiapkan aturan untuk:
- Batalkan permintaan ke https://www.google.comatauhttps://anything.else.com.
- Kirim pesan saat menavigasi ke https://www.google.com, tetapi tidak kehttps://something.else.com.
Ekstensi tidak dapat menyiapkan aturan untuk mengalihkan https://www.google.com ke https://mail.google.com.
Aturan
Declarative Web Request API mengikuti konsep Declarative API. Anda dapat mendaftar
ke objek peristiwa chrome.declarativeWebRequest.onRequest.
Declarative Web Request API mendukung satu jenis kriteria pencocokan, yaitu RequestMatcher. Tujuan
RequestMatcher cocok dengan permintaan jaringan jika dan hanya jika semua kriteria yang tercantum terpenuhi. Hal berikut
RequestMatcher akan cocok dengan permintaan jaringan saat pengguna memasukkan https://www.example.com di
{i>ominibox<i}:
var matcher = new chrome.declarativeWebRequest.RequestMatcher({
  url: { hostSuffix: 'example.com', schemes: ['http'] },
  resourceType: ['main_frame']
});
Permintaan ke https://www.example.com akan ditolak oleh RequestMatcher karena skema tersebut.
Selain itu, semua permintaan untuk iframe tersemat akan ditolak karena resourceType.
Untuk membatalkan semua permintaan ke "example.com", Anda dapat menentukan aturan sebagai berikut:
var rule = {
  conditions: [
    new chrome.declarativeWebRequest.RequestMatcher({
      url: { hostSuffix: 'example.com' } })
  ],
  actions: [
    new chrome.declarativeWebRequest.CancelRequest()
  ]
};
Untuk membatalkan semua permintaan ke example.com dan foobar.com, Anda dapat menambahkan kondisi kedua.
karena setiap kondisi cukup
untuk memicu semua tindakan yang ditentukan:
var rule2 = {
  conditions: [
    new chrome.declarativeWebRequest.RequestMatcher({
      url: { hostSuffix: 'example.com' } }),
    new chrome.declarativeWebRequest.RequestMatcher({
      url: { hostSuffix: 'foobar.com' } })
  ],
  actions: [
    new chrome.declarativeWebRequest.CancelRequest()
  ]
};
Daftarkan aturan sebagai berikut:
chrome.declarativeWebRequest.onRequest.addRules([rule2]);
Evaluasi kondisi dan tindakan
Declarative Web Request API mengikuti Model siklus proses untuk permintaan web API Permintaan. Artinya, kondisi hanya dapat diuji pada tahap permintaan web tertentu dan, demikian juga, tindakan juga hanya dapat dieksekusi pada tahap tertentu. Tabel berikut mencantumkan yang kompatibel dengan kondisi dan tindakan.
| Tahapan permintaan saat atribut kondisi dapat diproses. | ||||
|---|---|---|---|---|
| Atribut kondisi | onBeforeRequest | onBeforeSendHeaders | onHeadersReceived | onAuthRequired | 
| url | ✓ | ✓ | ✓ | ✓ | 
| resourceType | ✓ | ✓ | ✓ | ✓ | 
| contentType | ✓ | |||
| excludeContentType | ✓ | |||
| responseHeaders | ✓ | |||
| excludeResponseHeaders | ✓ | |||
| requestHeaders | ✓ | |||
| excludeRequestHeaders | ✓ | |||
| thirdPartyForCookies | ✓ | ✓ | ✓ | ✓ | 
| Tahapan permintaan saat tindakan dapat dijalankan. | ||||
| Acara | onBeforeRequest | onBeforeSendHeaders | onHeadersReceived | onAuthRequired | 
| AddRequestCookie | ✓ | |||
| AddResponseCookie | ✓ | |||
| AddResponseHeader | ✓ | |||
| CancelRequest | ✓ | ✓ | ✓ | ✓ | 
| EditRequestCookie | ✓ | |||
| EditResponseCookie | ✓ | |||
| IgnoreRules | ✓ | ✓ | ✓ | ✓ | 
| RedirectByRegEx | ✓ | ✓ | ||
| RedirectRequest | ✓ | ✓ | ||
| RedirectToEmptyDocument | ✓ | ✓ | ||
| RedirectToTransparentImage | ✓ | ✓ | ||
| RemoveRequestCookie | ✓ | |||
| RemoveRequestHeader | ✓ | |||
| RemoveResponseCookie | ✓ | |||
| RemoveResponseHeader | ✓ | |||
| SendMessageToExtension | ✓ | ✓ | ✓ | ✓ | 
| SetRequestHeader | ✓ | |||
Menggunakan prioritas untuk mengganti aturan
Aturan dapat dikaitkan dengan prioritas seperti yang dijelaskan dalam Events API. Mekanisme ini dapat berupa
yang digunakan untuk 
mengekspresikan pengecualian. Contoh berikut memblokir semua permintaan ke gambar yang bernama evil.jpg
kecuali di server "myserver.com".
var rule1 = {
  priority: 100,
  conditions: [
    new chrome.declarativeWebRequest.RequestMatcher({
        url: { pathEquals: 'evil.jpg' } })
  ],
  actions: [
    new chrome.declarativeWebRequest.CancelRequest()
  ]
};
var rule2 = {
  priority: 1000,
  conditions: [
    new chrome.declarativeWebRequest.RequestMatcher({
      url: { hostSuffix: '.myserver.com' } })
  ],
  actions: [
    new chrome.declarativeWebRequest.IgnoreRules({
      lowerPriorityThan: 1000 })
  ]
};
chrome.declarativeWebRequest.onRequest.addRules([rule1, rule2]);
Perlu diketahui bahwa tindakan IgnoreRules tidak dipertahankan di seluruh permintaan
tahap. Semua kondisi semua aturan akan dievaluasi pada setiap tahap permintaan web. Jika
Tindakan IgnoreRules dijalankan, dan hanya berlaku untuk tindakan lain yang dieksekusi untuk
permintaan web dalam tahap yang sama.
Jenis
AddRequestCookie
Menambahkan cookie ke permintaan atau mengganti cookie, jika cookie lain dengan nama yang sama sudah ada. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: AddRequestCookie) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    kueCookie yang akan ditambahkan ke permintaan. Tidak ada kolom yang mungkin tidak ditentukan. 
AddResponseCookie
Menambahkan cookie ke respons atau mengganti cookie, jika cookie lain dengan nama yang sama sudah ada. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: AddResponseCookie) => {...} - 
            akan menampilkan
 
- 
            
- 
    kueCookie yang akan ditambahkan ke respons. Nama dan nilai harus ditentukan. 
AddResponseHeader
Menambahkan header respons ke respons permintaan web ini. Karena beberapa header respons mungkin memiliki nama yang sama, Anda harus menghapus terlebih dahulu lalu menambahkan header respons baru untuk menggantikannya.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: AddResponseHeader) => {...} - 
            akan menampilkan
 
- 
            
- 
    namastring Nama header respons HTTP. 
- 
    nilaistring Nilai header respons HTTP. 
CancelRequest
Tindakan peristiwa deklaratif yang membatalkan permintaan jaringan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: CancelRequest) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
EditRequestCookie
Mengedit satu atau beberapa cookie permintaan. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: EditRequestCookie) => {...} - 
            akan menampilkan
 
- 
            
- 
    filterFilter cookie yang akan diubah. Semua entri kosong akan diabaikan. 
- 
    modifikasiAtribut yang harus diganti dalam cookie yang menggunakan filter. Atribut yang ditetapkan ke string kosong akan dihapus. 
EditResponseCookie
Mengedit satu atau beberapa cookie respons. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: EditResponseCookie) => {...} - 
            akan menampilkan
 
- 
            
- 
    filterFilter cookie yang akan diubah. Semua entri kosong akan diabaikan. 
- 
    modifikasiAtribut yang harus diganti dalam cookie yang menggunakan filter. Atribut yang ditetapkan ke string kosong akan dihapus. 
FilterResponseCookie
Filter cookie di Respons HTTP.
Properti
- 
    ageLowerBoundangka opsional Batas bawah inklusif selama masa aktif cookie (ditentukan dalam detik setelah waktu saat ini). Hanya cookie dengan tanggal habis masa berlaku yang disetel ke 'now + ageLowerBound' atau kemudian memenuhi kriteria ini. Cookie sesi tidak memenuhi kriteria filter ini. Masa aktif cookie dihitung dari 'max-age' atau 'berakhir' atribut cookie. Jika keduanya ditentukan, 'max-age' digunakan untuk menghitung masa berlaku cookie. 
- 
    ageUpperBoundangka opsional Batas atas inklusif selama masa aktif cookie (ditentukan dalam detik setelah waktu saat ini). Hanya cookie dengan tanggal habis masa berlaku yang berada dalam interval [now, now + ageUpperBound] yang memenuhi kriteria ini. Cookie sesi dan cookie sesi dengan waktu tanggal habis masa berlaku yang sudah berlalu tidak memenuhi kriteria filter ini. Masa aktif cookie dihitung dari 'max-age' atau 'berakhir' atribut cookie. Jika keduanya ditentukan, 'max-age' digunakan untuk menghitung masa berlaku cookie. 
- 
    domainstring opsional Nilai atribut cookie Domain. 
- 
    expiresstring opsional Nilai atribut cookie Berakhir. 
- 
    httpOnlystring opsional Keberadaan atribut cookie HttpOnly. 
- 
    maxAgeangka opsional Nilai atribut cookie Usia Maks 
- 
    namastring opsional Nama cookie. 
- 
    jalurstring opsional Nilai atribut cookie Jalur. 
- 
    amanstring opsional Keberadaan atribut cookie Aman. 
- 
    sessionCookieboolean opsional Memfilter cookie sesi. Cookie sesi tidak memiliki masa aktif yang ditentukan dalam 'max-age' atau 'berakhir' . 
- 
    nilaistring opsional Nilai cookie, dapat diisi dengan tanda petik ganda. 
HeaderFilter
Memfilter header permintaan untuk berbagai kriteria. Beberapa kriteria dievaluasi sebagai korelasi.
Properti
- 
    nameContainsstring | string[] opsional Cocok jika nama header berisi semua string yang ditentukan. 
- 
    nameEqualsstring opsional Cocok jika nama header sama dengan string yang ditentukan. 
- 
    namePrefixstring opsional Cocok jika nama header diawali dengan string yang ditentukan. 
- 
    nameSuffixstring opsional Cocok jika nama header diakhiri dengan string yang ditentukan. 
- 
    valueContainsstring | string[] opsional Cocok jika nilai header berisi semua string yang ditentukan. 
- 
    valueEqualsstring opsional Mencocokkan jika nilai header sama dengan string yang ditentukan. 
- 
    valuePrefixstring opsional Cocok jika nilai header dimulai dengan string yang ditentukan. 
- 
    valueSuffixstring opsional Cocok jika nilai header diakhiri dengan string yang ditentukan. 
IgnoreRules
Menyamarkan semua aturan yang cocok dengan kriteria yang ditentukan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: IgnoreRules) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    hasTagstring opsional Jika ditetapkan, aturan dengan tag yang ditentukan akan diabaikan. Pengabaian ini tidak dipertahankan, hanya memengaruhi aturan dan tindakannya pada tahap permintaan jaringan yang sama. Perhatikan bahwa aturan dijalankan dalam urutan prioritas menurun. Tindakan ini memengaruhi aturan yang memiliki prioritas lebih rendah daripada aturan saat ini. Aturan dengan prioritas yang sama dapat diabaikan atau tidak. 
- 
    lowerPriorityThanangka opsional Jika ditetapkan, aturan dengan prioritas yang lebih rendah dari nilai yang ditentukan akan diabaikan. Batas ini tidak dipertahankan, karena hanya memengaruhi aturan dan tindakannya pada tahap permintaan jaringan yang sama. 
RedirectByRegEx
Mengalihkan permintaan dengan menerapkan ekspresi reguler di URL. Ekspresi reguler menggunakan sintaksis RE2.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RedirectByRegEx) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    daristring Pola pencocokan yang mungkin berisi grup tangkapan. Capture group dirujuk dalam sintaks Perl ($1, $2, ...) bukan sintaks RE2 (\1, \2, ...) agar lebih dekat dengan Ekspresi Reguler JavaScript. 
- 
    hinggastring Pola tujuan. 
RedirectRequest
Tindakan peristiwa deklaratif yang mengalihkan permintaan jaringan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RedirectRequest) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    redirectUrlstring Tujuan tempat permintaan dialihkan. 
RedirectToEmptyDocument
Tindakan peristiwa deklaratif yang mengalihkan permintaan jaringan ke dokumen kosong.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RedirectToEmptyDocument) => {...} - 
            akan menampilkan
 
- 
            
RedirectToTransparentImage
Tindakan peristiwa deklaratif yang mengalihkan permintaan jaringan ke gambar transparan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RedirectToTransparentImage) => {...} - 
            akan menampilkan
 
- 
            
RemoveRequestCookie
Menghapus satu atau beberapa cookie permintaan. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RemoveRequestCookie) => {...} - 
            akan menampilkan
 
- 
            
- 
    filterFilter cookie yang akan dihapus. Semua entri kosong akan diabaikan. 
RemoveRequestHeader
Menghapus header permintaan dengan nama yang ditentukan. Jangan gunakan SetRequestHeader dan RemoveRequestHeader dengan nama header yang sama pada permintaan yang sama. Setiap nama header permintaan hanya muncul sekali dalam setiap permintaan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RemoveRequestHeader) => {...} - 
            akan menampilkan
 
- 
            
- 
    namastring Nama header permintaan HTTP (tidak peka huruf besar/kecil). 
RemoveResponseCookie
Menghapus satu atau beberapa cookie respons. Perhatikan bahwa lebih baik menggunakan Cookies API karena secara komputasi lebih murah.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RemoveResponseCookie) => {...} - 
            akan menampilkan
 
- 
            
- 
    filterFilter cookie yang akan dihapus. Semua entri kosong akan diabaikan. 
RemoveResponseHeader
Menghapus semua header respons dari nama dan nilai yang ditentukan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RemoveResponseHeader) => {...} - 
            akan menampilkan
 
- 
            
- 
    namastring Nama header permintaan HTTP (tidak peka huruf besar/kecil). 
- 
    nilaistring opsional Nilai header permintaan HTTP (tidak peka huruf besar/kecil). 
RequestCookie
Filter atau spesifikasi cookie di Permintaan HTTP.
Properti
- 
    namastring opsional Nama cookie. 
- 
    nilaistring opsional Nilai cookie, dapat diisi dengan tanda petik ganda. 
RequestMatcher
Mencocokkan peristiwa jaringan berdasarkan berbagai kriteria.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: RequestMatcher) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    contentTypestring[] opsional Mencocokkan jika jenis media MIME respons (dari header Content-Type HTTP) terdapat dalam daftar. 
- 
    excludeContentTypestring[] opsional Cocok jika jenis media MIME respons (dari header Content-Type HTTP) tidak terdapat dalam daftar. 
- 
    excludeRequestHeadersHeaderFilter[] opsional Cocok jika tidak ada header permintaan yang cocok oleh HeaderFilters mana pun. 
- 
    excludeResponseHeadersHeaderFilter[] opsional Mencocokkan jika tidak ada header respons yang cocok oleh HeaderFilters mana pun. 
- 
    firstPartyForCookiesUrlUrlFilter opsional Tidak digunakan lagiDiabaikan sejak rilis 82. Cocok jika kondisi UrlFilter terpenuhi untuk 'pihak pertama' URL permintaan. 'Pihak pertama' URL permintaan, jika ada, dapat berbeda dari URL target permintaan, dan menjelaskan apa yang dianggap sebagai 'pihak pertama' demi pemeriksaan cookie pihak ketiga. 
- 
    requestHeadersHeaderFilter[] opsional Cocok jika beberapa header permintaan cocok dengan salah satu HeaderFilters. 
- 
    resourceTypeResourceType[] opsional Cocok jika jenis permintaan sebuah permintaan terdapat dalam daftar. Permintaan yang tidak cocok dengan jenis apa pun akan difilter. 
- 
    responseHeadersHeaderFilter[] opsional Cocok jika beberapa header respons cocok dengan salah satu HeaderFilters. 
- 
    tahapStage[] opsional Berisi daftar string yang menjelaskan tahapan. Nilai yang diizinkan adalah 'onBeforeRequest', 'onBeforeSendHeaders', 'onHeadersReceived', 'onAuthRequired'. Jika ada, atribut ini akan membatasi tahapan yang berlaku pada tahapan yang tercantum. Perhatikan bahwa seluruh kondisi hanya berlaku dalam tahapan yang kompatibel dengan semua atribut. 
- 
    thirdPartyForCookiesboolean opsional Tidak digunakan lagiDiabaikan sejak rilis 87. Jika ditetapkan ke true, permintaan pencocokan yang tunduk pada kebijakan cookie pihak ketiga. Jika kebijakan disetel ke salah (false), permintaan tersebut akan cocok dengan semua permintaan lainnya. 
- 
    urlUrlFilter opsional Cocok jika kondisi UrlFilter terpenuhi untuk URL permintaan. 
ResponseCookie
Spesifikasi cookie di Respons HTTP.
Properti
- 
    domainstring opsional Nilai atribut cookie Domain. 
- 
    expiresstring opsional Nilai atribut cookie Berakhir. 
- 
    httpOnlystring opsional Keberadaan atribut cookie HttpOnly. 
- 
    maxAgeangka opsional Nilai atribut cookie Usia Maks 
- 
    namastring opsional Nama cookie. 
- 
    jalurstring opsional Nilai atribut cookie Jalur. 
- 
    amanstring opsional Keberadaan atribut cookie Aman. 
- 
    nilaistring opsional Nilai cookie, dapat diisi dengan tanda petik ganda. 
SendMessageToExtension
Memicu peristiwa declarativeWebRequest.onMessage.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: SendMessageToExtension) => {...} - 
            akan menampilkan
 
- 
            
- 
    pesanstring Nilai yang akan diteruskan dalam atribut messagekamus yang diteruskan ke pengendali peristiwa.
SetRequestHeader
Menetapkan header permintaan nama yang ditentukan ke nilai yang ditentukan. Jika sebelumnya tidak ada header dengan nama yang ditentukan, header baru akan dibuat. Perbandingan nama header selalu tidak peka huruf besar/kecil. Setiap nama header permintaan hanya muncul sekali dalam setiap permintaan.
Properti
- 
    konstruktorvoid Fungsi constructorakan terlihat seperti ini:(arg: SetRequestHeader) => {...} - 
    arg
 - 
            akan menampilkan
 
- 
    
- 
    namastring Nama header permintaan HTTP. 
- 
    nilaistring Nilai header permintaan HTTP. 
Stage
Enum
"onBeforeRequest" 
 
"onBeforeSendHeaders" 
 
"onHeaderReceived" 
 
"onAuthRequired" 
 
Acara
onMessage
chrome.declarativeWebRequest.onMessage.addListener(
callback: function,
)
Diaktifkan saat pesan dikirim melalui declarativeWebRequest.SendMessageToExtension dari tindakan API permintaan web deklaratif.
Parameter
- 
    callbackfungsi Parameter callbackterlihat seperti ini:(details: object) => void - 
    detailobjek - 
    documentIdstring opsional UUID dokumen yang membuat permintaan. 
- 
    documentLifecycleSiklus proses dokumen berada. 
- 
    frameIdangka Nilai 0 menunjukkan bahwa permintaan terjadi di frame utama; nilai positif menunjukkan ID subframe tempat permintaan terjadi. Jika dokumen dari frame (sub) dimuat ( typeadalahmain_frameatausub_frame),frameIdmenunjukkan ID frame ini, bukan ID frame luar. ID frame bersifat unik dalam satu tab.
- 
    frameTypeJenis frame tempat navigasi terjadi. 
- 
    pesanstring Pesan yang dikirim oleh skrip panggilan. 
- 
    methodstring Metode HTTP standar. 
- 
    parentDocumentIdstring opsional UUID dokumen induk yang memiliki frame ini. ID ini tidak disetel jika tidak ada induk. 
- 
    parentFrameIdangka ID frame yang menggabungkan frame yang mengirim permintaan. Setel ke -1 jika tidak ada frame induk. 
- 
    requestIdstring ID permintaan. ID permintaan bersifat unik dalam sesi browser. Akibatnya, keduanya dapat digunakan untuk mengaitkan berbagai peristiwa dari permintaan yang sama. 
- 
    tahapTahap permintaan jaringan saat peristiwa dipicu. 
- 
    tabIdangka ID tab tempat permintaan terjadi. Tetapkan ke -1 jika permintaan tidak terkait dengan tab. 
- 
    timeStampangka Waktu saat sinyal ini dipicu, dalam milidetik sejak epoch. 
- 
    jenisCara penggunaan resource yang diminta. 
- 
    urlstring 
 
- 
    
 
- 
    
onRequest
        Menyediakan Declarative Event API yang terdiri dari addRules, removeRules, dan getRules.
      
Kondisi
Tindakan