@outbook/webcomponents-player 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +126 -0
  3. package/_i18n/af.json +12 -0
  4. package/_i18n/ar.json +12 -0
  5. package/_i18n/bg.json +12 -0
  6. package/_i18n/bn.json +12 -0
  7. package/_i18n/ca.json +12 -0
  8. package/_i18n/cs.json +12 -0
  9. package/_i18n/da.json +12 -0
  10. package/_i18n/de.json +12 -0
  11. package/_i18n/el.json +12 -0
  12. package/_i18n/en.json +12 -0
  13. package/_i18n/es.json +12 -0
  14. package/_i18n/eu.json +12 -0
  15. package/_i18n/fa.json +12 -0
  16. package/_i18n/fi.json +12 -0
  17. package/_i18n/fr.json +12 -0
  18. package/_i18n/gl.json +12 -0
  19. package/_i18n/ha.json +12 -0
  20. package/_i18n/hi.json +12 -0
  21. package/_i18n/hu.json +12 -0
  22. package/_i18n/i18n.js +95 -0
  23. package/_i18n/id.json +12 -0
  24. package/_i18n/it.json +12 -0
  25. package/_i18n/ja.json +12 -0
  26. package/_i18n/km.json +12 -0
  27. package/_i18n/ko.json +12 -0
  28. package/_i18n/lo.json +12 -0
  29. package/_i18n/ms.json +12 -0
  30. package/_i18n/nl.json +12 -0
  31. package/_i18n/no.json +12 -0
  32. package/_i18n/pl.json +12 -0
  33. package/_i18n/pt.json +12 -0
  34. package/_i18n/ro.json +12 -0
  35. package/_i18n/ru.json +12 -0
  36. package/_i18n/sk.json +12 -0
  37. package/_i18n/sv.json +12 -0
  38. package/_i18n/sw.json +12 -0
  39. package/_i18n/th.json +12 -0
  40. package/_i18n/tl.json +12 -0
  41. package/_i18n/tr.json +12 -0
  42. package/_i18n/uk.json +12 -0
  43. package/_i18n/vi.json +12 -0
  44. package/_i18n/zh.json +12 -0
  45. package/_i18n/zu.json +12 -0
  46. package/_lib/background.js +28 -0
  47. package/_lib/controls/index.js +91 -0
  48. package/_lib/cover-fallback/index.js +48 -0
  49. package/_lib/get-cover.js +4 -0
  50. package/_lib/hooks.js +23 -0
  51. package/_lib/order-by-luminance.js +9 -0
  52. package/_lib/playlist/index.js +105 -0
  53. package/_lib/playlist/modules/item-duration.js +17 -0
  54. package/_lib/playlist/modules/show-cover.js +14 -0
  55. package/_lib/rgb-to-hex.js +13 -0
  56. package/_lib/setup-media-session.js +29 -0
  57. package/_lib/timeline/_lib/handle-timeline.js +42 -0
  58. package/_lib/timeline/index.js +121 -0
  59. package/_lib/track-info/index.js +36 -0
  60. package/_lib/track-text/index.js +20 -0
  61. package/_style/_lib/_variables.scss +5 -0
  62. package/_style/_modules/_controls.scss +50 -0
  63. package/_style/_modules/_cover-fallback.scss +52 -0
  64. package/_style/_modules/_playlist.scss +119 -0
  65. package/_style/_modules/_timeline.scss +125 -0
  66. package/_style/_modules/_track-info.scss +54 -0
  67. package/_style/player.style.js +4 -0
  68. package/package.json +48 -0
  69. package/player.js +324 -0
package/_i18n/i18n.js ADDED
@@ -0,0 +1,95 @@
1
+ import defaultLiterals from './en.json';
2
+ import af from './af.json';
3
+ import ar from './ar.json';
4
+ import bg from './bg.json';
5
+ import ca from './ca.json';
6
+ import cs from './cs.json';
7
+ import da from './da.json';
8
+ import de from './de.json';
9
+ import el from './el.json';
10
+ import es from './es.json';
11
+ import eu from './eu.json';
12
+ import fa from './fa.json';
13
+ import fi from './fi.json';
14
+ import fr from './fr.json';
15
+ import gl from './gl.json';
16
+ import ha from './ha.json';
17
+ import hi from './hi.json';
18
+ import hu from './hu.json';
19
+ import id from './id.json';
20
+ import it from './it.json';
21
+ import ja from './ja.json';
22
+ import km from './km.json';
23
+ import ko from './ko.json';
24
+ import lo from './lo.json';
25
+ import ms from './ms.json';
26
+ import nl from './nl.json';
27
+ import no from './no.json';
28
+ import pl from './pl.json';
29
+ import pt from './pt.json';
30
+ import ro from './ro.json';
31
+ import ru from './ru.json';
32
+ import sk from './sk.json';
33
+ import sv from './sv.json';
34
+ import sw from './sw.json';
35
+ import th from './th.json';
36
+ import tl from './tl.json';
37
+ import tr from './tr.json';
38
+ import uk from './uk.json';
39
+ import vi from './vi.json';
40
+ import zh from './zh.json';
41
+ import zu from './zu.json';
42
+
43
+ const literals = {
44
+ af,
45
+ ar,
46
+ bg,
47
+ ca,
48
+ cs,
49
+ da,
50
+ de,
51
+ el,
52
+ en: defaultLiterals,
53
+ es,
54
+ eu,
55
+ fa,
56
+ fi,
57
+ fr,
58
+ gl,
59
+ ha,
60
+ hi,
61
+ hu,
62
+ id,
63
+ it,
64
+ ja,
65
+ km,
66
+ ko,
67
+ lo,
68
+ ms,
69
+ nl,
70
+ no,
71
+ pl,
72
+ pt,
73
+ ro,
74
+ ru,
75
+ sk,
76
+ sv,
77
+ sw,
78
+ th,
79
+ tl,
80
+ tr,
81
+ uk,
82
+ vi,
83
+ zh,
84
+ zu
85
+ };
86
+
87
+ /**
88
+ * @param {string} lang - ISO language code (e.g. "fr", "de").
89
+ * @returns {Promise<Object>} Resolved with the language object.
90
+ */
91
+ export async function loadLiterals(lang) {
92
+ const key = String(lang).trim().toLowerCase();
93
+ const loadedLiterals = literals[key] || defaultLiterals;
94
+ return Promise.resolve(loadedLiterals);
95
+ }
package/_i18n/id.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Lagu berikutnya",
4
+ "pause": "Jeda",
5
+ "play": "Putar",
6
+ "previousTrack": "Lagu sebelumnya",
7
+ "stop": "Berhenti"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Tidak ada lagu yang diputar"
11
+ }
12
+ }
package/_i18n/it.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Prossimo brano",
4
+ "pause": "Pausa",
5
+ "play": "Riproduci",
6
+ "previousTrack": "Brano precedente",
7
+ "stop": "Ferma"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Nessun brano in riproduzione"
11
+ }
12
+ }
package/_i18n/ja.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "次のトラック",
4
+ "pause": "一時停止",
5
+ "play": "再生",
6
+ "previousTrack": "前のトラック",
7
+ "stop": "停止"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "再生中のトラックはありません"
11
+ }
12
+ }
package/_i18n/km.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "បទបន្ទាប់",
4
+ "pause": "ផ្អាក",
5
+ "play": "លេង",
6
+ "previousTrack": "បទមុន",
7
+ "stop": "បញ្ឈប់"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "មិនមានបទចាក់"
11
+ }
12
+ }
package/_i18n/ko.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "다음 트랙",
4
+ "pause": "일시 정지",
5
+ "play": "재생",
6
+ "previousTrack": "이전 트랙",
7
+ "stop": "정지"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "재생 중인 트랙 없음"
11
+ }
12
+ }
package/_i18n/lo.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "ເພງຕໍ່ໄປ",
4
+ "pause": "ຢຸດຊົ່ວຄາວ",
5
+ "play": "ຫຼິ້ນ",
6
+ "previousTrack": "ເພງກ່ອນໜ້າ",
7
+ "stop": "ຢຸດ"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "ບໍ່ມີເພງກຳລັງຫຼິ້ນ"
11
+ }
12
+ }
package/_i18n/ms.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Lagu seterusnya",
4
+ "pause": "Jeda",
5
+ "play": "Main",
6
+ "previousTrack": "Lagu sebelumnya",
7
+ "stop": "Berhenti"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Tiada lagu dimainkan"
11
+ }
12
+ }
package/_i18n/nl.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Volgend nummer",
4
+ "pause": "Pauzeren",
5
+ "play": "Afspelen",
6
+ "previousTrack": "Vorig nummer",
7
+ "stop": "Stoppen"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Geen spelend nummer"
11
+ }
12
+ }
package/_i18n/no.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Neste spor",
4
+ "pause": "Pause",
5
+ "play": "Spill av",
6
+ "previousTrack": "Forrige spor",
7
+ "stop": "Stopp"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Ingen spor spilles av"
11
+ }
12
+ }
package/_i18n/pl.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Następny utwór",
4
+ "pause": "Pauza",
5
+ "play": "Odtwórz",
6
+ "previousTrack": "Poprzedni utwór",
7
+ "stop": "Zatrzymaj"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Brak odtwarzanego utworu"
11
+ }
12
+ }
package/_i18n/pt.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Próxima faixa",
4
+ "pause": "Pausar",
5
+ "play": "Reproduzir",
6
+ "previousTrack": "Faixa anterior",
7
+ "stop": "Parar"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Nenhuma faixa em reprodução"
11
+ }
12
+ }
package/_i18n/ro.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Următoarea piesă",
4
+ "pause": "Pauză",
5
+ "play": "Redare",
6
+ "previousTrack": "Piesa anterioară",
7
+ "stop": "Oprește"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Nicio piesă în redare"
11
+ }
12
+ }
package/_i18n/ru.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Следующий трек",
4
+ "pause": "Пауза",
5
+ "play": "Играть",
6
+ "previousTrack": "Предыдущий трек",
7
+ "stop": "Стоп"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Нет воспроизводимого трека"
11
+ }
12
+ }
package/_i18n/sk.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Ďalšia skladba",
4
+ "pause": "Pozastaviť",
5
+ "play": "Prehrať",
6
+ "previousTrack": "Predchádzajúca skladba",
7
+ "stop": "Zastaviť"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Neprehráva sa žiadna skladba"
11
+ }
12
+ }
package/_i18n/sv.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Nästa spår",
4
+ "pause": "Pausa",
5
+ "play": "Spela",
6
+ "previousTrack": "Föregående spår",
7
+ "stop": "Stoppa"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Inget spår spelas"
11
+ }
12
+ }
package/_i18n/sw.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Wimbo unaofuata",
4
+ "pause": "Sitisha",
5
+ "play": "Cheza",
6
+ "previousTrack": "Wimbo uliopita",
7
+ "stop": "Acha"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Hakuna wimbo unaocheza"
11
+ }
12
+ }
package/_i18n/th.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "เพลงถัดไป",
4
+ "pause": "หยุดชั่วคราว",
5
+ "play": "เล่น",
6
+ "previousTrack": "เพลงก่อนหน้า",
7
+ "stop": "หยุด"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "ไม่มีเพลงที่กำลังเล่นอยู่"
11
+ }
12
+ }
package/_i18n/tl.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Susunod na track",
4
+ "pause": "I-pause",
5
+ "play": "I-play",
6
+ "previousTrack": "Nakaraang track",
7
+ "stop": "Ihinto"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Walang tumutugtog na track"
11
+ }
12
+ }
package/_i18n/tr.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Sonraki parça",
4
+ "pause": "Duraklat",
5
+ "play": "Oynat",
6
+ "previousTrack": "Önceki parça",
7
+ "stop": "Durdur"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Çalan parça yok"
11
+ }
12
+ }
package/_i18n/uk.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Наступний трек",
4
+ "pause": "Пауза",
5
+ "play": "Відтворити",
6
+ "previousTrack": "Попередній трек",
7
+ "stop": "Зупинити"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Немає відтворюваного треку"
11
+ }
12
+ }
package/_i18n/vi.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Bài hát tiếp theo",
4
+ "pause": "Tạm dừng",
5
+ "play": "Phát",
6
+ "previousTrack": "Bài hát trước",
7
+ "stop": "Dừng"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Không có bài hát nào đang phát"
11
+ }
12
+ }
package/_i18n/zh.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "下一曲",
4
+ "pause": "暂停",
5
+ "play": "播放",
6
+ "previousTrack": "上一曲",
7
+ "stop": "停止"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "没有正在播放的曲目"
11
+ }
12
+ }
package/_i18n/zu.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "controls": {
3
+ "nextTrack": "Ingoma elandelayo",
4
+ "pause": "Yimisa okwesikhashana",
5
+ "play": "Dlala",
6
+ "previousTrack": "Ingoma edlule",
7
+ "stop": "Ima"
8
+ },
9
+ "trackInfo": {
10
+ "noPlaying": "Ayikho ingoma edlalayo"
11
+ }
12
+ }
@@ -0,0 +1,28 @@
1
+ import { prominent } from 'color.js';
2
+ import { rgbToHex } from './rgb-to-hex.js';
3
+ import { orderByLuminance } from './order-by-luminance.js';
4
+
5
+ export const emptyBackground = '';
6
+
7
+ export function getBackgroundColor(coverUrl) {
8
+ return prominent(coverUrl, {
9
+ amount: 5,
10
+ format: 'rgb',
11
+ group: 40,
12
+ sample: 10
13
+ }).then(colors => {
14
+ const colorPropsRgb = colors.map(item => ({
15
+ r: item[0],
16
+ g: item[1],
17
+ b: item[2]
18
+ }));
19
+
20
+ const orderedColorsRgb = orderByLuminance(colorPropsRgb);
21
+
22
+ return orderedColorsRgb
23
+ .map((item, index) => {
24
+ return `--player--main-color-${index}: ${rgbToHex(item)};`;
25
+ })
26
+ .join(''); // Return the string!
27
+ });
28
+ }
@@ -0,0 +1,91 @@
1
+ import { virtual } from 'haunted';
2
+ import { html } from 'lit';
3
+ import { TypeIcon } from '@outbook/webcomponents-type-icon/shadow';
4
+ import { skip_next, skip_previous, play_arrow, pause, stop } from '@outbook/icons';
5
+ import { ifDefined } from 'lit/directives/if-defined.js';
6
+ import { isEventClick, isKeyEnterOrKeySpace } from 'a11y-key-conjurer';
7
+ import { classMap } from 'lit/directives/class-map.js';
8
+
9
+ export const Controls = virtual(({ props, handleAudio, literals = {} }) => {
10
+ const { isPlaying = false, playlist, indexSelected } = props;
11
+ const controlsDisabled = !Number.isInteger(indexSelected);
12
+ const controlItems = [
13
+ {
14
+ label: literals.previousTrack,
15
+ icon: 'skip_previous',
16
+ isDisabled: controlsDisabled || indexSelected === 0,
17
+ action: handleAudio.previous,
18
+ id: 'previous'
19
+ },
20
+ isPlaying && !controlsDisabled
21
+ ? {
22
+ label: literals.pause,
23
+ icon: 'pause',
24
+ action: handleAudio.pause,
25
+ isDisabled: false,
26
+ id: 'pause'
27
+ }
28
+ : {
29
+ label: literals.play,
30
+ icon: 'play_arrow',
31
+ action: handleAudio.play,
32
+ isDisabled: controlsDisabled,
33
+ id: 'play'
34
+ },
35
+ {
36
+ label: literals.stop,
37
+ icon: 'stop',
38
+ isDisabled: controlsDisabled,
39
+ action: handleAudio.stop,
40
+ id: 'stop'
41
+ },
42
+ {
43
+ label: literals.nextTrack,
44
+ icon: 'skip_next',
45
+ isDisabled: controlsDisabled || playlist.length - 1 === indexSelected,
46
+ action: handleAudio.next,
47
+ id: 'next'
48
+ }
49
+ ];
50
+
51
+ function handleControl(action) {
52
+ return ev => {
53
+ if (isEventClick(ev) || isKeyEnterOrKeySpace(ev)) {
54
+ action();
55
+ }
56
+ };
57
+ }
58
+
59
+ return html`
60
+ <div class="myth-controls">
61
+ <ul class="myth-controls__items">
62
+ ${controlItems.map(item => {
63
+ const buttonClasses = classMap({
64
+ 'myth-controls__button': true,
65
+ 'is-disabled': item.isDisabled
66
+ });
67
+ return html`
68
+ <li class="myth-controls__item">
69
+ <button
70
+ class="${buttonClasses}"
71
+ aria-label="${item.label}"
72
+ disabled="${ifDefined(
73
+ item.isDisabled ? 'disabled' : undefined
74
+ )}"
75
+ data-test-id="player-button-${item.id}"
76
+ @click="${handleControl(item.action)}"
77
+ @keydown="${handleControl(item.action)}"
78
+ >
79
+ ${TypeIcon({
80
+ icon: item.icon,
81
+ icons: { skip_next, skip_previous, play_arrow, pause, stop },
82
+ extraClasses: 'myth-controls__icon'
83
+ })}
84
+ </button>
85
+ </li>
86
+ `;
87
+ })}
88
+ </ul>
89
+ </div>
90
+ `;
91
+ });
@@ -0,0 +1,48 @@
1
+ import { html } from 'lit';
2
+ import { classMap } from 'lit/directives/class-map.js';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
+ import { TypeIcon } from '@outbook/webcomponents-type-icon/shadow';
5
+ import { audiotrack } from '@outbook/icons';
6
+ import { component } from 'haunted';
7
+
8
+ function CoverFallbackComponent(element) {
9
+ const { props, icon = 'audiotrack' } = element;
10
+ const { isInFileItem } = props;
11
+ const mainClasses = classMap({
12
+ 'cover-fallback': true,
13
+ 'cover-fallback--in-file-item': isInFileItem
14
+ });
15
+ return html`
16
+ <div class="${mainClasses}">
17
+ <div class="cover-fallback__icon">
18
+ ${TypeIcon({
19
+ icon,
20
+ icons: { audiotrack },
21
+ extraClasses: 'cover-fallback__icon-inner'
22
+ })}
23
+ </div>
24
+ </div>
25
+ `;
26
+ }
27
+
28
+ if (!customElements.get('mythical-cover-fallback')) {
29
+ customElements.define(
30
+ 'mythical-cover-fallback',
31
+ component(CoverFallbackComponent, {
32
+ observedAttributes: ['icon'],
33
+ useShadowDOM: false
34
+ })
35
+ );
36
+ }
37
+
38
+ export function CoverFallback(props) {
39
+ const { extraClasses, icon = null } = props;
40
+
41
+ return html`
42
+ <mythical-cover-fallback
43
+ class="${ifDefined(extraClasses || undefined)}"
44
+ icon="${ifDefined(icon || undefined)}"
45
+ .props="${props}"
46
+ ></mythical-cover-fallback>
47
+ `;
48
+ }
@@ -0,0 +1,4 @@
1
+ export function getCover(data) {
2
+ const { path, extension, name } = data;
3
+ return `${path}/${name}.${extension}`;
4
+ }
package/_lib/hooks.js ADDED
@@ -0,0 +1,23 @@
1
+ import { useEffect } from 'haunted';
2
+
3
+ export function useDocumentEvent(eventName, handler, condition) {
4
+ useEffect(() => {
5
+ if (condition) {
6
+ document.addEventListener(eventName, handler);
7
+ return () => {
8
+ document.removeEventListener(eventName, handler);
9
+ };
10
+ }
11
+ }, [eventName, handler, condition]);
12
+ }
13
+
14
+ export function useWindowEvent(eventName, handler, condition = true) {
15
+ useEffect(() => {
16
+ if (condition) {
17
+ window.addEventListener(eventName, handler);
18
+ return () => {
19
+ window.removeEventListener(eventName, handler);
20
+ };
21
+ }
22
+ }, [eventName, handler, condition]);
23
+ }
@@ -0,0 +1,9 @@
1
+ // https://en.wikipedia.org/wiki/Luma_(video)
2
+ const calculateLuminance = p => {
3
+ return 0.2126 * p.r + 0.7152 * p.g + 0.0722 * p.b;
4
+ };
5
+ export const orderByLuminance = rgbValues => {
6
+ return rgbValues.sort((p1, p2) => {
7
+ return calculateLuminance(p2) - calculateLuminance(p1);
8
+ });
9
+ };