Power management (Português)/Suspend and hibernate (Português) - ArchWiki

Jump to content
From ArchWiki
< Power management (Português)
Status de tradução: Esse artigo é uma tradução de Power management/Suspend and hibernate. Data da última tradução: 2023-11-08. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

Artigos relacionados

- Uswsusp
- systemd
- Gestão de energia
- Wakeup triggers
- swap

Existem múltiplos métodos de suspensão disponíveis, notavelmente:

Suspender para ocioso
  Chamado de S0ix pela Intel, Modern Standby (antes como "Connected Standby") pela Microsoft e S2Idle pelo kernel. Projetado para ser usado ao invés do estado de sono S3 em sistemas com este suporte, de forma que fornece economia de energia idêntica, mas que reduz drasticamente o tempo exigido para acordar o sistema.
  Dica: Enquanto o estado mencionado acima está sujeito a problemas com drenagem de bateria no Windows ou macOS, pelo fato que ambos os sistemas conseguem acordar dispositivos neste estado de sono para exercer atividade na rede, em contrapartida, o ecossistema de software no Linux atualmente não usa este recurso, e portanto deve permanecer inalterado.
Suspender para RAM (conhecido por suspensão padrão/normal, dormir)
  Este estado de sono é definido pelo ACPI como S3. O funcionamento se baseia em cortar a energia da maior parte da máquina, exceto a RAM, da qual é necessária para restaurar o estado original. Por conta da grande economia de energia, é aconselhável que notebooks/laptops entrem automaticamente neste modo quando o computador estiver descarregando as baterias e com a tampa fechada (ou quando o usuário está inativo por um certo tempo).
Suspender para o disco (conhecido por hibernação)
  O estado de sono S4, assim como foi definido pelo ACPI, salva o estado original da máquina dentro de um espaço swap e então desliga completamente a máquina. Quando a máquina volta a ligar, o estado é restaurado. Há zero consumo de energia até o momento que ocorra o retorno do sistema.
Suspensão híbrida (conhecido por sono híbrido)
  É um híbrido entre suspender e hibernar, às vezes chamado de suspender para ambos. O sono híbrido salva o estado original em um espaço swap, porém não há desligamento da máquina, a suspensão invocada pelo sistema é a padrão. Se a bateria não estiver esgotada, o sistema pode retornar instantaneamente; se caso houver a perda de energia, o sistema pode retornar os dados pelo disco, que no caso é mais lento do que retornar pela RAM, mas o estado original da máquina não é perdido.

Há também múltiplas interfaces de baixo nível (backends) que oferecem funcionalidade básica, e há algumas interfaces de alto nível que proporcionam ajustes finos para lidar com drivers de hardware ou módulos de kernel problemáticos (por exemplo a reinicialização da placa de vídeo).

## Interfaces de baixo nível

Apesar de ser possível usar estas interfaces diretamente, é aconselhável que se use interfaces de alto nível para suspender/hibernar. Usar de forma direta interfaces de baixo nível pode até ser significantemente mais rápido, ao contrário de usar interfaces de alto nível porque executar todos os hooks pré e pós suspensão demanda certo tempo, contudo os hooks são úteis em configurar apropriadamente o relógio do hardware, restaurar conexões wi-fi, etc.

### Kernel (swsusp)

O meio mais prático é informar diretamente o código de suspensão do software no kernel (swsusp), e com isso a máquina adentrar em um estado de suspensão; o método e estado exatos dependem do nível de suporte do hardware. Em kernels modernos, escrever apropriadamente strings para `/sys/power/state` é o mecanismo primário para acionar a devida suspensão.

Veja a documentação do kernel se quiser explorar os detalhes.

### Espaço de usuário (uswsusp)

As ferramentas de uswsusp ('Userspace Software Suspend', ou 'Suspensão de Software do Espaço de Usuário') fornecem wrappers ao redor do mecanismo de suspender-para-RAM do kernel, de tal forma que disponibiliza algumas manipulações aos adaptadores gráficos diretamente do espaço de usuário, e que agem antes de suspender e depois de retornado o estado da máquina. Veja o artigo principal em Uswsusp.

Nota: O projeto em questão não recebe atualizações desde 2011.

## Interfaces de alto nível

O objetivo destes pacotes é fornecer binários/scripts que podem ser chamados para efetuar suspensão/hibernação. Entretanto na realidade a conexão (hooking) por botões de power, ou em menus interativos, ou em eventos de tampa em notebooks/laptops é feita normalmente por outras ferramentas. Para automaticamente suspender/hibernar em determinados eventos de energia, como ao fechar a tampa do notebook/laptop ou depois de uma certa porcentagem para o esgotamento de bateria, pode ser mais vantajoso dar uma olhada em como executar Acpid.

### systemd

O systemd fornece comandos nativos para suspensão, hibernação e suspensão híbrida; se quiser detalhes veja Gestão de energia#Gestão de energia. O systemd é a interface padrão usada em Arch Linux.

Veja Gestão de energia#Hooks de sono para informações adicionais em como configurar hooks de suspensão/hibernação. E também veja os manuais systemctl(1), systemd-sleep(8) e systemd.special(7).

## Mudando método de suspensão

Em caso de sistemas que a suspensão S0ix não fornece a mesma economia de energia como o estado de sono S3 comum, ou quando a conservação de energia é preferida para um tempo de retorno rápido da suspensão, é possível alterar o método de suspensão padrão.

Tip: S0ix deveria supostamente fornecer economias de energia idênticas ou melhores do que o estado S3. Veja as postagens em inglês antigas do blog da Intel: Como alcançar os estados S0ix no Linux, Solução de problemas S0ix no Linux e Eficiência do modo ocioso no Linux: Um estudo de caso para verificar a possibilidade de fazer funcionar adequadamente. Usuários em sistemas sob uso de Intel podem usar S0ixSelftestTool.

Execute o seguinte comando para ver todos os métodos de suspensão que o hardware notifica ter suporte (o respectivo método é sinalizado dentro dos colchetes) [1]:

    $ cat /sys/power/mem_sleep

    [s2idle] shallow deep

Se o seu hardware não notificar o status de sono `deep`, verifique primeiro se a sua UEFI possui alguma configuração de estados de sono; geralmente em "Power" ou "Sleep state", ou nomes semelhantes; pelas opções nomeadas como "Windows 10", "Windows and Linux" ou "S3/Modern standby support" para S0ix, e "Legacy", "Linux", "Linux S3" ou "S3 enabled" para estados de sono S3. Se ainda assim não houver correspondências, você pode manter o uso de `s2idle`. Considere usar hibernação ou tente corrigir as tabelas DSDT (ou procure uma versão com patch online).

Note: A última solução acima pode causar problemas. Por conta que fabricantes pararam de corrigir bugs com o estado S3 do ACPI desde o momento que tais fabricantes regularizaram a escolha do sistema operacional Windows, e os mesmos são encorajados a usar "Modern standby" por padrão; se caso o sistema de fábrica foi propositalmente não informado, então provavelmente o hardware está de alguma forma com defeito.

Confirme que o hardware não exibe problemas com o estado de sono S3 ao testar alguns ciclos de sono com o método de sono alterado:

    # echo "deep" > /sys/power/mem_sleep

Se nenhum problema foi encontrado, então você pode fazer a mudança permanente com o parâmetro de kernel `mem_sleep_default=deep`.

Em contrapartida, firmwares danificados anunciam o suporte como sono `deep`, enquanto que apenas `s2idle` é suportado. Se este for o caso, um método alternativo ao usar `s2idle` está disponível através de `SuspendState` em sleep.conf.d(5):

    /etc/systemd/sleep.conf.d/freeze.conf

    [Sleep]
    SuspendState=freeze

## Hibernação

Para usar a hibernação você deve criar uma partição ou arquivo swap, informar e direcionar o caminho para o devido swap com o parâmetro de kernel `resume=`, configurável via bootloader, e por fim configurar o initramfs; desta forma o kernel poderá retornar o sistema pelo swap especificado durante o início do espaço de usuário. Estas três etapas estão detalhadas abaixo.

Nota:

- Veja Dm-crypt/Criptografia de Swap#Com suporte a suspender para o disco ao usar criptografia.
- linux-hardened não tem suporte para hibernar, veja em FS#63648.
- Hibernação em um espaço swap com zram não é suportado, mesmo que o zram seja configurado em um dispositivo de armazenamento não volátil (em disco). O logind irá proteger contra as tentativas de hibernação em um espaço de swap sob uso do zam.

### Sobre tamanho de partição/arquivo swap

Mesmo que sua partição swap seja menor que a RAM, você ainda terá uma boa chance de hibernar de forma bem sucedida. Veja "image_size" na documentação do kernel para mais informações sobre este pseudo-arquivo `image_size` em sysfs(5).

Por um lado, você pode diminuir o valor de `/sys/power/image_size`, e desta forma a imagem de suspensão pode ser a menor possível (para pequenas partições de swap), ou por outro, você pode aumentar o valor e possivelmente acelerar o processo de hibernação. Para sistemas com uma grande quantidade de RAM, pequenos valores podem drasticamente aumentar a velocidade de volta da hibernação. É possível manter as alterações persistentes ao configurar por um arquivo temporário no systemd, como demonstrado em systemd#systemd-tmpfiles - arquivos temporários:

    /etc/tmpfiles.d/hibernation_image_size.conf

    #    Path                   Mode UID  GID  Age Argument
    w    /sys/power/image_size  -    -    -    -   0

A imagem de suspensão não pode gerar múltiplas partições e/ou arquivos de swap, a mesma deve caber completamente em uma partição de swap ou em um único arquivo swap. [2]

### Configure o initramfs

- Quando um initramfs baseado em busybox é usado, cujo é o padrão, a definição do hook `resume` é um requisito, e o mesmo deve ser escrito em `/etc/mkinitcpio.conf`. Independente da partição swap ser chamada pelo label (rótulo de disco) ou pelo UUID, a partição usa o nó de dispositivo referenciado pelo udev, e portanto o hook `resume` deve ser colocado depois do hook `udev`. O exemplo a seguir foi feito a partir da configuração de hooks pré-definida:

      HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems resume fsck)

  Lembre-se de gerar novamente o initramfs para as mudanças terem efeito.

  Nota: Usuários de LVM devem adicionar o hook `resume` depois de `lvm2`.

- Quando um initramfs com o hook `systemd` é usado, o mecanismo de retorno já é proporcionado, em vista disso não é necessário adicionar outros hooks.

### Parâmetros de kernel exigidos

É obrigatório usar o parâmetro de kernel `resume=seu_dispositivo_swap`. Qualquer um dos métodos com nomeação persistente de dispositivo de bloco podem definir o `seu_dispositivo_swap`. Por exemplo:

- `resume=UUID=4209c845-f495-4c43-8a03-5363dd433153`
- `resume="PARTLABEL=Swap partition"`
- `resume=/dev/archGrupoVolume/archVolumeLogico` -- isso se o swap fizer parte de um volume lógico feito pelo LVM (configurar por UUID e Label devem funcionar da mesma forma).

Os parâmetros de kernel só irão ter efeito após reiniciar a máquina. Para hibernar de forma imediata obtenha o maior número e o menor número do volume de dispositivo pelo comando lsblk e ajuste (com echo) os valores de acordo com o mesmo formato `maior:menor` em `/sys/power/resume`. Se caso a configuração pretendida for para um arquivo swap, adicionalmente configure o resume offset em `/sys/power/resume_offset`. [3]

Por exemplo, se o dispositivo swap for `8:3`:

    # echo 8:3 > /sys/power/resume

Ou se caso a hibernação for direcionada para um arquivo swap, e se o mesmo estiver no volume `8:2` e possui o offset como `38912`, o ajuste seria:

    # echo 8:2 > /sys/power/resume
    # echo 38912 > /sys/power/resume_offset

#### Hibernação em um arquivo swap

Usar um arquivo swap requer configurar o parâmetro de kernel `resume=UUID=seu_dispositivo_swap_uuid` e adicionalmente o `resume_offset=arquivo_swap_offset`. Veja sobre na documentação do kernel.

O `seu_dispositivo_swap` é o volume do qual o arquivo swap reside e segue o mesmo formato que o parâmetro root.

Em sistemas de arquivos que não são Btrfs, o valor de `arquivo_swap_offset` pode ser obtido executando `filefrag -v arquivo_swap`. A saída é por um formato em tabela e o determinado valor exigido está na primeira linha da coluna `physical_offset`.

Por exemplo:

    # filefrag -v /swapfile

    Filesystem type is: ef53
    File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes)
     ext:     logical_offset:        physical_offset: length:   expected: flags:
       0:        0..       0:      38912..     38912:      1:
       1:        1..   22527:      38913..     61439:  22527:             unwritten
       2:    22528..   53247:     899072..    929791:  30720:      61440: unwritten
    ...

Na demonstração acima o valor de `arquivo_swap_offset` é visto na primeira linha da terceira coluna: `38912` — valor antecipado de dois pontos finais — e portanto o parâmetro de kernel seria `resume_offset=38912`.

Para sistemas de arquivos Btrfs, não tente usar a ferramenta filefrag, pois o offset "físico" obtido por filefrag não é o valor real do physical offset fornecido pelo disco. Ao invés disto existe um espaço de endereçamento virtual no disco, com o objetivo de dar suporte a múltiplos dispositivos [4]. Nesta situação use o comando btrfs-inspect-internal(8). Como por exemplo:

    # btrfs inspect-internal map-swapfile -r /swap/swapfile

    198122980

Como visto acima, o `arquivo_swap_offset` é `198122980`, então o parâmetro de kernel seria `resume_offset=198122980`.

Dica:

- O comando a seguir poderá ser útil para identificar o `seu_dispositivo_swap_uuid`: `findmnt -no UUID -T /swapfile`
- O comando a seguir poderá ser útil para identificar o `arquivo_swap_offset` em sistemas de arquivos diferentes de Btrfs: `filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'`
- O valor de `arquivo_swap_offset` também é adquirido ao executar `swap-offset arquivo_swap`. O binário swap-offset é incluso no conjunto de ferramentas de uswsusp. Se for usar este método, então os dois parâmetros (resume e offset) devem ser fornecidos dentro de `/etc/suspend.conf` por via das chaves `resume device` e `resume offset`. Não é obrigatório reiniciar o sistema por este método.

Nota:

- Em blocos de dispositivos stacked (em camadas), como no caso de um armazenamento criptografado (LUKS), em RAID ou em LVM, o parâmetro `resume` deve apontar para o dispositivo desbloqueado/mapeado que contém o sistema de arquivos com o arquivo swap.
- Se o arquivo swap estiver na `/home/`, o systemd-logind não conseguirá determinar o tamanho do arquivo, por consequência será impedida a hibernação e mostrada a seguinte mensagem: `Failed to hibernate system via logind: Not enough swap space for hibernation`, ou se preferir de forma traduzida: `Falha ao hibernar sistema via logind: Não há espaço swap suficiente para hibernação`. Veja systemd issue 15354 para conhecer duas formas de contornar a situação.

Dica: Você talvez queira diminuir o swappiness do seu arquivo swap se o propósito do mesmo for apenas para permitir hibernação, e não para expandir a RAM.

#### Hibernação em volume LVM de provisionamento fino

A hibernação dentro de um volume LVM de provisionamento fino é possível, mas é necessário ter certeza que o volume está totalmente alocado. Se caso não estiver, retornar o sistema por este volume falhará, veja em FS#50703.

Você pode alocar por completo o volume LVM ao simplesmente encher o mesmo com diversos zeros. Como por exemplo:

    # dd if=/dev/zero of=/dev/vg0/swap bs=1M status=progress

Para verificar se o volume está totalmente alocado use:

    # lvs

      LV                   VG  Attr       LSize   Pool Origin    Data%  Meta%  Move Log Cpy%Sync Convert
      swap                 vg0 Vwi-aot--- 10.00g  pool           100

Um volume com a plena distribuição de armazenamento irá mostrar que possui o uso de dados (Data%) em 100%.

Atenção: Não use TRIM em volumes de provisionamento fino que são designados para hibernação, isto é, não use `discard` em `/etc/fstab` e não atribua a opção `-d`/`--discard` em swapon. Caso contrário o espaço usado será desalocado.

## Tecnologia Intel Rapid Start (IRST)

A Tecnologia Intel Rapid Start é um método firmware de hibernação que permite hibernar a partir do sono e logo após um intervalo pré-definido ou de acordo com o estado de bateria. Este método pode ser mais rápido e mais confiável do que a hibernação regular, por conta de ser feito pelo firmware ao invés de ser feito a nível de sistema operacional. Geralmente é necessário habilitar pelo firmware e o mesmo precisa fornecer o suporte para configurar a duração após o evento de suspender/bateria acionar a hibernação. Entretanto em alguns dispositivos, apesar de terem o suporte IRST, o firmware por si só permite configurar pelos drivers Intel do Windows. Nestes casos o módulo de kernel intel-rst descrito abaixo deverá permitir configurar eventos pelo Linux.

Com a Tecnologia Intel Rapid Start (IRST) ativada, retornar da suspensão deep sleep demora cerca de "alguns segundos a mais do que retornar pelo estado S3, porém é muito mais rápido do que voltar através da hibernação".

Muitos sistemas com base na Intel possuem o suporte para IRST no firmware, todavia estes sistemas requerem uma partição especial ou um SSD (ao invés de um HDD). As implantações OEM do Windows podem já ter uma partição IRST pré-criada, da qual pode ser mantida durante o processo de instalação do Arch Linux (uma melhor opção ao contrário de limpar e reparticionar todo o SSD). A partição deve aparecer como não formatada e com tamanho igual a capacidade de RAM do sistema.

Atenção: A partição que pertence a Tecnologia Intel Rapid Start não é criptografada. "A Intel recomenda desabilitar a Tecnologia Intel Rapid Start se você está usando criptografia de disco baseada em software". [5]

Se você pretende limpar e reparticionar todo o armazenamento (ou se você já fez isso) e planeja usar a tecnologia, então a partição IRST precisa ser recriada; isto pode ser feito ao definir uma nova partição vazia com o mesmo tamanho da RAM e ao configurar o tipo de partição para GUID `D3BFE2DE-3DAF-11DF-BA40-E3A556D89593` em caso de uma partição GPT, ou para ID `0x84` em caso de uma partição MBR. Há também a possibilidade de ser preciso ativar o suporte para IRST nas configurações de firmware do sistema.

Dica: O tempo de duração antes do IRST ter efeito (e que é depois da suspensão) pode ser ajustado nas configurações de firmware do sistema.

A duração do processo de hibernação IRST (ou seja, para copiar "todo o conteúdo da RAM para uma partição especial") depende da capacidade total de RAM no sistema e a velocidade do SSD, então o processo pode durar entre 20 a 60 segundos. Alguns sistemas podem indicar o processo concluído com uma indicação por LED, por exemplo a luz pode parar de piscar para indicar a conclusão.

Configurar os eventos de hibernação IRST no kernel Linux requer a configuração já embutida (built-in) `CONFIG_INTEL_RST`, ou as definições por meio de módulo. Ao carregar via `modprobe intel_rst`, já é esperado que haja a criação por conta própria dos arquivos `wakeup_events` e `wakeup_time` dentro de `/sys/bus/acpi/drivers/intel_rapid_start/*/`; demais configurações podem ser igualmente ajustadas neste mesmo local. Outras informações sobre este módulo foram documentadas de maneira sucinta. Veja a fonte do código drivers/platform/x86/intel/rst.c para mais detalhes.

Veja também as perguntas frequentes e o guia de usuários para a Tecnologia Intel Rapid Start.

## Solução de problemas

### ACPI_OS_NAME

Você talvez precise aplicar ajustes finos na sua tabela DSDT para fazer funcionar adequadamente. Veja em DSDT.

### Suspensão/hibernação não funcionam, ou não de forma consistente

Existem vários relatos sobre a imensa dificuldade de diagnosticar/visualizar erros quando a tela fica totalmente escura ou de fazer qualquer coisa quando o sistema retorna da suspensão e/ou hibernação; estes problemas foram vistos tanto em notebooks/laptops quanto em desktops. Não é uma solução oficial, mas trocar para um kernel mais antigo, especialmente para o kernel LTS, provavelmente restaura o funcionamento.

O problema pode surgir quando há o uso do temporizador watchdog pelo hardware (desabilitado por padrão, veja `RuntimeWatchdogSec=` em systemd-system.conf(5) § OPTIONS). Um temporizador bugado pode reiniciar o computador antes do sistema terminar de criar a imagem de hibernação.

Às vezes a tela pode ficar escura devido a inicialização do dispositivo a partir do initramfs. Remover qualquer módulo que talvez esteja em Mkinitcpio#MODULES, remover o hook `kms` e reconstruir o initramfs possivelmente soluciona o problema, em especial com drivers gráficos que iniciam com o KMS. Inicializar tais dispositivos antes do sistema retornar pode causar inconsistências que previnem o sistema de voltar da hibernação; isto, no entanto, não afeta a volta pela RAM. Além do que foi mencionado aqui, dê uma olhada no artigo do blog a seguir: As melhores práticas para depurar problemas de suspensão.

Mover o driver de vídeo ATI para o novo driver AMDGPU pode também ajudar a solucionar transtornos com o processo do sistema ao hibernar ou ao acordar, e com isso o processo ser bem sucedido.

Para usuários de NVIDIA, adicionar à lista negra o módulo `nvidiafb` talvez ajude. [6]

Notebooks/laptops com uma CPU Intel e que carregam o módulo `intel_lpss_pci` para touchpad podem se deparar com pânicos de kernel ao retornar o sistema (tecla Caps Lock pisca incessantemente) [7]. O módulo precisa ser adicionado ao initramfs desta forma:

    /etc/mkinitcpio.conf

    MODULES=(... intel_lpss_pci ...)

E então gere novamente o initramfs.

### Wake-on-LAN

Se o Wake-on-LAN está ativo, a interface da placa de rede irá consumir energia mesmo se o computador estiver em hibernação.

### Sistema acorda instantaneamente da suspensão

Veja a página em inglês: Wakeup triggers#Instantaneous wakeups from suspend.

Se você estiver usando a versão 6.1, ou acima, do kernel Linux com uma CPU da AMD, há chance de ocorrer mal funcionamento por conta de problemas com o controle de protocolo relacionado ao estado de sono S3 no kernel. Uma solução temporária seria desligar o retorno (wakeup) de dispositivos que estejam envolvidos com o i2c. Você pode encontrá-los por:

    $ ls /sys/bus/i2c/devices/*/power/wakeup

O formato de nome dos dispositivos será algo como `i2c-ELAN0679:00` ou `i2c-MSFT0001:00`. Por fim, ajuste para desabilitar e teste se o comando abaixo resulta na suspensão do sistema apropriadamente:

    # echo disabled > /sys/bus/i2c/devices/nome_dispositivo/power/wakeup
    # systemctl suspend

Se funcionar, você pode fazer a configuração persistente ao adicioná-la a uma regra udev:

    /etc/udev/rules.d/99-avoid-i2c-wakeup.rules

    KERNEL=="nome_dispositivo", SUBSYSTEM=="i2c", ATTR{power/wakeup}="disabled"

### Sistema não desliga quando em hibernação

Ao hibernar o seu sistema, ele precisa desligar (logo depois de salvo o estado da máquina para o disco). Em certas ocasiões talvez você perceba o LED do botão power ainda acesso; se isto ocorrer, é instruído que você defina o `HibernateMode` para `shutdown` em sleep.conf.d(5):

    /etc/systemd/sleep.conf.d/hibernatemode.conf

    [Sleep]
    HibernateMode=shutdown

A configuração acima, e se demais configurações estiverem corretas, fará com que a invocação por `systemctl hibernate` desligue a máquina adequadamente, incluindo o salvamento do estado original para o disco antes de desligar.

### Sistema operacional não encontrado (ou iniciando errado) ao dar boot depois da hibernação

Isto pode ocorrer quando o disco de iniciação (de boot) é um disco externo; a situação é aparentemente causada por uma limitação própria da BIOS ou do próprio firmware. A BIOS ou o firmware tenta iniciar o sistema por um disco interno, contudo a hibernação foi feita por um sistema operacional em um disco externo (ou em outro dispositivo).

Defina `HibernateMode=shutdown` como mostrado em #Sistema não desliga quando em hibernação para resolver o problema permanentemente. Se você já deslogou do seu sistema, você pode tentar reiniciar o sistema 4 vezes (espere até a mensagem de erro aparecer em cada uma das vezes), em algumas BIOS isto força um processo de boot normal, ou seja, logo em seguida de várias tentativas falhas o sistema volta para o estado padrão de boot.

Category:

- Power management (Português)