Apakah elemen khusus HTML5 valid?


181

Saya tidak dapat menemukan jawaban pasti apakah tag khusus valid dalam HTML5, seperti ini:

<greeting>Hello!</greeting>

Saya tidak menemukan apa pun di spec dengan cara apa pun:

http://dev.w3.org/html5/spec/single-page.html

Dan tag khusus tampaknya tidak divalidasi dengan validator W3C.


2
Anda mungkin tidak ingin memasukkan terlalu banyak stok dalam artikel HTML5 yang ditulis lebih dari 4,5 tahun yang lalu.
jessegavin

9
Artikel Crockford sangat aneh. Kalimat penting adalah "Ini proposal saya untuk HTML 5 yang lebih ramah dan lembut". Dengan kata lain, ini bukan HTML5 yang kita kenal sekarang, tetapi proposal untuk HTML 5 yang berbeda sebagai pengganti HTML 4. Aneh, karena bertanggal November 2007, ketika W3C sudah bekerja pada HTML5 selama hampir setahun. . Penggunaan kata "diizinkan" di sini membingungkan. Tag khusus tidak pernah "sesuai" / "valid", tetapi pengurai peramban terus berfungsi di hadapan mereka. Lagi pula, proposal Crockford tidak mendapat daya tarik sama sekali. Hampir tidak ada bagian dari itu yang dimasukkan ke dalam HTML5.
Alohci

3
Elemen khusus menjadi kelas satu sekarang karena standar W3 yang muncul untuk Komponen Web Elemen Kustom mulai mendarat di Firefox dan Chrome: dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/…
csuwldcat

3
Adapun Douglas Crockford, saya tergoda untuk percaya semua yang dia katakan.
wnrph

1
Tabel dukungan browser web untuk elemen khusus caniuse.com/#feat=custom-elements
Adrien Be

Jawaban:


169

The Kustom Elements spesifikasi tersedia di Chrome dan Opera, dan menjadi tersedia di browser lain . Ini menyediakan sarana untuk mendaftarkan elemen khusus secara formal.

Elemen khusus adalah tipe baru elemen DOM yang dapat ditentukan oleh penulis. Tidak seperti dekorator , yang stateless dan sementara, elemen khusus dapat merangkum status dan menyediakan antarmuka skrip.

Elemen khusus adalah bagian dari spesifikasi W3 yang lebih besar yang disebut Komponen Web , bersama dengan Templat, Impor HTML, dan Shadow DOM.

Komponen Web memungkinkan penulis aplikasi Web untuk mendefinisikan widget dengan tingkat kekayaan visual dan interaktivitas yang tidak mungkin dengan CSS saja, dan kemudahan komposisi dan penggunaan kembali tidak mungkin dengan pustaka skrip saat ini.

Namun, dari penelusuran yang luar biasa ini melalui artikel tentang Google Developers tentang Custom Elements v1:

Nama elemen khusus harus mengandung tanda hubung ( -). Jadi <x-tags>,, <my-element>dan <my-awesome-app>semuanya adalah nama yang valid, sementara <tabs>dan <foo_bar>tidak. Persyaratan ini agar pengurai HTML dapat membedakan elemen khusus dari elemen biasa. Itu juga memastikan kompatibilitas maju ketika tag baru ditambahkan ke HTML.

Beberapa sumber daya


3
Itu jawaban yang bagus (+1) tetapi aturannya agak melingkar. "Pengguna tidak boleh melakukan hal-hal yang tidak diizinkan ..."
Alohci

8
@Alohci Anda harus menambahkan 3 kata berikutnya ke kutipan Anda: "dengan spesifikasi ini".
jessegavin

1
Saya juga membaca bagian spek itu, dan itu benar-benar membingungkan saya. Inilah alasannya: 1) atribut khusus diizinkan dalam HTML5. Ini menegaskan pengamatan argumen melingkar Alochi. 2) Tidak ada spesifikasi mengatakan bahwa elemen kustom tidak diizinkan.
d13

Kutipan ini tidak jelas. Tentunya W3C memiliki sikap yang lebih konkret satu arah atau yang lain?
Flash

2
Tautan ke customelements.io tidak lagi berguna. Apakah Anda keberatan memperbarui / menghapusnya?
Nisarg

22

Itu mungkin dan diizinkan:

Agen pengguna harus memperlakukan elemen dan atribut yang tidak mereka pahami sebagai netral semantik; meninggalkan mereka di DOM (untuk prosesor DOM), dan menata mereka sesuai dengan CSS (untuk prosesor CSS), tetapi tidak menyimpulkan makna dari mereka.

http://www.w3.org/TR/html5/infrastructure.html#extensibility-0

Tetapi, jika Anda ingin menambahkan interaktivitas, Anda harus membuat dokumen Anda tidak valid (tetapi masih berfungsi penuh) untuk mengakomodasi IE 7 dan 8.

Lihat http://blog.svidgen.com/2012/10/building-custom-xhtml5-tags.html (blog saya)


Sepertinya Anda tidak membaca seluruh bagian itu. Tidak hanya sebagian besar tentang atribut , bahkan sangat tidak menyarankan kustomisasi di sana.
Andrew Barber

Mengulangi komentar saya yang lain, ya, saya minta maaf saya tidak tahu bahwa ini adalah blog saya. Saya berasumsi bahwa banyak hal sudah jelas. Artikel ini relevan secara langsung. Dan saya akan menambahkan, itu tidak dimaksudkan sebagai referensi untuk mendukung "klaim" apa pun yang telah saya ajukan, tetapi untuk menunjukkan dalam format yang lebih panjang bagaimana melakukannya agar berfungsi.
svidgen

1
Intinya sederhana ini: spesifikasi secara eksplisit memungkinkan hal-hal ini. Dan dalam sebagian besar konteks perilaku yang mengecilkan hati , spesifikasinya jelas berbicara kepada vendor agen pengguna, bukan penulis HTML.
svidgen

3
Pernyataan yang dikutip di sini di atas tampaknya telah dihapus dalam versi terbaru dari w3.org/TR/html5/introduction.html#extensibility . Sejauh ini, saya masih tidak dapat menemukan dokumentasi tentang apakah penggunaan elemen HTML khusus non-hyphenated dapat valid atau tidak atau apakah Anda memerlukan pernyataan JS untuk memvalidasi elemen HTML khusus hyphenated ( html5rocks.com/en/tutorials/webcomponents/ customelements ).
John Slegers

@ JohnSlegers Ya, sepertinya dokumentasi dan / atau penahannya diatur ulang sedikit. Saya telah memperbarui tautannya. Kutipan dalam jawaban saya terletak di dekat bagian bawah tautan ke Extensibility .
svidgen

14

NB Jawaban di bawah ini benar ketika ditulis pada tahun 2012. Sejak itu, banyak hal telah berubah. Spesifikasi HTML sekarang mendefinisikan dua jenis elemen khusus - "elemen khusus otonom" dan "elemen bawaan yang disesuaikan". Yang pertama dapat pergi ke mana saja konten ungkapan diharapkan; yang sebagian besar tempat di dalam tubuh, tetapi tidak misalnya anak-anak dari elemen ul atau ol, atau elemen tabel selain elemen td, th atau caption. Yang terakhir dapat pergi ke mana saja elemen yang mereka dapat dapat pergi.


Ini sebenarnya adalah konsekuensi dari akumulasi model konten elemen.

Misalnya, elemen root harus berupa htmlelemen.

The htmlelemen hanya dapat berisi Unsur kepala diikuti dengan elemen body.

The bodyelemen hanya dapat berisi konten Arus mana konten aliran didefinisikan sebagai unsur-unsur: a, abbr, address, area (jika turunan dari elemen peta), artikel, selain, audio, b, bdi, bdo, blockquote, br, tombol, kanvas, mengutip, kode, perintah, datalist, del, detail , dfn, div dl, em, embed, fieldset, gambar, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, i, iframe, img, input, in, kbd, keygen, label, peta, tandai, matematika, menu, meter, nav, noscript, objek, ol, output, p, pra, kemajuan, q, ruby, s, samp, skrip, bagian, pilih, kecil, bentang, kuat, gaya ( jika ada atribut scoped), sub, sup, svg, tabel, textarea, waktu,u, ul, var, video, wbr dan Teks

dan seterusnya.

Model konten mengatakan "Anda dapat meletakkan elemen apa pun yang Anda suka di yang ini", yang akan diperlukan untuk elemen / tag khusus.


Oke, jadi kita dapat berasumsi bahwa jika elemen khusus tidak disebutkan, maka mereka juga tidak diizinkan. Tampaknya cukup adil.
d13

4
Jawaban ini sekarang tidak valid, standar Elemen Khusus Komponen Web W3 yang muncul mulai mendarat di browser sekarang: dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/…
csuwldcat

1
@csuwldcat - Sebenarnya tidak. Standar HTML5 atau yang lebih baru masih perlu diperbarui dengan beberapa cara untuk memungkinkan elemen khusus tersebut menjadi bagian dari model kontennya. Ini berita menarik. Di browser mana saya dapat menggunakannya?
Alohci

3
@Alochi - tentu saja spesifikasi lain dengan bahasa lama perlu diperbarui untuk mencerminkan kenyataan baru ini, tetapi HTML adalah standar hidup, dan tidak memblokir spesifikasi lain - pembaruan akan dilakukan setelah kami pindah ke tahap selanjutnya dari standar jalur. Anda dapat bermain-main dengan implementasi asli Komponen Web di Chrome Canary, dan segera di Firefox Aurora. Selain itu, ada polyfill yang tersedia untuk 3 dari 4 spesifikasi Komponen Web yang bekerja dengan sangat baik di semua browser moder saat ini - ini termasuk spesifikasi / fitur Elemen Kustom.
csuwldcat

Jadi elemen khusus dapat diletakkan di tempat-tempat tertentu? Atau apakah Anda mengatakan mereka tidak diizinkan sama sekali?
Melab

12

Atribut dan Elemen Kustom Dasar

Elemen dan atribut khusus valid dalam HTML, asalkan:

  • Nama elemen adalah huruf kecil dan dimulai dengan x-
  • Nama atribut adalah huruf kecil dan mulai dengan data-

Misalnya, <x-foo data-bar="gaz"/>atau <br data-bar="gaz"/>.

Konvensi umum untuk elemen adalah x-foo; x-vendor-featuredirekomendasikan.

Ini menangani sebagian besar kasus, karena itu bisa dibilang jarang bahwa pengembang akan membutuhkan semua kekuatan yang datang dengan mendaftarkan elemen mereka. Sintaksnya juga cukup valid dan stabil. Penjelasan lebih rinci ada di bawah ini.

Atribut dan Elemen Kustom Tingkat Lanjut

Pada 2014, ada cara baru yang lebih baik untuk mendaftarkan elemen dan atribut khusus. Ini tidak akan berfungsi di browser lama seperti IE 9 atau Chrome / Firefox 20. Tapi itu memungkinkan Anda untuk menggunakan HTMLElementantarmuka standar , mencegah tabrakan, menggunakan bukan- x-*dan-bukan- data-*nama, dan menentukan perilaku khusus dan sintaksis untuk browser untuk menghormati . Ini membutuhkan sedikit JavaScript yang mewah, seperti yang dijelaskan dalam tautan di bawah ini.

HTML5 Rocks - Menentukan Elemen Baru di HTML
WebComponents.org - Pengantar Elemen Kustom
W3C - Komponen Web: Elemen Kustom

Mengenai Validitas Sintaks Dasar

Menggunakan data-*untuk nama atribut khusus telah benar-benar valid untuk beberapa waktu, dan bahkan berfungsi dengan versi HTML yang lebih lama.

W3C - HTML5: Extensibility

Sedangkan untuk nama elemen kustom (tidak terdaftar), W3C sangat merekomendasikan untuk melawan mereka, dan menganggapnya tidak sesuai. Tetapi browser diperlukan untuk mendukungnya, dan x-*pengidentifikasi tidak akan bertentangan dengan spesifikasi HTML di masa depan dan x-vendor-featurepengidentifikasi tidak akan bertentangan dengan pengembang lain. DTD khusus dapat digunakan untuk mengatasi browser yang pilih-pilih.

Berikut adalah beberapa kutipan yang relevan dari dokumen resmi:

"Spesifikasi yang berlaku MUNGKIN mendefinisikan konten dokumen baru (misalnya elemen foobar) [...]. Jika sintaks dan semantik dokumen HTML5 yang sesuai tidak berubah oleh penggunaan spesifikasi yang berlaku, maka dokumen tersebut tetap menjadi HTML5 yang sesuai dokumen."

"Agen pengguna harus memperlakukan elemen dan atribut yang mereka tidak pahami sebagai netral semantik; membiarkannya di DOM (untuk prosesor DOM), dan menata mereka sesuai dengan CSS (untuk prosesor CSS), tetapi tidak menyimpulkan makna apa pun dari mereka."

"Agen pengguna tidak bebas untuk menangani dokumen yang tidak sesuai sesuka hati; model pemrosesan yang dijelaskan dalam spesifikasi ini berlaku untuk implementasi terlepas dari kesesuaian dokumen input."

"Antarmuka HTMLUnknownElement harus digunakan untuk elemen HTML yang tidak ditentukan oleh spesifikasi ini."

W3C - HTML5: Menyesuaikan Dokumen
WhatWG - HTML Standard: DOM Elements


11

Saya ingin menunjukkan bahwa kata "valid" dapat memiliki dua arti berbeda dalam konteks ini, yang salah satu di antaranya berpotensi, um, valid.

  1. Haruskah dokumen HTML dengan tag khusus dianggap HTML5 yang valid? Jawabannya jelas "tidak." Spesifikasi ini mencantumkan dengan tepat tag apa yang valid dalam konteks apa. Inilah sebabnya mengapa validator HTML tidak akan menerima dokumen dengan tag khusus, atau dengan tag standar di tempat yang salah (seperti tag "img" di header).

  2. Apakah dokumen HTML dengan tag khusus akan diuraikan dan disajikan dengan cara standar dan jelas di seluruh browser? Di sini, mungkin secara mengejutkan, jawabannya adalah "ya." Meskipun dokumen tersebut secara teknis tidak akan dianggap sebagai HTML5 yang valid, spesifikasi HTML5 menentukan secara spesifik apa yang seharusnya dilakukan browser ketika mereka melihat tag khusus: singkatnya, tag kustom tersebut bertindak seperti a <span>- itu tidak berarti apa-apa dan tidak melakukan apa-apa oleh default, tetapi dapat ditata oleh HTML dan diakses oleh javascript.


5

Elemen HTML khusus adalah standar W3 yang sedang berkembang yang telah saya berikan kontribusi yang memungkinkan Anda mendeklarasikan dan mendaftarkan elemen khusus dengan parser, Anda dapat membaca spek di sini: W3 Web Components Custom Elements spec . Selain itu, Microsoft mendukung perpustakaan (ditulis oleh mantan pengembang Mozilla), yang disebut X-Tag - ini membuat bekerja dengan Komponen Web menjadi lebih mudah.


1
Apakah konsep ini disahkan?
Starx

Sebagian mendarat di Firefox dan Chrome - kami bekerja sama secara erat dan berharap implementasi penuh akan selesai pada akhir 2013.
csuwldcat

1
Sekarang 2014, sudahkah implementasi penuh mendarat?
Hasib Mahmud

1
@JamieHutber dan lihat laman web Anda masuk ke peramban terbaru satu tahun dari sekarang. Aturan # 1 untuk interoperabilitas browser: bermain sesuai aturan.
Tn. Lister

1
@HasibMahmud spesifikasi sekarang telah selesai, dan akan mendarat di Chrome Beta dalam beberapa minggu, Firefox Aurora dalam ~ 6 minggu. Anda dapat menggunakannya di Firefox Aurora hari ini dengan membalikkan bendera config dom.webcomponents.enabledke true.
csuwldcat

4

Untuk memberikan jawaban yang diperbarui yang mencerminkan halaman modern.

Tag khusus valid jika salah satunya,

1) Mereka mengandung tanda hubung

<my-element>

2) Mereka tertanam XML

<greeting xmlns="http://example.com/customNamespace">Hello!</greeting>

Ini mengasumsikan Anda menggunakan doctype HTML5 <!doctype html>

Mempertimbangkan pembatasan sederhana ini sekarang masuk akal untuk melakukan yang terbaik untuk menjaga agar markup HTML Anda tetap valid (tolong berhenti menutup tag seperti <img>dan <hr>, itu konyol dan salah kecuali Anda menggunakan DOCTYPE XHTML, yang Anda mungkin tidak perlu).

Mengingat bahwa HTML5 dengan jelas mendefinisikan aturan parsing, browser yang patuh akan dapat menangani tag apa pun yang Anda lemparkan padanya meskipun itu tidak sepenuhnya valid.


3

Mengutip dari bagian Extensibility dari spesifikasi HTML5 :

Untuk fitur tingkat markup yang dapat terbatas pada serialisasi XML dan tidak perlu didukung dalam serialisasi HTML, vendor harus menggunakan mekanisme namespace untuk menentukan ruang nama kustom di mana elemen dan atribut non-standar didukung.

Jadi jika Anda menggunakan serialisasi XML dari HTML5, legal bagi Anda untuk melakukan sesuatu seperti ini:

<greeting xmlns="http://example.com/customNamespace">Hello!</greeting>

Namun, jika Anda menggunakan sintaks HTML Anda jauh lebih terbatas dalam apa yang dapat Anda lakukan.

Untuk fitur tingkat markup yang dimaksudkan untuk digunakan dengan sintaks HTML, ekstensi harus dibatasi pada atribut baru dari bentuk "fitur x-vendor-fitur" [...] Nama elemen baru tidak boleh dibuat.

Tetapi instruksi tersebut terutama diarahkan pada vendor browser, yang dianggap akan menyediakan gaya visual dan fungsionalitas untuk elemen kustom apa pun yang mereka pilih untuk dibuat.

Untuk seorang penulis, meskipun mungkin legal untuk menyematkan elemen khusus di halaman (setidaknya dalam serialisasi XML), Anda tidak akan mendapatkan apa pun selain sebuah simpul di DOM. Jika Anda ingin elemen kustom Anda benar-benar melakukan sesuatu, atau diberikan dengan cara khusus, Anda harus melihat spesifikasi Elemen Kustom .

Untuk primer yang lebih lembut pada subjek, baca Pengenalan Komponen Web , yang juga mencakup informasi tentang DOM Bayangan dan spesifikasi terkait lainnya. Spesifikasi ini masih dalam konsep saat ini - Anda dapat melihat status saat ini di sini - tetapi sedang dikembangkan secara aktif.

Sebagai contoh, definisi sederhana untuk greetingelemen mungkin terlihat seperti ini:

<element name="greeting">
  <template>
    <style scoped>
      span { color:gray; }
    </style>
    <span>Simon says:</span>
    <q><content/></q>
  </template>
</element>

Ini memberitahu browser untuk membuat konten elemen dalam tanda kutip, dan diawali dengan teks "Simon berkata:" yang ditata dengan warna abu-abu. Biasanya definisi elemen khusus seperti ini akan disimpan dalam file html terpisah yang akan Anda impor dengan tautan.

<link rel="import" href="greeting-definition.html" />

Meskipun Anda juga bisa memasukkannya secara inline jika Anda mau.

Saya telah membuat demonstrasi yang berfungsi dari definisi di atas menggunakan perpustakaan Polyfill Polymer yang dapat Anda lihat di sini . Perhatikan bahwa ini menggunakan versi lama dari perpustakaan Polymer - versi yang lebih baru bekerja sangat berbeda. Namun, dengan spesifikasi yang masih dalam pengembangan, ini bukan sesuatu yang saya sarankan untuk digunakan dalam kode produksi.


2

cukup gunakan apa pun yang Anda inginkan tanpa deklarasi dom

<container>content here</container>

tambahkan gaya Anda sendiri (tampilan: blok) dan itu akan berfungsi dengan browser modern apa pun


1

data-*atribut valid dalam HTML5 dan bahkan dalam HTML4 semua browser web yang digunakan untuk menghormatinya. Menambahkan tag baru secara teknis oke, tetapi tidak disarankan hanya karena:

  1. Ini mungkin bertentangan dengan sesuatu yang ditambahkan di masa depan, dan
  2. Membuat dokumen HTML tidak valid kecuali ditambahkan secara dinamis melalui JavaScript.

Saya menggunakan tag khusus hanya di tempat-tempat yang Google tidak peduli, untuk contoh di iframe mesin permainan, saya membuat <log>tag yang berisi <msg>, <error>dan <warning>- tetapi melalui JavaScript saja. Dan itu sepenuhnya valid, menurut validator. Ia bahkan bekerja di Internet explorer dengan gaya! ;]


1
Itu valid untuk validator karena Anda membuat elemen dengan JavaScript, dan validator tidak melihatnya karena tidak menjalankan JavaScript Anda. Itu hanya akan melihat halaman seperti yang muncul ketika pertama kali dimuat.
animuson

Persis. Meskipun tidak HTML yang valid, tag khusus masih valid SGML dan bagaimanapun juga HTML adalah SGML. CSS dapat digunakan untuk mendesain tag khusus dan berfungsi dengan baik di IE. :) Selain itu, Anda dapat menentukan DTD Anda sendiri dengan elemen kustom Anda sendiri dalam spesifikasi DOCTYPE Anda, jadi tag kustom saya mungkin benar-benar divalidasi bahkan tanpa JavaScript - tapi saya tidak peduli dengan mereka - mesin GUI sistem mesin pasti bukan Google pekerjaan :)
Петър Петров

1
Ya, ada tangkapan. Anda tidak bisa hanya melempar elemen kustom mau tak mau. Anda harus mendefinisikan dan mendaftarkannya ke DTD agar mereka dianggap HTML yang "valid". Hanya karena sesuatu berfungsi tidak berarti itu valid.
animuson

Jika Anda hanya menambahkan kualifikasi ke nama elemen Anda, seperti <x-msg>, <x-log>, dll. Maka Anda akan mematuhi spesifikasi Komponen Web / Elemen Kustom.
Neil Monroe

Dalam mesin game di mana Webkit hanya ada untuk membuat GUI dinamis Anda, tidak ada yang akan peduli tentang DTD juga. Setiap tag diketahui untuk HTML HTMLUnknownElement untuk JS, masih bekerja sempurna dengan JQuery dan CSS, sehingga GUI Anda mendapatkan beberapa semantik di akhir: <inventory>, <item type="potion" sprite="2">- jadi lebih baik untuk disebut SGML + CSS daripada HTML, meskipun begitu elemen HTML yang memiliki definisi bekerja apa adanya - Tombol, daftar, ...
Петър Петров

1

Tag khusus tidak valid dalam HTML5. Tetapi saat ini browser mendukung untuk menguraikannya dan Anda juga dapat menggunakannya menggunakan css. Jadi jika Anda ingin menggunakan tag khusus untuk browser saat ini maka Anda bisa. Tetapi dukungan dapat diambil begitu browser menerapkan standar W3C secara ketat untuk mem-parsing konten HTML.


1
Mungkin itu akan terjadi ketika mereka berhenti mendukung <center>dan <marquee>?
Ravenstine

1

Saya tahu pertanyaan ini sudah lama, tetapi saya telah mempelajari subjek ini dan meskipun beberapa pernyataan di atas benar, mereka bukan satu-satunya cara untuk membuat elemen khusus. Sebagai contoh:

<button id="find">click me</button>
<Query? ?attach="find" ?content="alert( find() );" ?prov="Hello there :D" >
I won't be displayed :D
</Query?>

<style type="text/css">

[\?content] {

display: none;

}

</style>

<script type="text/javascript">

S = document.getElementsByTagName("Query?")[0];

Q = S.getAttribute("?content");

A = document.getElementById( S.getAttribute("?attach") );

function find() {

  return S.getAttribute("?prov");

}

(function() {

A.setAttribute("onclick", Q);

})();

</script>

akan bekerja dengan sangat baik (di versi yang lebih baru dari Google Chrome, IE, FireFox, dan mobile Safari sejauh ini). Yang Anda butuhkan hanyalah karakter alfa (az, AZ) untuk memulai tag, dan kemudian Anda dapat menggunakan salah satu karakter non alpha setelahnya. Jika dalam CSS, Anda harus menggunakan "\" (backslash) untuk menemukan elemen, seperti membutuhkan Query \ ^ {...}. Tetapi di JS, Anda sebut saja bagaimana Anda melihatnya. Saya harap ini membantu. Lihat contoh di sini

-Mink CBOS


3
Ini adalah HTML paling aneh yang pernah saya lihat akhir-akhir ini :)
Dan Dascalescu
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.