| 
					
				 | 
			
			
				@@ -1,3 +1,329 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<script setup lang="ts"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { useStore } from "vuex"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	defineAsyncComponent, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ref, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	computed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	onMounted, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	onBeforeUnmount 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} from "vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Sortable } from "sortablejs-vue3"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import Toast from "toasters"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { useModalState, useModalActions } from "@/vuex_helpers"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import ws from "@/ws"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import utils from "@/utils"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const SongItem = defineAsyncComponent( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	() => import("@/components/SongItem.vue") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const Settings = defineAsyncComponent(() => import("./Tabs/Settings.vue")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const AddSongs = defineAsyncComponent(() => import("./Tabs/AddSongs.vue")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const ImportPlaylists = defineAsyncComponent( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	() => import("./Tabs/ImportPlaylists.vue") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const props = defineProps({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	modalUuid: { type: String, default: "" } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const store = useStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const station = computed(() => store.state.station); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const loggedIn = computed(() => store.state.user.auth.loggedIn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const userId = computed(() => store.state.user.auth.userId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const userRole = computed(() => store.state.user.auth.role); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { socket } = store.state.websockets; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const drag = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const apiDomain = ref(""); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const gettingSongs = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const tabs = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const songItems = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const playlistSongs = computed({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	get: () => store.state.modals.editPlaylist[props.modalUuid].playlist.songs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	set: value => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		store.commit( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			`modals/editPlaylist/${props.modalUuid}/updatePlaylistSongs`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const modalState = useModalState("modals/editPlaylist/MODAL_UUID", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	modalUuid: props.modalUuid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const playlistId = computed(() => modalState.playlistId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const tab = computed(() => modalState.tab); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const playlist = computed(() => modalState.playlist); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { setPlaylist, clearPlaylist, addSong, removeSong, repositionedSong } = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	useModalActions( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"modals/editPlaylist/MODAL_UUID", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		[ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"setPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"clearPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"addSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"removeSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"repositionedSong" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			modalUuid: props.modalUuid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const closeCurrentModal = () => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	store.dispatch("modalVisibility/closeCurrentModal"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const showTab = payload => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	tabs.value[`${payload}-tab`].scrollIntoView({ block: "nearest" }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	store.dispatch(`modals/editPlaylist/${props.modalUuid}/showTab`, payload); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isEditable = () => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(playlist.value.type === "user" || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value.type === "user-liked" || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value.type === "user-disliked") && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(userId.value === playlist.value.createdBy || userRole.value === "admin"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const dragOptions = computed(() => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	animation: 200, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	group: "songs", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	disabled: !isEditable(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ghostClass: "draggable-list-ghost" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const init = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gettingSongs.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch("playlists.getPlaylist", playlistId.value, res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (res.status === "success") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			setPlaylist(res.data.playlist); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gettingSongs.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isAdmin = () => userRole.value === "admin"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isOwner = () => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	loggedIn.value && userId.value === playlist.value.createdBy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const repositionSong = ({ oldIndex, newIndex }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (oldIndex === newIndex) return; // we only need to update when song is moved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const song = playlistSongs.value[oldIndex]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"playlists.repositionSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			...song, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			oldIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			newIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (res.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				repositionedSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					...song, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					newIndex: oldIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					oldIndex: newIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const moveSongToTop = (song, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	repositionSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		oldIndex: index, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		newIndex: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const moveSongToBottom = (song, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	repositionSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		oldIndex: index, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		newIndex: playlistSongs.value.length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const totalLength = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	let length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	playlist.value.songs.forEach(song => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		length += song.duration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return utils.formatTimeLong(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// const shuffle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 	socket.dispatch("playlists.shuffle", playlist.value._id, res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 		new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 		if (res.status === "success") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 			updatePlaylistSongs( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 				res.data.playlist.songs.sort((a, b) => a.position - b.position) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 	}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const removeSongFromPlaylist = id => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"playlists.removeSongFromPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const removePlaylist = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (isOwner()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		socket.dispatch("playlists.remove", playlist.value._id, res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (res.status === "success") closeCurrentModal(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (isAdmin()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		socket.dispatch("playlists.removeAdmin", playlist.value._id, res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (res.status === "success") closeCurrentModal(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const downloadPlaylist = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (apiDomain.value === "") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		apiDomain.value = await lofig.get("backend.apiDomain"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	fetch(`${apiDomain.value}/export/playlist/${playlist.value._id}`, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		credentials: "include" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.then(res => res.blob()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.then(blob => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			const url = window.URL.createObjectURL(blob); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			const a = document.createElement("a"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			a.style.display = "none"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			a.href = url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			a.download = `musare-playlist-${ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				playlist.value._id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}-${new Date().toISOString()}.json`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			document.body.appendChild(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			a.click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			window.URL.revokeObjectURL(url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new Toast("Successfully downloaded playlist."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.catch(() => new Toast("Failed to export and download playlist.")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const addSongToQueue = youtubeId => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"stations.addToQueue", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		station.value._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		youtubeId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const clearAndRefillStationPlaylist = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"playlists.clearAndRefillStationPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const clearAndRefillGenrePlaylist = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"playlists.clearAndRefillGenrePlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		playlist.value._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ws.onConnect(init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"event:playlist.song.added", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (playlist.value._id === res.data.playlistId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				addSong(res.data.song); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ modalUuid: props.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"event:playlist.song.removed", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (playlist.value._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// remove song from array of playlists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				removeSong(res.data.youtubeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ modalUuid: props.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"event:playlist.displayName.updated", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (playlist.value._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				setPlaylist({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					displayName: res.data.displayName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					...playlist.value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ modalUuid: props.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		"event:playlist.song.repositioned", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (playlist.value._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const { song, playlistId } = res.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if (playlist.value._id === playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					repositionedSong(song); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ modalUuid: props.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+onBeforeUnmount(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clearPlaylist(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Delete the VueX module that was created for this modal, after all other cleanup tasks are performed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	store.unregisterModule(["modals", "editPlaylist", props.modalUuid]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	<modal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		:title=" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -23,7 +349,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						<button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							class="button is-default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							:class="{ selected: tab === 'settings' }" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							ref="settings-tab" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							:ref="el => (tabs['settings-tab'] = el)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							@click="showTab('settings')" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							v-if=" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								userId === playlist.createdBy || 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -36,7 +362,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						<button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							class="button is-default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							:class="{ selected: tab === 'add-songs' }" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							ref="add-songs-tab" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							:ref="el => (tabs['add-songs-tab'] = el)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							@click="showTab('add-songs')" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							v-if="isEditable()" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -47,7 +373,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							:class="{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								selected: tab === 'import-playlists' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							ref="import-playlists-tab" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							:ref="el => (tabs['import-playlists-tab'] = el)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							@click="showTab('import-playlists')" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							v-if="isEditable()" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,17 +418,17 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					<aside class="menu"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						<draggable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						<sortable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							:component-data="{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								name: !drag ? 'draggable-list-transition' : null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							v-if="playlistSongs.length > 0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							v-model="playlistSongs" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							:list="playlistSongs" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							item-key="_id" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							v-bind="dragOptions" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							:options="dragOptions" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							@start="drag = true" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							@end="drag = false" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							@change="repositionSong" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							@update="repositionSong" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							<template #item="{ element, index }"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								<div class="menu-list scrollable-list"> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -111,7 +437,12 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 										:class="{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 											'item-draggable': isEditable() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 										}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										:ref="`song-item-${index}`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										:ref=" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+											el => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+												(songItems[ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+													`song-item-${index}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+												] = el) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 									> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 										<template #tippyActions> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 											<i 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -193,7 +524,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 									</song-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							</template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						</draggable> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						</sortable> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						<p v-else-if="gettingSongs" class="nothing-here-text"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							Loading songs... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						</p> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -246,361 +577,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	</modal> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { mapState, mapGetters, mapActions } from "vuex"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import draggable from "vuedraggable"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import Toast from "toasters"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { mapModalState, mapModalActions } from "@/vuex_helpers"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import ws from "@/ws"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import SongItem from "../../SongItem.vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import Settings from "./Tabs/Settings.vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import AddSongs from "./Tabs/AddSongs.vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import ImportPlaylists from "./Tabs/ImportPlaylists.vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import utils from "@/utils"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-export default { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	components: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		draggable, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		SongItem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		Settings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		AddSongs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ImportPlaylists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	props: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		modalUuid: { type: String, default: "" } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	data() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			utils, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			drag: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			apiDomain: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			gettingSongs: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	computed: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapState("station", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			station: state => state.station 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapModalState("modals/editPlaylist/MODAL_UUID", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			playlistId: state => state.playlistId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			tab: state => state.tab, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			playlist: state => state.playlist 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		playlistSongs: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return this.$store.state.modals.editPlaylist[this.modalUuid] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					.playlist.songs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			set(value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.$store.commit( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					`modals/editPlaylist/${this.modalUuid}/updatePlaylistSongs`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapState({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			loggedIn: state => state.user.auth.loggedIn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			userId: state => state.user.auth.userId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			userRole: state => state.user.auth.role 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		dragOptions() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				animation: 200, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				group: "songs", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				disabled: !this.isEditable(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ghostClass: "draggable-list-ghost" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapGetters({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			socket: "websockets/getSocket" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	mounted() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ws.onConnect(this.init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"event:playlist.song.added", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (this.playlist._id === res.data.playlistId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.addSong(res.data.song); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			{ modalUuid: this.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"event:playlist.song.removed", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (this.playlist._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// remove song from array of playlists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.removeSong(res.data.youtubeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			{ modalUuid: this.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"event:playlist.displayName.updated", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (this.playlist._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const playlist = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						displayName: res.data.displayName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						...this.playlist 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.setPlaylist(playlist); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			{ modalUuid: this.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.socket.on( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"event:playlist.song.repositioned", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (this.playlist._id === res.data.playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const { song, playlistId } = res.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (this.playlist._id === playlistId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.repositionedSong(song); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			{ modalUuid: this.modalUuid } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	beforeUnmount() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.clearPlaylist(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// Delete the VueX module that was created for this modal, after all other cleanup tasks are performed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.$store.unregisterModule([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"modals", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"editPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.modalUuid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	methods: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.gettingSongs = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.getPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlistId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (res.status === "success") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.setPlaylist(res.data.playlist); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.gettingSongs = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		isEditable() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				(this.playlist.type === "user" || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.playlist.type === "user-liked" || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.playlist.type === "user-disliked") && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				(this.userId === this.playlist.createdBy || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.userRole === "admin") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		isAdmin() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return this.userRole === "admin"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		isOwner() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return this.loggedIn && this.userId === this.playlist.createdBy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		repositionSong({ moved }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!moved) return; // we only need to update when song is moved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.repositionSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					...moved.element, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					oldIndex: moved.oldIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					newIndex: moved.newIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (res.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.repositionedSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							...moved.element, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							newIndex: moved.oldIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							oldIndex: moved.newIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		moveSongToTop(song, index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.$refs[`song-item-${index}`].$refs.songActions.tippy.hide(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.repositionSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				moved: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					element: song, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					oldIndex: index, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					newIndex: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		moveSongToBottom(song, index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.$refs[`song-item-${index}`].$refs.songActions.tippy.hide(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.repositionSong({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				moved: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					element: song, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					oldIndex: index, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					newIndex: this.playlistSongs.length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		totalLength() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.playlist.songs.forEach(song => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				length += song.duration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return this.utils.formatTimeLong(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		shuffle() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.shuffle", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (res.status === "success") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.updatePlaylistSongs( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							res.data.playlist.songs.sort( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								(a, b) => a.position - b.position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		removeSongFromPlaylist(id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.removeSongFromPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		removePlaylist() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (this.isOwner()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					"playlists.remove", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (res.status === "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							this.closeModal("editPlaylist"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else if (this.isAdmin()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					"playlists.removeAdmin", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						new Toast(res.message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (res.status === "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							this.closeModal("editPlaylist"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		async downloadPlaylist() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (this.apiDomain === "") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.apiDomain = await lofig.get("backend.apiDomain"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			fetch(`${this.apiDomain}/export/playlist/${this.playlist._id}`, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				credentials: "include" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				.then(res => res.blob()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				.then(blob => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const url = window.URL.createObjectURL(blob); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const a = document.createElement("a"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.style.display = "none"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.href = url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.download = `musare-playlist-${ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.playlist._id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}-${new Date().toISOString()}.json`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					document.body.appendChild(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					window.URL.revokeObjectURL(url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					new Toast("Successfully downloaded playlist."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				.catch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					() => new Toast("Failed to export and download playlist.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		addSongToQueue(youtubeId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"stations.addToQueue", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.station._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				youtubeId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		clearAndRefillStationPlaylist() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.clearAndRefillStationPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		clearAndRefillGenrePlaylist() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.socket.dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				"playlists.clearAndRefillGenrePlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.playlist._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				data => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (data.status !== "success") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						new Toast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							content: `Error: ${data.message}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							timeout: 8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					else new Toast({ content: data.message, timeout: 4000 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapActions({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			showTab(dispatch, payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.$refs[`${payload}-tab`].scrollIntoView({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					block: "nearest" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return dispatch( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					`modals/editPlaylist/${this.modalUuid}/showTab`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					payload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapModalActions("modals/editPlaylist/MODAL_UUID", [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"setPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"clearPlaylist", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"addSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"removeSong", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"repositionedSong" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		...mapActions("modalVisibility", ["openModal", "closeModal"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-</script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <style lang="less" scoped> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 .night-mode { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	.label, 
			 |