Merge remote-tracking branch 'upstream/develop' into betterStorage

* upstream/develop: (23 commits)
  fix lint
  use prime number step for Who to follow panel
  fix
  Revert "Revert "Update messages.js""
  Revert "Update messages.js"
  Update messages.js Update the Occitan language - Fixed Linting
  remove formatting options
  Remove outdated settings
  features panel i18n
  features panes supports chat & gopher
  Simplified image sensitivity label
  show features panel only if not login
  update
  debug
  update
  debug
  mock features panel
  i18n/messages.js: changed Folgende back to Follower
  updated german translation
  updated german translation
  ...
This commit is contained in:
Henry Jameson 2018-09-09 19:36:41 +03:00
commit ce36e8383a
8 changed files with 175 additions and 80 deletions

View file

@ -2,8 +2,9 @@ import UserPanel from './components/user_panel/user_panel.vue'
import NavPanel from './components/nav_panel/nav_panel.vue'
import Notifications from './components/notifications/notifications.vue'
import UserFinder from './components/user_finder/user_finder.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import ChatPanel from './components/chat_panel/chat_panel.vue'
export default {
@ -13,8 +14,9 @@ export default {
NavPanel,
Notifications,
UserFinder,
WhoToFollowPanel,
InstanceSpecificPanel,
FeaturesPanel,
WhoToFollowPanel,
ChatPanel
},
data: () => ({

View file

@ -28,6 +28,7 @@
<user-panel></user-panel>
<nav-panel></nav-panel>
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
<features-panel v-if="!currentUser"></features-panel>
<who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
<notifications v-if="currentUser"></notifications>
</div>

View file

@ -0,0 +1,14 @@
const FeaturesPanel = {
computed: {
chat: function () {
return this.$store.state.config.chatAvailable && (!this.$store.state.chatDisabled)
},
gopher: function () { return this.$store.state.config.gopherAvailable },
whoToFollow: function () { return this.$store.state.config.suggestionsEnabled },
mediaProxy: function () { return this.$store.state.config.mediaProxyAvailable },
scopeOptions: function () { return this.$store.state.config.scopeOptionsEnabled },
textlimit: function () { return this.$store.state.config.textlimit }
}
}
export default FeaturesPanel

View file

@ -0,0 +1,29 @@
<template>
<div class="features-panel">
<div class="panel panel-default base01-background">
<div class="panel-heading timeline-heading base02-background base04">
<div class="title">
{{$t('features_panel.title')}}
</div>
</div>
<div class="panel-body features-panel">
<ul>
<li v-if="chat">{{$t('features_panel.chat')}}</li>
<li v-if="gopher">{{$t('features_panel.gopher')}}</li>
<li v-if="whoToFollow">{{$t('features_panel.who_to_follow')}}</li>
<li v-if="mediaProxy">{{$t('features_panel.media_proxy')}}</li>
<li v-if="scopeOptions">{{$t('features_panel.scope_options')}}</li>
<li>{{$t('features_panel.text_limit')}} = {{textlimit}}</li>
</ul>
</div>
</div>
</div>
</template>
<script src="./features_panel.js" ></script>
<style lang="scss">
.features-panel li {
line-height: 24px;
}
</style>

View file

@ -90,8 +90,7 @@
</div>
<div class="upload_settings" v-if="newStatus.files.length > 0">
<input type="checkbox" id="filesSensitive" v-model="newStatus.nsfw">
<label for="filesSensitive" v-if="newStatus.nsfw">{{$t('post_status.attachments_sensitive')}}</label>
<label for="filesSensitive" v-else v-html="$t('post_status.attachments_not_sensitive')"></label>
<label for="filesSensitive">{{$t('post_status.attachments_sensitive')}}</label>
</div>
</form>
</div>

View file

@ -3,9 +3,10 @@ import apiService from '../../services/api/api.service.js'
function showWhoToFollow (panel, reply) {
var users = reply
var cn
var index = 0
var random = Math.floor(Math.random() * 10)
for (cn = random; cn < users.length; cn = cn + 10) {
var index
var step = 7
cn = Math.floor(Math.random() * step)
for (index = 0; index < 3; index++) {
var user
user = users[cn]
var img
@ -46,11 +47,8 @@ function showWhoToFollow (panel, reply) {
}
})
}
index = index + 1
if (index > 2) {
break
}
}
cn = (cn + step) % users.length
}
function getWhoToFollow (panel) {

View file

@ -10,7 +10,8 @@ const de = {
timeline: 'Zeitleiste',
mentions: 'Erwähnungen',
public_tl: 'Lokale Zeitleiste',
twkn: 'Das gesamte Netzwerk'
twkn: 'Das gesamte Netzwerk',
friend_requests: 'Followanfragen'
},
user_card: {
follows_you: 'Folgt dir!',
@ -21,10 +22,12 @@ const de = {
statuses: 'Beiträge',
mute: 'Stummschalten',
muted: 'Stummgeschaltet',
followers: 'Folgende',
followers: 'Followers',
followees: 'Folgt',
per_day: 'pro Tag',
remote_follow: 'Remote Follow'
remote_follow: 'Folgen',
approve: 'Genehmigen',
deny: 'Ablehnen'
},
timeline: {
show_new: 'Zeige Neuere',
@ -42,12 +45,12 @@ const de = {
bio: 'Bio',
avatar: 'Avatar',
current_avatar: 'Dein derzeitiger Avatar',
set_new_avatar: 'Setze neuen Avatar',
set_new_avatar: 'Setze einen neuen Avatar',
profile_banner: 'Profil Banner',
current_profile_banner: 'Dein derzeitiger Profil Banner',
set_new_profile_banner: 'Setze neuen Profil Banner',
current_profile_banner: 'Der derzeitige Banner deines Profils',
set_new_profile_banner: 'Setze einen neuen Banner für dein Profil',
profile_background: 'Profil Hintergrund',
set_new_profile_background: 'Setze neuen Profil Hintergrund',
set_new_profile_background: 'Setze einen neuen Hintergrund für dein Profil',
settings: 'Einstellungen',
theme: 'Farbschema',
presets: 'Voreinstellungen',
@ -81,15 +84,15 @@ const de = {
autoload: 'Aktiviere automatisches Laden von älteren Beiträgen beim scrollen',
streaming: 'Aktiviere automatisches Laden (Streaming) von neuen Beiträgen',
reply_link_preview: 'Aktiviere reply-link Vorschau bei Maus-Hover',
follow_import: 'Folgeliste importieren',
import_followers_from_a_csv_file: 'Importiere Kontakte, denen du folgen möchtest, aus einer CSV-Datei',
follows_imported: 'Folgeliste importiert! Die Bearbeitung kann eine Zeit lang dauern.',
follow_import_error: 'Fehler beim importieren der Folgeliste',
follow_import: 'Followers importieren',
import_followers_from_a_csv_file: 'Importiere Follower, denen du folgen möchtest, aus einer CSV-Datei',
follows_imported: 'Followers importiert! Die Bearbeitung kann eine Zeit lang dauern.',
follow_import_error: 'Fehler beim importieren der Follower',
delete_account: 'Account löschen',
delete_account_description: 'Lösche deinen Account und alle deine Nachrichten dauerhaft.',
delete_account_instructions: 'Tippe dein Passwort unten in das Feld ein um die Löschung deines Accounts zu bestätigen.',
delete_account_description: 'Lösche deinen Account und alle deine Nachrichten unwiderruflich.',
delete_account_instructions: 'Tippe dein Passwort unten in das Feld ein, um die Löschung deines Accounts zu bestätigen.',
delete_account_error: 'Es ist ein Fehler beim löschen deines Accounts aufgetreten. Tritt dies weiterhin auf, wende dich an den Administrator der Instanz.',
follow_export: 'Folgeliste exportieren',
follow_export: 'Follower exportieren',
follow_export_processing: 'In Bearbeitung. Die Liste steht gleich zum herunterladen bereit.',
follow_export_button: 'Liste (.csv) erstellen',
change_password: 'Passwort ändern',
@ -97,7 +100,8 @@ const de = {
new_password: 'Neues Passwort',
confirm_new_password: 'Neues Passwort bestätigen',
changed_password: 'Passwort erfolgreich geändert!',
change_password_error: 'Es gab ein Problem bei der Änderung des Passworts.'
change_password_error: 'Es gab ein Problem bei der Änderung des Passworts.',
lock_account_description: 'Sperre deinen Account, um neue Follower zu genehmigen oder abzulehnen'
},
notifications: {
notifications: 'Benachrichtigungen',
@ -119,7 +123,8 @@ const de = {
fullname: 'Angezeigter Name',
email: 'Email',
bio: 'Bio',
password_confirm: 'Passwort bestätigen'
password_confirm: 'Passwort bestätigen',
token: 'Einladungsschlüssel'
},
post_status: {
posting: 'Veröffentlichen',
@ -130,7 +135,7 @@ const de = {
scope: {
public: 'Öffentlich - Beitrag an öffentliche Zeitleisten',
unlisted: 'Nicht gelistet - Nicht in öffentlichen Zeitleisten anzeigen',
private: 'Nur Folgende - Beitrag nur an Folgende',
private: 'Nur Follower - Beitrag nur für Follower sichtbar',
direct: 'Direkt - Beitrag nur an erwähnte Profile'
}
},
@ -396,8 +401,7 @@ const en = {
account_not_locked_warning: 'Your account is not {0}. Anyone can follow you to view your follower-only posts.',
account_not_locked_warning_link: 'locked',
direct_warning: 'This post will only be visible to all the mentioned users.',
attachments_sensitive: 'Attachments marked sensitive',
attachments_not_sensitive: 'Attachments <strong>not</strong> marked sensitive',
attachments_sensitive: 'Mark attachments as sensitive',
scope: {
public: 'Public - Post to public timelines',
unlisted: 'Unlisted - Do not post to public timelines',
@ -422,19 +426,28 @@ const en = {
who_to_follow: {
who_to_follow: 'Who to follow',
more: 'More'
},
features_panel: {
title: 'Features',
chat: 'Chat',
gopher: 'Gopher',
who_to_follow: 'Who to follow',
media_proxy: 'Media proxy',
scope_options: 'Scope options',
text_limit: 'Text limit'
}
}
const eo = {
chat: {
title: 'Babilo'
title: 'Babilejo'
},
nav: {
chat: 'Loka babilo',
timeline: 'Tempovido',
chat: 'Loka babilejo',
timeline: 'Tempolinio',
mentions: 'Mencioj',
public_tl: 'Publika tempovido',
twkn: 'Tuta konata reto'
public_tl: 'Publika tempolinio',
twkn: 'La tuta konata reto'
},
user_card: {
follows_you: 'Abonas vin!',
@ -444,26 +457,26 @@ const eo = {
block: 'Bari',
statuses: 'Statoj',
mute: 'Silentigi',
muted: 'Silentigita',
muted: 'Silentigitaj',
followers: 'Abonantoj',
followees: 'Abonatoj',
per_day: 'tage',
remote_follow: 'Fora abono'
remote_follow: 'Fore aboni'
},
timeline: {
show_new: 'Montri novajn',
error_fetching: 'Eraro ĝisdatigante',
error_fetching: 'Eraro dum ĝisdatigo',
up_to_date: 'Ĝisdata',
load_older: 'Enlegi pli malnovajn statojn',
load_older: 'Montri pli malnovajn statojn',
conversation: 'Interparolo',
collapse: 'Maletendi',
repeated: 'ripetata'
},
settings: {
user_settings: 'Uzulaj agordoj',
name_bio: 'Nomo kaj prio',
user_settings: 'Uzantaj agordoj',
name_bio: 'Nomo kaj priskribo',
name: 'Nomo',
bio: 'Prio',
bio: 'Priskribo',
avatar: 'Profilbildo',
current_avatar: 'Via nuna profilbildo',
set_new_avatar: 'Agordi novan profilbildon',
@ -473,9 +486,9 @@ const eo = {
profile_background: 'Profila fono',
set_new_profile_background: 'Agordi novan profilan fonon',
settings: 'Agordoj',
theme: 'Haŭto',
presets: 'Antaŭmetaĵoj',
theme_help: 'Uzu deksesumajn kolorkodojn (#rrvvbb) por adapti vian koloran haŭton.',
theme: 'Etoso',
presets: 'Antaŭagordoj',
theme_help: 'Uzu deksesumajn kolorkodojn (#rrvvbb) por adapti vian koloran etoson.',
radii_help: 'Agordi fasadan rondigon de randoj (rastrumere)',
background: 'Fono',
foreground: 'Malfono',
@ -483,65 +496,65 @@ const eo = {
links: 'Ligiloj',
cBlue: 'Blua (Respondo, abono)',
cRed: 'Ruĝa (Nuligo)',
cOrange: 'Orange (Ŝato)',
cOrange: 'Oranĝa (Ŝato)',
cGreen: 'Verda (Kunhavigo)',
btnRadius: 'Butonoj',
panelRadius: 'Paneloj',
avatarRadius: 'Profilbildoj',
avatarAltRadius: 'Profilbildoj (Sciigoj)',
avatarAltRadius: 'Profilbildoj (sciigoj)',
tooltipRadius: 'Ŝpruchelpiloj/avertoj',
attachmentRadius: 'Kunsendaĵoj',
filtering: 'Filtrado',
filtering_explanation: 'Ĉiuj statoj kun tiuj ĉi vortoj silentiĝos, po unu linie',
attachments: 'Kunsendaĵoj',
hide_attachments_in_tl: 'Kaŝi kunsendaĵojn en tempovido',
hide_attachments_in_tl: 'Kaŝi kunsendaĵojn en tempolinio',
hide_attachments_in_convo: 'Kaŝi kunsendaĵojn en interparoloj',
nsfw_clickthrough: 'Ŝalti traklakan kaŝon de konsternaj kunsendaĵoj',
stop_gifs: 'Movi GIF-bildojn dum ŝvebo',
autoload: 'Ŝalti memfaran enlegadon ĉe subo de paĝo',
streaming: 'Ŝalti memfaran fluigon de novaj afiŝoj ĉe supro de paĝo',
autoload: 'Ŝalti memfaran ŝarĝadon ĉe subo de paĝo',
streaming: 'Ŝalti memfaran fluigon de novaj afiŝoj ĉe la supro de la paĝo',
reply_link_preview: 'Ŝalti respond-ligilan antaŭvidon dum ŝvebo',
follow_import: 'Abona enporto',
import_followers_from_a_csv_file: 'Enporti abonojn de CSV-dosiero',
import_followers_from_a_csv_file: 'Enporti abonojn el CSV-dosiero',
follows_imported: 'Abonoj enportiĝis! Traktado daŭros iom.',
follow_import_error: 'Eraro enportante abonojn'
},
notifications: {
notifications: 'Sciigoj',
read: 'Legita!',
read: 'Legite!',
followed_you: 'ekabonis vin',
favorited_you: 'ŝatis vian staton',
repeated_you: 'ripetis vian staton'
},
login: {
login: 'Saluti',
login: 'Ensaluti',
username: 'Salutnomo',
placeholder: 'ekz. lain',
password: 'Pasvorto',
register: 'Registriĝi',
logout: 'Adiaŭi'
logout: 'Elsaluti'
},
registration: {
registration: 'Registriĝo',
fullname: 'Vidiga nomo',
email: 'Retpoŝtadreso',
bio: 'Prio',
bio: 'Priskribo',
password_confirm: 'Konfirmo de pasvorto'
},
post_status: {
posting: 'Afiŝanta',
default: 'Ĵus alvenis la universalan kongreson!'
posting: 'Afiŝante',
default: 'Ĵus alvenis al la Universala Kongreso!'
},
finder: {
find_user: 'Trovi uzulon',
error_fetching_user: 'Eraro alportante uzulon'
find_user: 'Trovi uzanton',
error_fetching_user: 'Eraro alportante uzanton'
},
general: {
submit: 'Sendi',
apply: 'Apliki'
},
user_profile: {
timeline_title: 'Uzula tempovido'
timeline_title: 'Uzanta tempolinio'
}
}
@ -946,6 +959,15 @@ const ja = {
who_to_follow: {
who_to_follow: 'おすすめユーザー',
more: 'くわしく'
},
features_panel: {
title: 'ゆうこうなきのう',
chat: 'チャット',
gopher: 'Gopher',
who_to_follow: 'おすすめユーザー',
media_proxy: 'メディアプロクシ',
scope_options: 'こうかいはんい',
text_limit: 'もじのかず'
}
}
@ -1157,8 +1179,8 @@ const oc = {
twkn: 'Lo malhum conegut'
},
user_card: {
follows_you: 'Vos sèc!',
following: 'Seguit!',
follows_you: 'Vos sèc!',
following: 'Seguit!',
follow: 'Seguir',
blocked: 'Blocat',
block: 'Blocar',
@ -1203,10 +1225,10 @@ const oc = {
links: 'Ligams',
cBlue: 'Blau (Respondre, seguir)',
cRed: 'Roge (Anullar)',
cOrange: 'Irange (Metre en favorit)',
cOrange: 'Irange (Aimar)',
cGreen: 'Verd (Repartajar)',
inputRadius: 'Camps tèxte',
btnRadius: 'Botons',
inputRadius: 'Camps tèxte',
panelRadius: 'Panèls',
avatarRadius: 'Avatars',
avatarAltRadius: 'Avatars (Notificacions)',
@ -1225,12 +1247,25 @@ const oc = {
follow_import: 'Importar los abonaments',
import_followers_from_a_csv_file: 'Importar los seguidors dun fichièr csv',
follows_imported: 'Seguidors importats. Lo tractament pòt trigar una estona.',
follow_import_error: 'Error en important los seguidors'
follow_import_error: 'Error en important los seguidors',
delete_account: 'Suprimir lo compte',
delete_account_description: 'Suprimir vòstre compte e los messatges per sempre.',
delete_account_instructions: 'Picatz vòstre senhal dins lo camp tèxte çai-jos per confirmar la supression del compte.',
delete_account_error: 'Una error ses producha en suprimir lo compte. Saquò ten darribar mercés de contactar vòstre administrador dinstància.',
follow_export: 'Exportar los abonaments',
follow_export_processing: 'Tractament, vos demandarem lèu de telecargar lo fichièr',
follow_export_button: 'Exportar vòstres abonaments dins un fichièr csv',
change_password: 'Cambiar lo senhal',
current_password: 'Senhal actual',
new_password: 'Nòu senhal',
confirm_new_password: 'Confirmatz lo nòu senhal',
changed_password: 'Senhal corrèctament cambiat',
change_password_error: 'Una error ses producha en cambiant lo senhal.'
},
notifications: {
notifications: 'Notficacions',
read: 'Legit!',
followed_you: 'vos sèc',
read: 'Legit!',
followed_you: 'vos a seguit',
favorited_you: 'a aimat vòstre estatut',
repeated_you: 'a repetit your vòstre estatut'
},
@ -1251,6 +1286,7 @@ const oc = {
},
post_status: {
posting: 'Mandadís',
content_warning: 'Avís de contengut (opcional)',
default: 'Escrivètz aquí vòstre estatut.'
},
finder: {
@ -1506,7 +1542,7 @@ const pt = {
title: 'Chat'
},
nav: {
chat: 'Chat Local',
chat: 'Chat local',
timeline: 'Linha do tempo',
mentions: 'Menções',
public_tl: 'Linha do tempo pública',
@ -1550,16 +1586,28 @@ const pt = {
theme: 'Tema',
presets: 'Predefinições',
theme_help: 'Use cores em código hexadecimal (#rrggbb) para personalizar seu esquema de cores.',
radii_help: 'Arredondar arestas da interface (em píxeis)',
background: 'Plano de Fundo',
foreground: 'Primeiro Plano',
text: 'Texto',
links: 'Links',
cBlue: 'Azul (Responder, seguir)',
cRed: 'Vermelho (Cancelar)',
cOrange: 'Laranja (Favoritar)',
cGreen: 'Verde (Repetir)',
btnRadius: 'Botões',
panelRadius: 'Paineis',
avatarRadius: 'Avatares',
avatarAltRadius: 'Avatares (Notificações)',
tooltipRadius: 'Dicass/alertas',
attachmentRadius: 'Anexos',
filtering: 'Filtragem',
filtering_explanation: 'Todas as postagens contendo estas palavras serão silenciadas, uma por linha.',
attachments: 'Anexos',
hide_attachments_in_tl: 'Ocultar anexos na linha do tempo.',
hide_attachments_in_convo: 'Ocultar anexos em conversas',
nsfw_clickthrough: 'Habilitar clique para ocultar anexos NSFW',
stop_gifs: 'Reproduzir GIFs ao passar o cursor em cima',
autoload: 'Habilitar carregamento automático quando a rolagem chegar ao fim.',
streaming: 'Habilitar o fluxo automático de postagens quando ao topo da página',
reply_link_preview: 'Habilitar a pré-visualização de link de respostas ao passar o mouse.',
@ -1570,8 +1618,10 @@ const pt = {
},
notifications: {
notifications: 'Notificações',
read: 'Ler!',
followed_you: 'seguiu você'
read: 'Lido!',
followed_you: 'seguiu você',
favorited_you: 'favoritou sua postagem',
repeated_you: 'repetiu sua postagem'
},
login: {
login: 'Entrar',
@ -1590,7 +1640,7 @@ const pt = {
},
post_status: {
posting: 'Publicando',
default: 'Acabo de aterrizar em L.A.'
default: 'Acabei de chegar no Rio!'
},
finder: {
find_user: 'Buscar usuário',
@ -1599,6 +1649,9 @@ const pt = {
general: {
submit: 'Enviar',
apply: 'Aplicar'
},
user_profile: {
timeline_title: 'Linha do tempo do usuário'
}
}

View file

@ -117,26 +117,20 @@ window.fetch('/api/statusnet/config.json')
var redirectRootNoLogin = (config.redirectRootNoLogin)
var redirectRootLogin = (config.redirectRootLogin)
var chatDisabled = (config.chatDisabled)
var showWhoToFollowPanel = (config.showWhoToFollowPanel)
var whoToFollowProvider = (config.whoToFollowProvider)
var whoToFollowLink = (config.whoToFollowLink)
var showInstanceSpecificPanel = (config.showInstanceSpecificPanel)
var scopeOptionsEnabled = (config.scopeOptionsEnabled)
var formattingOptionsEnabled = (config.formattingOptionsEnabled)
var collapseMessageWithSubject = (config.collapseMessageWithSubject)
var defaultCollapseMessageWithSubject = (config.collapseMessageWithSubject)
store.dispatch('setOption', { name: 'theme', value: theme })
store.dispatch('setOption', { name: 'background', value: background })
store.dispatch('setOption', { name: 'logo', value: logo })
store.dispatch('setOption', { name: 'logoMask', value: logoMask })
store.dispatch('setOption', { name: 'logoMargin', value: logoMargin })
store.dispatch('setOption', { name: 'showWhoToFollowPanel', value: showWhoToFollowPanel })
store.dispatch('setOption', { name: 'whoToFollowProvider', value: whoToFollowProvider })
store.dispatch('setOption', { name: 'whoToFollowLink', value: whoToFollowLink })
store.dispatch('setOption', { name: 'showInstanceSpecificPanel', value: showInstanceSpecificPanel })
store.dispatch('setOption', { name: 'scopeOptionsEnabled', value: scopeOptionsEnabled })
store.dispatch('setOption', { name: 'formattingOptionsEnabled', value: formattingOptionsEnabled })
store.dispatch('setOption', { name: 'collapseMessageWithSubject', value: collapseMessageWithSubject })
store.dispatch('setOption', { name: 'defaultCollapseMessageWithSubject', value: defaultCollapseMessageWithSubject })
if (chatDisabled) {
store.dispatch('disableChat')
}
@ -225,7 +219,12 @@ window.fetch('/instance/panel.html')
window.fetch('/nodeinfo/2.0.json')
.then((res) => res.json())
.then((data) => {
const suggestions = data.metadata.suggestions
const metadata = data.metadata
store.dispatch('setOption', { name: 'mediaProxyAvailable', value: data.metadata.mediaProxy })
store.dispatch('setOption', { name: 'chatAvailable', value: data.metadata.chat })
store.dispatch('setOption', { name: 'gopherAvailable', value: data.metadata.gopher })
const suggestions = metadata.suggestions
store.dispatch('setOption', { name: 'suggestionsEnabled', value: suggestions.enabled })
store.dispatch('setOption', { name: 'suggestionsWeb', value: suggestions.web })
})