Giter Site home page Giter Site logo

instantid's Introduction

InstantID: Zero-shot Identity-Preserving Generation in Seconds

Qixun Wang12 · Xu Bai12 · Haofan Wang12* · Zekui Qin12 · Anthony Chen123

Huaxia Li2 · Xu Tang2 · Yao Hu2

1InstantX Team · 2Xiaohongshu Inc · 3Peking University

*corresponding authors

GitHub

ModelScope Open in OpenXLab

InstantID is a new state-of-the-art tuning-free method to achieve ID-Preserving generation with only single image, supporting various downstream tasks.

Release

Demos

Stylized Synthesis

Comparison with Previous Works

Comparison with existing tuning-free state-of-the-art techniques. InstantID achieves better fidelity and retain good text editability (faces and styles blend better).

Comparison with pre-trained character LoRAs. We don't need multiple images and still can achieve competitive results as LoRAs without any training.

Comparison with InsightFace Swapper (also known as ROOP or Refactor). However, in non-realistic style, our work is more flexible on the integration of face and background.

Download

You can directly download the model from Huggingface. You also can download the model in python script:

from huggingface_hub import hf_hub_download
hf_hub_download(repo_id="InstantX/InstantID", filename="ControlNetModel/config.json", local_dir="./checkpoints")
hf_hub_download(repo_id="InstantX/InstantID", filename="ControlNetModel/diffusion_pytorch_model.safetensors", local_dir="./checkpoints")
hf_hub_download(repo_id="InstantX/InstantID", filename="ip-adapter.bin", local_dir="./checkpoints")

Or run the following command to download all models:

pip install -r gradio_demo/requirements.txt
python gradio_demo/download_models.py

If you cannot access to Huggingface, you can use hf-mirror to download models.

export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download --resume-download InstantX/InstantID --local-dir checkpoints --local-dir-use-symlinks False

For face encoder, you need to manually download via this URL to models/antelopev2 as the default link is invalid. Once you have prepared all models, the folder tree should be like:

  .
  ├── models
  ├── checkpoints
  ├── ip_adapter
  ├── pipeline_stable_diffusion_xl_instantid.py
  └── README.md

Usage

If you want to reproduce results in the paper, please refer to the code in infer_full.py. If you want to compare the results with other methods, even without using depth-controlnet, it is recommended that you use this code.

If you are pursuing better results, it is recommended to follow InstantID-Rome.

The following code👇 comes from infer.py. If you want to quickly experience InstantID, please refer to the code in infer.py.

# !pip install opencv-python transformers accelerate insightface
import diffusers
from diffusers.utils import load_image
from diffusers.models import ControlNetModel

import cv2
import torch
import numpy as np
from PIL import Image

from insightface.app import FaceAnalysis
from pipeline_stable_diffusion_xl_instantid import StableDiffusionXLInstantIDPipeline, draw_kps

# prepare 'antelopev2' under ./models
app = FaceAnalysis(name='antelopev2', root='./', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))

# prepare models under ./checkpoints
face_adapter = f'./checkpoints/ip-adapter.bin'
controlnet_path = f'./checkpoints/ControlNetModel'

# load IdentityNet
controlnet = ControlNetModel.from_pretrained(controlnet_path, torch_dtype=torch.float16)

base_model = 'wangqixun/YamerMIX_v8'  # from https://civitai.com/models/84040?modelVersionId=196039
pipe = StableDiffusionXLInstantIDPipeline.from_pretrained(
    base_model,
    controlnet=controlnet,
    torch_dtype=torch.float16
)
pipe.cuda()

# load adapter
pipe.load_ip_adapter_instantid(face_adapter)

Then, you can customized your own face images

# load an image
face_image = load_image("./examples/yann-lecun_resize.jpg")

# prepare face emb
face_info = app.get(cv2.cvtColor(np.array(face_image), cv2.COLOR_RGB2BGR))
face_info = sorted(face_info, key=lambda x:(x['bbox'][2]-x['bbox'][0])*(x['bbox'][3]-x['bbox'][1]))[-1]  # only use the maximum face
face_emb = face_info['embedding']
face_kps = draw_kps(face_image, face_info['kps'])

# prompt
prompt = "film noir style, ink sketch|vector, male man, highly detailed, sharp focus, ultra sharpness, monochrome, high contrast, dramatic shadows, 1940s style, mysterious, cinematic"
negative_prompt = "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, vibrant, colorful"

# generate image
image = pipe(
    prompt,
    negative_prompt=negative_prompt,
    image_embeds=face_emb,
    image=face_kps,
    controlnet_conditioning_scale=0.8,
    ip_adapter_scale=0.8,
).images[0]

To save VRAM, you can enable CPU offloading

pipe.enable_model_cpu_offload()
pipe.enable_vae_tiling()

Speed Up with LCM-LoRA

Our work is compatible with LCM-LoRA. First, download the model.

from huggingface_hub import hf_hub_download
hf_hub_download(repo_id="latent-consistency/lcm-lora-sdxl", filename="pytorch_lora_weights.safetensors", local_dir="./checkpoints")

To use it, you just need to load it and infer with a small num_inference_steps. Note that it is recommendated to set guidance_scale between [0, 1].

from diffusers import LCMScheduler

lcm_lora_path = "./checkpoints/pytorch_lora_weights.safetensors"

pipe.load_lora_weights(lcm_lora_path)
pipe.fuse_lora()
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)

num_inference_steps = 10
guidance_scale = 0

Start a local gradio demo

Run the following command:

python gradio_demo/app.py

or MultiControlNet version:

gradio_demo/app-multicontrolnet.py 

Usage Tips

  • For higher similarity, increase the weight of controlnet_conditioning_scale (IdentityNet) and ip_adapter_scale (Adapter).
  • For over-saturation, decrease the ip_adapter_scale. If not work, decrease controlnet_conditioning_scale.
  • For higher text control ability, decrease ip_adapter_scale.
  • For specific styles, choose corresponding base model makes differences.
  • We have not supported multi-person yet, only use the largest face as reference facial landmarks.
  • We provide a style template for reference.

Community Resources

Replicate Demo

WebUI

ComfyUI

Windows

Acknowledgements

  • InstantID is developed by InstantX Team, all copyright reserved.
  • Our work is highly inspired by IP-Adapter and ControlNet. Thanks for their great works!
  • Thanks Yamer for developing YamerMIX, we use it as base model in our demo.
  • Thanks ZHO-ZHO-ZHO, huxiuhan, sdbds, zsxkib for their generous contributions.
  • Thanks to the HuggingFace gradio team for their free GPU support!
  • Thanks to the ModelScope team for their free GPU support!
  • Thanks to the OpenXLab team for their free GPU support!
  • Thanks to SiliconFlow for their OneDiff integration of InstantID!

Disclaimer

The code of InstantID is released under Apache License for both academic and commercial usage. However, both manual-downloading and auto-downloading face models from insightface are for non-commercial research purposes only according to their license. Our released checkpoints are also for research purposes only. Users are granted the freedom to create images using this tool, but they are obligated to comply with local laws and utilize it responsibly. The developers will not assume any responsibility for potential misuse by users.

Star History

Star History Chart

Sponsor Us

If you find this project useful, you can buy us a coffee via Github Sponsor! We support Paypal and WeChat Pay.

Cite

If you find InstantID useful for your research and applications, please cite us using this BibTeX:

@article{wang2024instantid,
  title={InstantID: Zero-shot Identity-Preserving Generation in Seconds},
  author={Wang, Qixun and Bai, Xu and Wang, Haofan and Qin, Zekui and Chen, Anthony},
  journal={arXiv preprint arXiv:2401.07519},
  year={2024}
}

For any question, please feel free to contact us via [email protected] or [email protected].

instantid's People

Contributors

czxck001 avatar eltociear avatar felixsanz avatar johndpope avatar researcherxman avatar sdbds avatar zsxkib avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

instantid's Issues

Is this the same as IP-Adapter faceID?

Is this the same as the recently released ( IP-Adapter faceID ) with some extra features like identity interpolation or are there any substantial benefits of instantID that IP-Adapter faceID doesn't provide?

I was astonished by the quality of the results of this project on the InstantID project page and I'm greatly looking forward to the release of the training / finetuning and inference code as well as the weights of this project. Do you have any rough estimates when the release will happen? Is it days / weeks / months away?

I can't wait for the release of this exciting technological breakthrough but if it takes more than a few weeks I'd probably just start implementing and finetuning the recently released IP-Adapter faceID for my upcoming projects.

Unable to upload pictures on iPhone mobile device

Clicking the image upload button opens the folder by default instead of the album library. Unable to recognize image formats in the folder directory, and also unable to click to upload them. I hope you will take note of this issue

Discuss anything here

Thanks for all interests in our project. To make it more clearer, we illustrate differences with previous works as following.

(1) Compared to Dreambooth, Textual Inverison, LoRA, etc., we are tuning-free during the inference phase, which means we do not need to collect multiple images from a specific person and fine-tune them. We consider the recent work PhotoMaker to be a type of LoRA as it trains UNet but in a PEFT manner and requires building a human-centered text image dataset. Surprisingly, our results were comparable or even better than the fine-tuned approach.

(2) Our work is most similar to IP-Adapter. We follow its decoupled cross-attention design and are as pluggable and compatible with other models in the community. But we additionally introduce IdentityNet (a variant of ControlNet) to obtain better ID retention capabilities.

We are open to discuss anything here, you can post your finding and share with us. We also make a WeChat group to facilitate discussion.

61dc1a8365749a8b35d6b9a6a3e819c6

support multiple reference images

Hi!

I want to use multiple reference image to generate image

but as I saw code, github and huggingface code not support multiple reference image

how can i use multiple reference image and how it work? ( average of face embeding? )

Quick Inquiry About Model Usage

Hope you're all doing great! 😊 First off, huge thanks for making such an awesome product available under the Apache License.

Just a quick question - about the antelopev2 model mentioned in your README. Is it cool to use this model for commercial projects if we download it from your link?

And hey, if it's not meant for commercial use, any chance you could point me towards a similar model that is? That'd be super helpful.

Thanks.

the result on my local machine is different from the result on the huggingface

Thank you very much for your wonderful work!

I have a problem. I ran the code on my machine, I used the same image input and prompt, and the same seed, but I got a result different so much with the result on the hugging face
The left image is the result using your hugging face https://huggingface.co/spaces/InstantX/InstantID
The right image is the result I got on the local machine
image

Could you guess, where I got wrong?

Thank you very much!

Support offloading with accelerate

When run with pipe.enable_model_cpu_offload(), it shows an error:

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cpu and cuda:0! (when checking argument for argument mat1 in method wrapper_CUDA_addmm)

CPU offloading drastically speeds up generation with low VRAM.

Can it be implemented?

About Identity Similarity...

In technical report, Fig. 6, "Jackie Chan" does not looks like reference image especially his nose. I supposed antelopev2 model should able to extract Jackie Chan very well as his images should be in Glint360k training data. Is this the limitation of face id encoder?

Also, the picture quality seems over saturated. Is it because of SDXL base model or your prompt?

antelopev2 not found in insightface releases

Hi @ResearcherXman!

Thank you and your team for such an interesting approach!

I was trying to use your inference code and found out that FaceAnalysis model initialization for the antelopev2 fails:

RuntimeError: Failed downloading url https://github.com/deepinsight/insightface/releases/download/v0.7/antelopev2.zip

Am I right, that the problem is on insightface side?
May I kindly ask you to share the weights of this model, while insightface team is trying to deal with download problem?

I created a corresponding issue in their repo deepinsight/insightface#2517

Inquiry Regarding InstantID's Integration with Pre-existing Architectures for Enhanced Flexibility

Dear InstantID Contributors,

I trust this message finds you well. I am reaching out to extend my commendations on the remarkable strides your team has made with the InstantID project. The innovative approach towards zero-shot identity-preserving generation is nothing short of impressive.

Having perused your technical report and examined the project's capabilities, I am keen to understand the potential for integrating InstantID with pre-existing neural network architectures. Specifically, I am curious about the following aspects:

  1. Compatibility and Adaptability: Could you elucidate on how InstantID might interface with architectures beyond the mentioned SD1.5 and SDXL models? Are there any plans to support additional frameworks, and if so, which ones?

  2. Module Flexibility: Given that InstantID operates as a plug-and-play module, what are the limitations when it comes to incorporating it with custom-designed neural networks? Are there specific architectural features or layers that are requisite for seamless integration?

  3. Performance Trade-offs: When embedding InstantID into other architectures, have you observed any significant trade-offs in terms of generation quality or identity preservation fidelity?

I believe that a deeper understanding of these integration dynamics could significantly enhance the utility of InstantID for researchers and developers who may wish to leverage its capabilities within a broader spectrum of applications.

I eagerly anticipate your response and any insights you may be willing to share. Should you require further clarification on my queries, please do not hesitate to contact me.

Thank you for your time and the invaluable contributions your work represents to the field of AI-driven image generation.

Best regards,
yihong1120

Issues with "Nonetype" pipe

I am able to get things running smoothly until I create the pipe from pipeline_stable_diffusion_xl_instantid.py. I believe this errors out somewhere when the following is called:

pipe = StableDiffusionXLInstantIDPipeline.from_pretrained(
base_model,
controlnet=controlnet,
torch_dtype=torch.float16
).cuda()

but the error is not caught and the pipe ends up as None. I am thinking it is a versioning error with my cuda/xformers. Could someone please provide the necessary versions for the following:

xformers
cuda
torch

Thanks in advance

MPS Support

Thank you for open sourcing the code.

I was trying to get this to work on Mac MPS machines, and got it to work but not sure if I am doing it correctly since I didn't dig deep into the code. I'll just share the parts I updated from the original gradio demo on huggingface:

  1. check the device for mps: https://huggingface.co/spaces/cocktailpeanut/InstantID/blob/main/app.py#L27-L34
  2. used torch_dtype of float32 for MPS (otherwise it keeps giving me black images) and use enable attention slicing: https://huggingface.co/spaces/cocktailpeanut/InstantID/blob/main/app.py#L53-L76

It works, but it uses a lot of memory, so I was wondering if there's a better way. Also even though it's working, I might be completely missing some parts or making a mistake. Would appreciate feedback. It's very fast on CUDA but on MPS takes much longer, so hopefully there's a way to improve the speed as well. Thank you!

how to use InstantID for face swapping tasks?

in the paper, it showed a comparison between Instant ID with InsightFace Swapper (Inswapper). the results are shockingly amazing when it comes to eastern asians
Are you guys planning on releasing the code for that specific task? and for this specific task, did you guys increase the number of reference images to see if a better quality was achieved?

What features do you most want us to add ?

We are a small team and cannot handle all feature requests at once. Thus, please tell us what is your favorite feature you wanna us add. Comment under this post. Meanwhile, we encourage all kinds of PRs (fixing bugs, adding new features, etc.) from the community, if you want to take on a feature, please open a new issue naming "Support for xxx" and we will assign you. Thanks for your interests, love you all ❤️.

Error attempting to use with IP Adapter

I tried to join IPA as an image control, but the following issue occurred and I am not sure if my usage is correct.

code:
ipa_model_path = f'/ipa_models'
device = "cuda"
face_adapter = f'InstantIDmodel/ip-adapter.bin'
controlnet_path = f'InstantIDmodel/ControlNetModel'
controlnet = ControlNetModel.from_pretrained(controlnet_path, torch_dtype=torch.float16)
pipe = StableDiffusionXLInstantIDPipeline.from_pretrained(
"modelscope/YamerMIX_v8", controlnet=controlnet, torch_dtype=torch.float16
)
pipe.load_ip_adapter_instantid(face_adapter)
pipe.load_ip_adapter(ipa_model_path, subfolder="models", weight_name="ip-adapter-plus_sdxl_vit-h.bin")
pipe.cuda()
pipe.set_ip_adapter_scale(0.8)
ip_image = Image.open("ref.png")
ip_image.resize((512, 512))
images = pipe(
prompt="a woman",
negative_prompt=None,ip_adapter_image=ip_image,
image_embeds=face_emb,
image=face_kps,width=width, height=height,
controlnet_conditioning_scale=0.8,
num_inference_steps=num_inference_steps,
guidance_scale=5,
).images

Error:
ValueError: <class 'diffusers.models.unet_2d_condition.UNet2DConditionModel'> has the config param encoder_hid_dim_type set to 'ip_image_proj' which requires the keyword argument image_embeds to be passed in added_conditions

Can InstantID be faster?

Thank you for your great work!
I'm curious if we can make InstantID faster? It's 3x slower than the standard SDXL pipeline on my 4090 (2.73it/s vs 8it/s). What slows it down so much?

Can width and height be customized?

Can width and height be customized? Or can they only be associated with the width and height of the input face image? I found that when setting width and height to 1024*1024, the face of the input image which is 9:16 will be distorted.

Out of memory issue with CUDA

Tried to run the code snippet from the readme and ran into a CUDA memory issue with an A100 which seems off

from diffusers.models import ControlNetModel
from pipeline_stable_diffusion_xl_instantid import StableDiffusionXLInstantIDPipeline, draw_kps

face_adapter = f'./checkpoints/ip-adapter.bin'
controlnet_path = f'./checkpoints/ControlNetModel'

app = FaceAnalysis(name='antelopev2', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))

controlnet = ControlNetModel.from_pretrained(controlnet_path, torch_dtype=torch.float16)
base_model = 'wangqixun/YamerMIX_v8'  # from https://civitai.com/models/84040?modelVersionId=196039
pipe = StableDiffusionXLInstantIDPipeline.from_pretrained(
    base_model,controlnet=controlnet, torch_dtype=torch.float16
)
pipe.cuda()
pipe.load_ip_adapter_instantid(face_adapter)


faces = app.get(img_cv)
faces = sorted(faces, key=lambda x:(x['bbox'][2]-x['bbox'][0])*x['bbox'][3]-x['bbox'][1])[-1] # only use the maximum face
face_emb = faces.embedding
face_kps = draw_kps(img, faces.kps)

pipe.set_ip_adapter_scale(0.8)
negative_prompt = "(lowres, low quality, worst quality:1.2), (text:1.2), watermark, painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured (lowres, low quality, worst quality:1.2), (text:1.2), watermark, painting, drawing, illustration, glitch,deformed, mutated, cross-eyed, ugly, disfigured"

# generate image
with torch.no_grad():
    image = pipe(
        "film noir style", image_embeds=face_emb, image=face_kps, controlnet_conditioning_scale=0.8
    ).images[0]

ram vram usage

Incredible work. I wonder if it can be run on low-power computers like 8GB VRAM and 12 RAM.

Why your method is better than ip-adapter in text control capabilities?

Hello, thanks for your nice work, I get confused about sth. Could you please help explain it?
ip adpater doesn't train UNet either, add a cross-attention just as yours, the big difference is you use landmark guide net, and they use clip image to control the structure(IP-Adapter Plus V2), I don't get why your method is better than ip-adapter in text control capabilities. Do you plan to release some training details, e.g. training data?
Thanks for you nice work!!!

Prompts used to produce the examples shown in the paper

Thank you for your great work!
Could you please publish the prompts (and parameters) used to produce the examples shown in the paper?
It's important for reproducibility.
Specifically, those used in Figure 5 and Figure 1.
Thanks!

What is the Extension Name of the Regional Control?

Hi author, the Figure 12 in your paper mentioned multi-identity synthesis with regional control. Did you combine the InstantID with SD webUI and use its regional control plug-in? If so, what is the name of that regional control plug-in?
Thanks.

ImportError: cannot import name 'IPAttnProcessor2_0' from 'ip_adapter.attention_processor'

Hi,

Trying the demo, looks like a bug here?

ImportError                               Traceback (most recent call last)

[<ipython-input-12-eeef1f01030c>](https://localhost:8080/#) in <cell line: 11>()
      9 
     10 from insightface.app import FaceAnalysis
---> 11 from pipeline_stable_diffusion_xl_instantid import StableDiffusionXLInstantIDPipeline, draw_kps

[/content/InstantID/pipeline_stable_diffusion_xl_instantid.py](https://localhost:8080/#) in <module>
     47         AttnProcessor2_0 as AttnProcessor,
     48     )
---> 49     from ip_adapter.attention_processor import (
     50         IPAttnProcessor2_0 as IPAttnProcessor,
     51     )

ImportError: cannot import name 'IPAttnProcessor2_0' from 'ip_adapter.attention_processor' (/content/InstantID/ip_adapter/attention_processor.py

Question: other models to use

First of all - thanks for amazing tool!
Have a question: is there a way to use any other model (looking for some specific style)? If yes - how to do it and is it compatible with 1.5 or SDXL models?
Thanks in advance

InstantID for full body.

Hello, thanks for the project. I’m currently using aipadapter to generate the same character(same face + outfit) with different pose, and I’m wondering if instantID would be a better choice. From the examples, it seems like this is for portrait only. Am I right? Thanks!

failed to load the base model

StableDiffusionXLInstantIDPipeline failed to load the base model(wangqixun/YamerMIX_v8). The base model has been downloaded locally, but the pipe is NONE after loading. What are the possible reasons? Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.