Todos os dias, o AWS Lambda executa trilhões de invocações de funções. O AWS Fargate agenda milhões de contêiner. Cada uma delas é uma máquina virtual completa, com seu próprio kernel, inicializada em uma fração de segundo.
Como? Cerca de 50.000 linhas de Rust chamadas Firecracker, que existe porque a indústria finalmente admitiu que um contêiner Linux que controla o uso de recursos nunca foi projetado para ser uma fronteira de segurança.
O problema do isolamento
Todo contêiner Docker no seu laptop são três recursos do kernel Linux em um sobretudo:
- Namespaces são vendas. Um processo dentro de um namespace tem uma visão privada do sistema: sua própria lista de PIDs, pilha de rede, tabela de montagem, hostname e IDs de usuário. O PID 1 dentro do contêiner é algum PID aleatório no host; o contêiner nem consegue ver os outros processos.
- cgroups são orçamentos. Control groups são a camada de contabilidade e limitação de taxa do kernel. Eles limitam quanto de CPU, memória, IO de disco e largura de banda de rede uma árvore de processos pode consumir.
- seccomp + capabilities são listas de permissão. capabilities dividem os poderes do root em ~40 privilégios separados (vincular portas baixas, carregar módulos do kernel, montar sistemas de arquivos, etc.) para que você possa conceder apenas os necessários. seccomp é um filtro por processo que decide quais syscalls (a única API do espaço do usuário para o kernel) o processo tem permissão para fazer.
Você pode provar isso sozinho sem o Docker instalado:
<code-segment id="0" lang="text">
$ unshare --fork --pid --mount-proc bash
Agora você está em um novo namespace de PID.
O bash acha que é o PID 1.
ps aux mostra apenas ele mesmo.
</code-segment>
Todo o resto que o Docker faz (camadas de imagem, registros, DNS) é orquestração em cima disso.
Toda essa proteção passa por um único kernel Linux, cerca de 30 milhões de linhas de código expondo 400+ syscalls. Cada contêiner no host chama esse mesmo kernel. Um bug em qualquer uma dessas syscalls e é game over para todos os inquilinos daquela máquina.
Máquinas virtuais completas resolvem o isolamento na força bruta: cada VM tem seu próprio kernel.
CPUs modernas têm um "modo convidado" que executa instruções convidadas no silício real. O host só é acionado quando o convidado faz algo privilegiado (toca em hardware real, causa uma falha, é interrompido). Um hypervisor é a camada fina que arbitra esses momentos.
O Linux vem com seu hypervisor como um módulo do kernel chamado KVM, exposto em /dev/kvm. Ele usa as extensões de virtualização do hardware (vmx na Intel, svm na AMD):
<code-segment id="1" lang="text">
Verifique se seu hardware suporta KVM
$ ls -l /dev/kvm
crw-rw---- 1 root kvm 10, 232 Mai 22 10:00 /dev/kvm
grep -E '(vmx|svm)' /proc/cpuinfo
</code-segment>
O problema com as VMs completas é que elas são lentas e pesadas. Uma VM QEMU clássica emula um PC imaginário inteiro (BIOS, barramento PCI, controlador IDE, placa VGA, teclado PS/2) porque era isso que um sistema operacional de 1998 esperava para inicializar. A imagem tem centenas de megabytes. A inicialização leva segundos. O consumo de memória é de centenas de MiB antes mesmo de sua carga de trabalho começar. Para uma requisição web que dura 40ms, você gastaria 40× isso inicializando a máquina.
Então você fica entre:
- Contêineres: 50ms de inicialização, 5 MiB de overhead, superfície de ataque do kernel compartilhado.
- VMs: 5+ segundos de inicialização, 300+ MiB de overhead, isolamento por hardware.
Todos que executam código multi-inquilino-inquilino não confiável (AWS e basicamente todos os fornecedores existentes de sandbox de IA) precisam dos dois lados dessa troca ao mesmo tempo.
Entram as microVMs
Um VMM (Virtual Machine Monitor) é o espaço do usuário) é o processo em espaço de usuário que dirige o hypervisor: ele configura a memória convidada, conecta dispositivos virtuais e diz ao KVM para começar a executar o código convidado.
Uma microVM é um VMM com o PC de 1998 deletado: sem BIOS, sem barramento PCI, sem VGA, sem USB, sem ACPI (nenhum do hardware legado pelo qual um desktop real inicializa, e nada disso relevante para uma chamada de função de 40ms). O que sobra: KVM, um console serial e um punhado de dispositivos virtio (net, block, vsock).
virtio é a interface de dispositivo padrão "Eu sei que estou rodando em uma VM". O convidado coopera com o hypervisor através de NICs e discos virtuais leves (virtio-net, virtio-block) em vez de fingir que está dirigindo uma placa Intel e1000 real ou um controlador IDE. Essa cooperação, mais toda a ausência de hardware legado acima, é o maior motivo pelo qual as microVMs inicializam rápido.
O resultado:
- ~125ms de inicialização desde o lançamento do VMM até o espaço do usuário convidado executando o init.
- <5 MiB.
- <5 MiB de overhead de memória do VMM por VM (a memória de manutenção que o host paga por VM, antes da carga de trabalho convidada alocar qualquer coisa para si).
- 150 VMs/segundo de taxa de criação em um único host.
- ~2–8% de perda de desempenho em tempo de execução em comparação com bare metal.
Mesmo isolamento em nível de hardware que uma VM completa com a mesma ordem de grandeza de densidade de um contêiner.

Firecracker é o VMM, o processo que realmente fala com /dev/kvm e inicializa a microVM. O resto deste post é essa pilha de ponta a pilha.
Firecracker
Em novembro de 2018, a AWS abriu o código do Firecracker no re:Invent. Ele já estava rodando o Lambda em produção, a coisa que faz seu import pandas inicializar a frio rápido o suficiente para ser cobrado por milissegundo. Em 2020, a equipe publicou a arquitetura no NSDI '20.
A arquitetura
Bifurcado do crosvm do Google, reescrito em Rust, com mais da metade do código removido. Cada processo do Firecracker é uma microVM, com exatamente três tipos de thread (documentados em docs/design.md):
- API thread é a mesa de pedidos. Um servidor REST vinculado a um socket Unix (um socket local que vive como um arquivo no disco, não uma porta TCP). Aceita configuração antes da inicialização e ações limitadas depois.
- VMM thread é o chão de fábrica do hardware. Ele finge ser todos os dispositivos que o convidado pode ver. Quando o convidado toca no que pensa ser um registrador de NIC, a CPU pausa o convidado, o VMM lida com o toque ("convidado chutou a fila de TX, drene-a") e retoma. O mecanismo: o convidado lê/escreve endereços mágicos; a CPU captura esses para o host.[^mmio]
- vCPU threads são os corredores. Uma por CPU convidada, cada uma em um loop apertado: peça ao KVM para executar o convidado até que algo interessante aconteça (toque em dispositivo, interrupção, parada), lide com isso, repita.
Eles se comunicam através de canais do Rust (filas de mensagens sem bloqueio entre threads). O convidado vê exatamente quatro dispositivos.

Os quatro dispositivos
- virtio-net é a NIC da VM, sem emulação de 1998. O convidado escreve pacotes em uma virtqueue (um buffer circular em memória compartilhada); o VMM os drena através de um dispositivo TAP do lado do host (uma interface Ethernet virtual que o kernel expõe como um arquivo), impulsionado por io_uring ou epoll para que a thread do VMM não bloqueie.
- virtio-block é o disco da VM, apenas IO de arquivo no host. O convidado coloca solicitações de setor em uma virtqueue; o VMM emite pread/pwrite simples contra um arquivo do host. Sem IDE, sem AHCI, sem SCSI.
- virtio-vsock é o interfone da VM para o host. Endereçado por uma tupla (context-id, porta) em vez de um par IP/porta, para que o agente convidado possa se comunicar com o host (logs, pings de saúde, metadados de snapshot) sem IP convidado e nada no fio para ser falsificado.
- UART serial 8250 é o console de inicialização. Um pequeno chip serial legado emulado em um endereço fixo. Usado para logs de inicialização e dumps de falha antes do virtio entrar em ação. Barato, universal, nunca vai desaparecer.
Inicializando uma microVM, ponta a ponta
A API é todo o plano de controle: o canal de configuração, mantido deliberadamente separado do plano de dados (as threads vCPU que realmente executam o código convidado). Você inicia o binário apontado para um socket Unix:
<code-segment id="2" lang="text">
$ ./firecracker --api-sock /tmp/firecracker.sock
</code-segment>
Então você coloca a configuração nele:
<code-segment id="3" lang="text">
1. Defina o kernel e a linha de comando
$ curl --unix-socket /tmp/firecracker.sock -i \
-X PUT 'http://localhost/boot-source' \
-H 'Content-Type: application/json' \
-d '{
"kernel_image_path": "./vmlinux.bin",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
}'
2. Anexe o sistema de arquivos raiz
$ curl --unix-socket /tmp/firecracker.sock -i \
-X PUT 'http://localhost/drives/rootfs' \
-H 'Content-Type: application/json' \
-d '{
"drive_id": "rootfs",
"path_on_host": "./rootfs.ext4",
"isos/ubuntu.ext4",
"is_root_device": true,
"is_read_only": false
}'
3. Configure a interface de rede
$ curl --unix-socket /tmp/firecracker.sock -i \
-X PUT 'http://localhost/network-interfaces/eth0' \
-H 'Content-Type: application/json' \
-d '{
"iface_id": "eth0",
"guest_mac": "06:00:AC:10:00:01",
"host_dev_name": "tap0"
}'
4. Inicialize a máquina
$ curl --unix-socket /tmp/firecracker.sock -i \
-X PUT 'http://localhost/actions' \
-H 'Content-Type: application/json' \
-d '{"action_type": "InstanceStart"}'
</code-segment>
Quatro chamadas HTTP. Esse é o plano de controle inteiro.

A cebola de segurança
Uma única fronteira KVM já é forte. O Firecracker envolve mais duas camadas ao redor dela.
O jailer é um construtor de sandbox. Seu único trabalho é isolar o VMM antes mesmo de ele executar. Ele cria um chroot (um recurso do Linux que prende um processo a uma única subárvore de diretório como se esse diretório fosse a raiz do sistema de arquivos; o processo literalmente não pode nomear nada acima dele), entra em um novo namespace de PID para que não possa ver os outros processos do host, alterna para um uid/gid sem privilégios, aplica limites de CPU/memória do cgroup, e só então executa o binário do Firecracker dentro dessa jaula:
<code-segment id="4" lang="text">
$ j \
--id 42 \
--chroot-base-dir /srv/jailer \
--exec-file ./firecracker \
--uid 1000 \
--gid 1000
</code-segment>
Agora o processo VMM em si não tem sistema de arquivos exceto um chroot dedicado, nenhuma visão de outros processos no host e nenhuma capacidade de root. Se uma fuga do convidado para o host ocorrer através do virtio ou KVM, o atacante cai naquele chroot com limites de cgroup.
Seccomp é uma lista de permissões de syscall por thread. Qualquer coisa que não esteja na lista é morta (ou retorna EPERM) antes de chegar ao manipulador de syscall do kernel. O Firecracker oferece três níveis:
- Nível 0: desligado. Não use em produção.
- Nível 1: lista de permissões por número de syscall.
- Nível 2: também restringe valores de argumento (ex.: ioctl é permitido, mas apenas com KVM_RUN como comando). Padrão e recomendado.
Cada thread obtém a superfície mínima possível: a thread da API não precisa de ioctl(KVM_RUN); as threads vCPU não precisam de socket(). Uma visão simplificada de como uma regra se parece:
<code-segment id="5" lang="text">
Permitir que as threads vCPU chamem ioctl, mas apenas com KVM_RUN
[allow]
syscall = "ioctl"
args = [
{ index = 1, value = 0xAE01, comparator = "eq" } # KVM_RUN
]
</code-segment>
Cada camada precisa falhar independentemente para um atacante alcançar o host.
Snapshots: o código secreto por trás do Lambda SnapStart
Tire um Snapshot de uma microVM em execução. Restaure-o em milissegundos, em um host diferente, em um novo processo VMM. Pule a inicialização do kernel, pule a inicialização do init, pule o aquecimento do JIT.
Você congela a VM em execução e despeja o estado da memória + dispositivos no disco:
<code-segment id="6" lang="text">
Crie um snapshot
$ curl --unix-socket /tmp/firecracker.sock -i \
-X PATCH 'http://localhost/vm' \
-H 'Content-Type: application/json' \
-d '{
"state": "Paused"
}'
$ curl --unix-socket /tmp/firecracker.sock -X PUT 'http://localhost/snapshot/create' \
-H 'Content-Type: application/json'Content-Type: application/json' \
-d '{
"snapshot_type": "Full",
"snapshot_path": "./snapshot_file",
"mem_file_path": "./mem_file",
"version": "1.0.0"
}'
</code-segment>
Um snapshot captura o estado pós-aquecimento, então a VM restaurada acorda no meio de sua vida, não no início dela.
É exatamente isso que o AWS Lambda SnapStart faz: inicializar um Java Lambda uma vez, tirar um snapshot da microVM e restaurar esse snapshot em cada inicialização a frio subsequente (anúncio). As inicializações a frio da JVM passam de 8+ segundos para menos de um segundo.

Como eles se encaixam
gVisor é um design diferente: um kernel em espaço de usuário em Go, uma reimplementação da interface de syscall do Linux que roda como um processo normal. As syscalls do convidado atingem o gVisor em vez do kernel host, e o gVisor decide o que (se algo) encaminhar adiante. Mais rápido de iniciar do que uma microVM, 10–30% de overhead de syscall no caminho quente e uma fronteira de confiança diferente.
O Firecracker está na caixa "meu próprio kernel, mas sem PCI BIOS": isolamento de hardware, modelo de dispositivo minúsculo e inicialização em milissegundos.
Escolha sua ferramenta:
<code-segment id="7" lang="text">
┌─────────────────────────────────────┬───────────────┬───────────────┬──────────────────────┐
│ │ Inicialização │ Overhead de Memória │
├─────────────────────────────────────┼─────────────── ┼──────────────────────┤
│ Contêiner (Docker) │ ~50ms │ ~5 MiB │
│ MicroVM (Firecracker) │ ~125ms │ <5 MiB │
│ VM completa (QEMU/KVM) │ 5+ segundos │ 300+ MiB │
└─────────────────────────────────────┴─────────────────────┴──────────────────────┘
</code-segment>
Quem usa isso
É quase mais rápido listar as plataformas serverless que não ficam em cima de microVMs.
Firecracker em produção:
- AWS Lambda e AWS Fargate: o caso de uso original. Cada invocação do Lambda cai em uma microVM do Firecracker; as tarefas do Fargate são VMs do Firecracker com um runtime de contêiner fino dentro.
- [Fly.io Machines](https://fly.io/docs/machines/): cada execução do fly machine é uma microVM do Firecracker, globalmente distribuída, com inicializações a frio em menos de um segundo e discos persistentes.
- **Quase todo sandbox de execução de execução de código de agente de IA que você usou nos últimos dezoito meses vive em uma microVM do Firecracker.
A forma de uma API de sandbox é mais ou menos a mesma em todos os fornecedores neste ponto:
<code-segment id="8" lang="text">
from browserbase import Sandbox
Inicialize uma microVM
sandbox = Sandbox()
Execute código não confiável dentro dela
result = sandbox.execute("pip install requests && python -c 'print(\"hello\")'")
print(result.text)
"hello from inside a microVM!"
</code-segment>
Em cerca de quatro linhas de código: uma microVM do Firecracker inicializa, um kernel inicializa, um processo agente dentro do convidado recebe seu comando pelo vsock, executa-o, transmite os resultados de volta e a VM morre.
A era dos agentes: por que tudo isso importa agora
Um ano atrás, "o que é um sandbox de IA?" era uma pergunta nicho. Se um LLM gerasse código, provavelmente não era 100% seguro para executar em qualquer máquina, então você o executava em um sandbox efêmeral.
Hoje, todo produto de IA sério envia um agente. Os sandboxes deles também melhoraram, mas a forma dos agentes mudou, e as respostas antigas de runtime não se encaixam na nova forma.
Agentes in-process vs agentes em nível de host
A primeira rodada de agentes de IA vivia dentro da sua aplicação. Você importava uma biblioteca, montava um loop e o executava em seu backend existente:
<code-segment id="9" lang="text">
Rodada 1: agente em processo
from openai import OpenAI
from vercel_ai_sdk import stream_text
def agent(user_input):
response = openai.chat.completions.create(
model="gpt-4",
tools=[search_tool, calculator_tool],
messages=[{"role": "user", "content": user_input}]
)
return response.choices[0].message.content
</code-segment>
Cada chamada era uma viagem de ida e volta HTTP para um modelo. Cada chamada de ferramenta era uma função no seu próprio processo. O "sandbox" era seu próprio servidor. Este é o mundo do Vercel AI SDK, LangChain, OpenAI Agents SDK. Funciona muito bem e ainda hoje uma grande parte dos agentes de produção.
A rodada dois é diferente. Claude Code, Codex e OpenCode são agentes em nível de host: binários que assumem o controle de uma máquina, não bibliotecas que vivem dentro da sua. Eles esperam um shell real, um gerenciador de pacotes e um disco gravável. Quando você dá uma tarefa ao Claude Code, ele executa algo assim:
<code-segment id="10" lang="text">
Rodada 2: agente em nível de host
$ claude "refatore este arquivo Python para usar async/await"
Internamente, o Claude Code executa:
$ ls -la src/
$ cat src/processor.py
$ grep -r "def process" src/
$ sed -i 's/def process/async def process/g' src/processor.py
$ python -m pytest src/test_processor.py
</code-segment>
Isso é um shell/bash. Ele precisa de um sistema de arquivos real, um fork/exec real, um gerenciador de pacotes, disco gravável, uma rede acessível. Nada disso é expressável como um esquema de ferramenta de chat-completion, e nada disso é seguro para executar em um contêiner de kernel compartilhado ao lado de outros inquilinos.
Os laboratórios estão treinando seus modelos diretamente nesses harnesses (o andaime ao redor do modelo): o shell, o editor de arquivos, o executor de testes, o próprio loop do agente. Isso significa que a lacuna entre "modelo + harness com o qual foi treinado" e "modelo + scaffolding DIY" está aumentando a cada trimestre.
Uma máquina Linux inteira por agente, executando código não confiável que o agente acabou é exatamente a carga de trabalho para a qual o Firecracker foi construído. A convergência acima não foi um acidente.
Estamos começando a ver mais experimentação com agentes em torno da separação entre computação e harness. O Managed Agents da Anthropic é um exemplo disso, onde o harness do agente está sendo executado ao lado do sandbox, não dentro dele.
Algumas empresas estão até construindo sistemas de arquivos hospedados completos (como Archil e Mesa), para dar aos agentes melhor pesquisa e armazenamento.
À medida que os agentes melhoram e mudam ao longo do tempo, haverá muitas mais ofertas de infraestrutura interessantes, construídas sobre o Firecracker.
O que você está realmente pagando para as plataformas de infraestrutura de agentes
Os sandboxes genéricos de "executar código arbitrário" são uma commodity agora. A infraestrutura é totalmente de código aberto. A camada de microVM é o Firecracker ou o Cloud Hypervisor, disponível sob Apache 2.0. A conversão de contêiner para rootfs é um script Go de 200 linhas. Engenheiros talentosos podem montar uma plataforma de sandbox funcional em um fim de semana.
Você paga pelo que está conectado à VM. A microVM nua é o mínimo para entrar no jogo.
A superfície de produto interessante:
- **Observabilidade é o produto, não uma ajuda de depuração. Tudo o que o agente faz (stdout, syscalls, escritas em arquivos, requisições de rede) passa por um único socket para um coletor do lado do host. Os construtores de agentes precisam de reprodução de sessão completa e dos artefatos por ação para criar os melhores produtos.
- **Segredos são intermediados no fio, nunca entregues ao convidado. O convidado vê apenas variáveis de ambiente; echo $SECRET dentro do sandbox retorna o placeholder. Um proxy de saída do lado do host (todo pacote de saída precisa cruzá-lo) substitui a credencial real no TAP do lado do host (a extremidade do kernel da NIC virtual da VM, que o convidado não pode ver ou endereçar), contra uma lista de permissões explícita, com uma trilha de auditoria por sessão. O agente pode estar executando código arbitrário que gerou cinco segundos atrás e ainda não consegue exfiltrar uma credencial que nunca teve.
- **Identidade é assinada no host, não dentro do agente. Requisições de saída podem carregar uma identidade criptográfica por sessão (incluindo assinaturas Web Bot Auth, construídas sobre HTTP Message Signatures + Ed25519) cunhada pelo host antes de o pacote sair da ponte. A chave de assinatura nunca entra na microVM.
- **A outra computação é agrupada na mesma microVM que o runtime. O Browserbase emparelha cada runtime de agente 1:1 com um navegador no mesmo host, muitas vezes na mesma microVM. A distância física entre o processo do agente e o Chromium é efetivamente zero: os comandos CDP (o Chrome DevTools Protocol, o formato de fio JSON sobre WebSocket usado para dirigir o Chrome programaticamente) vão por um socket Unix, não através de uma rede de serviços, então a latência da ação é de dígitos únicos. Os frames de screencast não precisam atravessar a internet pública para cair na reprodução de sessão.
E você não pode simplesmente costurar tudo isso de forma limpa em cima do Docker. As costuras não estão lá. Nossa aposta é que o mercado de runtime de agentes não será vencido com computação bruta, mas com a melhor observabilidade, segredos, identidade, parcerias e a computação colocalizada em uma única superfície de produto.

Alternativas de runtime que valem a pena observar
- [Bubblewrap](https://github.com/containers/bubblewrap): sandboxing de namespace de usuário sem privilégios. Um usuário não-root pode criar um sandbox sem sudo, usando os mesmos primitivos do kernel que o Flatpak usa para confinar aplicativos de desktop. Mais leve que uma VM, ainda compartilha o kernel do host, então não é um substituto para microVMs contra código verdadeiramente não confiável. Mas é uma ótima camada de isolamento aninhado para executar dentro de uma microVM, ou uma boa escolha para código confiável em seu próprio host.
- [V8 isolates](https://blog.cloudflare.com/cloud-computing-without-containers/): O modelo do Cloudflare Workers. Cada isolate é um contexto de execução JS separado com seu próprio heap, todos compartilhando um único processo V8 com potencialmente milhares de outros inquilinos. A inicialização é ~5ms, duas ordens de magnitude mais rápida que uma microVM. A fronteira de confiança é o próprio sandbox do V8; historicamente, ele se manteve bem, mas é uma linha muito mais fina que a de um hypervisor. O outro problema: você só obtém semânticas ao estilo Node. Sem fork, sem exec, sem módulos nativos, sistemas de arquivos simulados. Devastador para código de agente JS puro; inúizável se você precisa de pip install numpy.
- **[gVis, , sem
- **[gVis, que você também.
que
A. ou 。A. ou !A. ou !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. 能 !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. 中 ! 在 A. !A. !A. !A. !A. !A. !A. !A. !Aer the !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A. !A package/2、





