Skip to content
Skills Library
Programming · Building & coding

rust-stdlib

/rust-stdlib

Select and compose Rust standard-library APIs — collections (HashMap/BTreeMap/Vec/VecDeque/LinkedList/BinaryHeap), smart pointers (Box/Rc/Arc/RefCell/Mutex/OnceLock/LazyLock), string types (String/&str/OsString/PathBuf/Cow), interior mutability (Cell/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chain

Repository
rust-skills ↗
Licence
Apache-2.0
Last repository change
24.09.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
15
Scripts
1
HTML comments
0
URLs in SKILL.md
9
Deprecation

No signals detected. Repository changed on 24.09.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What to check before installing
  • 1 scripts in this package. Review them before installing, as Claude may execute them.

Scripts: examples/golden-stdlib/src/lib.rs

What it does and when to use it

Select and compose Rust standard-library APIs — collections (HashMap/BTreeMap/Vec/VecDeque/LinkedList/BinaryHeap), smart pointers (Box/Rc/Arc/RefCell/Mutex/OnceLock/LazyLock), string types (String/&str/OsString/PathBuf/Cow), interior mutability (Cell/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chain

Triggers from the description

which std type should I use
Original author description

Select and compose Rust standard-library APIs — collections (HashMap/BTreeMap/Vec/VecDeque/LinkedList/BinaryHeap), smart pointers (Box/Rc/Arc/RefCell/Mutex/OnceLock/LazyLock), string types (String/&str/OsString/PathBuf/Cow), interior mutability (Cell/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chain

How it works

  1. Capability Boundaries
  2. Data Privacy
  3. Decision tree
  4. Quick reference
  5. Entry API — avoid double lookup
  6. Cell vs RefCell vs OnceCell
  7. Option combinators
  8. Result combinators
  9. Common patterns
  10. Trait hierarchy
Original SKILL.md headings · 485 lines, 2,219 words
SKILL.md preview
---
name: rust-stdlib
license: Apache-2.0
description: Select and compose Rust standard-library APIs — collections (HashMap/BTreeMap/Vec/VecDeque/LinkedList/BinaryHeap), smart pointers (Box/Rc/Arc/RefCell/Mutex/OnceLock/LazyLock), string types (String/&str/OsString/PathBuf/Cow), interior mutability (Cell/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chains, choose Cell vs RefCell vs Mutex, work with std threads/channels, or pick the right std module for a task; hand async runtime to rust-concurrency, language semantics to rust-stable, and application-layer concerns to domain skills.
---

# Rust Standard Library — API Selection and Composition

> Authority: [Rust Standard Library](https://doc.rust-lang.org/std/) — the canonical reference. Read `references/std-module-index.md` for the full module map.

This skill owns **choosing and composing std APIs**: which collection, which smart pointer, which string type, which I/O trait, which iterator pattern. It does not own language semantics (`rust-stable`), async runtime (`rust-concurrency`), or application-layer concerns (the domain skills).

## Capability Boundaries

### ✅ Strengths
1. Picking the right collection (HashMap vs BTreeMap vs Vec vs VecDeque vs LinkedList vs BinaryHeap)
2. Choosing the right smart pointer (Box vs Rc vs Arc vs RefCell vs Mutex vs OnceLock)
3. Selecting the right string type (String vs &str vs OsString vs PathBuf vs Cow)
4. Choosing interior mutability primitive (Cell vs RefCell vs OnceCell vs OnceLock vs LazyLock)
5. Designing Option/Result combinator chains (map, and_then, unwrap_or_else, ok_or, transpose)
6. Selecting I/O trait (Read vs Write vs BufRead vs Seek vs AsyncRead)
7. Choosing iterator pattern (iter vs into_iter vs owning iterator, lazy vs collect)
8. Using std concurrency primitives (thread, mpsc, barrier, Once, scoped threads)
9. Selecting time API (Duration vs Instant vs SystemTime vs TryFromFloat)
10. Cross-platform path handling (Path vs PathBuf, fs, env, process::Command)

### ⚠️ Prerequisites
1. Rust ownership and lifetimes — see `rust-stable`
2. Cargo and project structure — see `rust-cargo-build`, `rust-workspace`

### ❌ Out of Scope
1. Async runtime (Tokio, async-std) → `rust-concurrency`
2. Language semantics (ownership, traits, lifetimes) → `rust-stable`
3. Application-layer concerns (CLI, web, database) → domain skills
4. Unsafe and FFI → `rust-unsafe-ffi`

## Data Privacy

This skill does not collect, store, or transmit user data.

---

# Part 1: Collections

## Decision tree

```
Need a collection?
│
├─ Key-value lookup?
│   ├─ Order doesn't matter, fast lookup → HashMap<K, V>
│   ├─ Need sorted iteration / range queries → BTreeMap<K, V>
│   └─ Tiny (<20 entries), linear scan OK → Vec<(K, V)> with .iter().find()
│
├─ Sequence?
│   ├─ Append/pop from end → Vec<T>
│   ├─ Push/pop from both ends → VecDeque<T>
│   ├─ Insert/remove from middle frequently → LinkedList<T> (rare; usually Vec is better)
│   └─ Priority queue / always-min-first → BinaryHeap<T>
│
├─ Set?
│   ├─ Fast membership, no order → HashSet<T>
│   └─ Sorted iteration → BTreeSet<T>
│
└─ No collection needed — use Vec<T>
```

## Quick reference

| Type | Order | Lookup | Insert | When |
|------|-------|---------|--------|------|
| `Vec<T>` | insertion | O(n) by value, O(1) by index | O(1) amortized push | Default sequence |
| `VecDeque<T>` | insertion | O(1) front/back | O(1) front/back | Queue, sliding window |
| `LinkedList<T>` | insertion | O(n) | O(1) anywhere with cursor | Almost never; prefer Vec |
| `BinaryHeap<T>` | priority | O(1) peek | O(log n) push/pop | Priority queue |
| `HashMap<K,V>` | none | O(1) avg | O(1) avg | Fast lookup, no order |
| `BTreeMap<K,V>` | sorted | O(log n) | O(log n) | Ordered keys, range queries |
| `HashSet<T>` | none | O(1) avg | O(1) avg | Membership |
| `BTreeSet<T>` | sorted | O(log n) | O(log n) | Sorted membership |

See `references/collections.md` for allocation behavior, hasher selection (`BuildHasherDefault`/`FxHashMap`), and entry API patterns.

## Entry API — avoid double lookup

```rust
use std::collections::HashMap;

let mut counts: HashMap<&str, u32> = HashMap::new();
for word in text.split_whitespace() {
    *counts.entry(word).or_insert(0) += 1;   // single hash, no double lookup
}
```

---

# Part 2: Smart Pointers

## Decision tree

```
Need shared/indirected ownership?
│
├─ Single owner, heap-allocated → Box<T>
│
├─ Multiple readers, single thread → Rc<T>
│   └─ Need to mutate through shared ref → Rc<RefCell<T>>
│
├─ Multiple readers, multiple threads → Arc<T>
│   └─ Need to mutate through shared ref → Arc<Mutex<T>> or Arc<RwLock<T>>
│
├─ Need lazy one-time init → OnceLock<T> (sync) or once_cell::Lazy
│
└─ Need interior mutability (no shared ownership)?
    ├─ Copy type, simple → Cell<T>
    ├─ Non-Copy, complex → RefCell<T> (single thread)
    └─ Multi-thread → Mutex<T> or RwLock<T>
```

## Quick reference

| Type | Ownership | Thread-safe | Mutability | Use |
|------|-----------|-------------|------------|-----|
| `Box<T>` | Single | Yes | Direct (owned) | Heap allocation, recursive types |
| `Rc<T>` | Shared | **No** | Immutable only | Reference counting, single-threaded |
| `Arc<T>` | Shared | Yes | Immutable only | Atomic RC, multi-threaded |
| `Cell<T>` | Single | **No** | Interior (Copy only) | Simple mutable state |
| `RefCell<T>` | Single | **No** | Interior (borrow check at runtime) | Mutation behind shared ref |
| `Mutex<T>` | Single | Yes | Interior (lock) | Shared mutable state, sync |
| `RwLock<T>` | Single | Yes | Interior (read/write lock) | Many readers, few writers |
| `OnceLock<T>` | Single | Yes | One-time init | Lazy globals, `std::sync::OnceLock` |
| `LazyLock<T>` | Single | Yes | One-time init, transparent deref | Const-ish globals (Rust 1.80+) |

See `references/smart-pointers.md` for trade-offs, drop ordering, and `Weak<T>` for cycles.

---

# Part 3: String Types

## Decision tree

```
Working with text?
│
├─ Function parameter → &str (always)
├─ Owned, mutable, UTF-8 → String
├─ Borrowed, UTF-8, with mixed owned/borrowed → Cow<'a, str>
├─ OS path (Windows/Unix native) → OsString (owned) / OsStr (borrowed)
├─ Filesystem path → PathBuf (owned) / Path (borrowed)
└─ Bytes that might not be UTF-8 → Vec<u8> / &[u8]
```

## Quick reference

| Type | Encoding | Owned? | Use |
|------|----------|--------|-----|
| `&str` | UTF-8 | No | Function params, string literals |
| `String` | UTF-8 | Yes | Owned mutable UTF-8 text |
| `OsString`/`OsStr` | Platform-native | Yes/No | Environment, process args |
| `PathBuf`/`Path` | Platform-native | Yes/No | Filesystem paths |
| `Cow<'a, str>` | UTF-8 | Maybe | Zero-copy when possible, owned when needed |
| `Vec<u8>`/`&[u8]` | Bytes | Yes/No | Binary data, non-UTF-8 |

See `references/string-types.md` for conversion (`.to_string()` vs `.to_owned()` vs `.into()`), `Cow` usage, and `&str` slicing safety (`is_char_boundary`).

---

# Part 4: Interior Mutability

## Cell vs RefCell vs OnceCell

```rust
use std::cell::{Cell, RefCell, OnceCell};

// Cell: only for Copy types, no borrow checking
let counter = Cell::new(0);
counter.set(counter.get() + 1);

// RefCell: for non-Copy types, runtime borrow check (panics on double borrow)
let cache = RefCell::new(HashMap::new());
cache.borrow_mut().insert("k", 42);

// OnceCell: one-time initialization
static CONFIG: OnceCell<Config> = OnceCell::new();
let cfg = CONFIG.get_or_init(|| Config::load());
```

| Type | Sync? | Use |
|------|-------|-----|
| `Cell<T>` | No | Copy types only, simple mutation |
| `RefCell<T>` | No | Non-Copy types, single-thread |
| `OnceCell<T>` | No | One-time lazy init |
| `OnceLock<T>` | **Yes** | One-time lazy init, multi-thread (std 1.70+) |
| `LazyLock<T>` | **Yes** | Transparent lazy init (std 1.80+) |

See `references/interior-mutability.md` for panic-safety (RefCell double-borrow), choose-Cell-vs-RefCell, and `Atomic*` for multi-thread.

---

# Part 5: Option and Result Combinators

## Option combinators

```rust
// map: transform inner value
name.map(|n| n.to_uppercase())                    // Option<String>

// and_then: chain fallible operations
id.and_then(|i| db.lookup(i))                     // Option<User>

// unwrap_or / unwrap_or_else: provide default
port.unwrap_or(8080)
port.unwrap_or_else(|| env::var("PORT").unwrap_or("8080").parse().unwrap())

// ok_or / ok_or_else: convert Option to Result
user.ok_or(Error::NotFound)?
user.ok_or_else(|| Error::UserMissing(id))?

// filter, is_some, is_some_and
age.filter(|&a| a >= 18)
opt.is_some_and(|x| x > 0)

// transpose: swap Option<Result> → Result<Option>
let x: Result<Option<i32>, _> = Some("5").parse::<i32>().map(Some);
```

## Result combinators

```rust
// ? for propagation (prefer over explicit match)
fn load() -> Result<Config, Error> { Ok(parse(file_read()?)?) }

// map_err: convert error type
file_read().map_err(|e| Error::Io(e))?

// map: transform success value
parse(s).map(|n| n * 2)

// and_then: chain fallible
validate(input).and_then(process)

// or_else / or: fallback on error
primary.or_else(|_| fallback())
```

## Common patterns

| Pattern | Code |
|---------|------|
| Try parsing, fallback to default | `s.parse().unwrap_or(default)` |
| Early return on error | `let x = result?;` |
| Convert Option to Result | `opt.ok_or(Error::Missing)?` |
| Collect all Results | `results.collect::<Result<Vec<_>, _>>()` |
| Try all, return first success | `opts.into_iter().find_map(|o| o.try_it().ok())` |

See `references/option-result-combinators.md` for the full combinator table and refactor patterns.

---

# Part 6: I/O Streams

## Trait hierarchy

```
Read ────┐
         ├─ BufRead (adds buffering, lines())
Write ───┘
Seek (random access)
```

## Choosing

| Need | Use |
|------|-----|
| Read bytes from a source | `impl Read` (File, Cursor, stdin) |
| Buffered reading (lines, until) | `impl BufRead` (BufReader wrapping) |
| Write bytes to a destination | `impl Write` (File, stdout, Vec) |
| Random access | `impl Seek` (File) |
| Async I/O | `tokio::io::AsyncRead`/`AsyncWrite` (rust-concurrency) |

```rust
use std::io::{BufRead, BufReader, Read, Write};
use std::fs::File;

let f = File::open("log.txt")?;          // impl Read
let reader = BufReader::new(f);          // wrap for BufRead
for line in reader.lines() {             // BufRead::lines
    println!("{}", line?);
}
```

See `references/io-streams.md` for `Cursor<Vec<u8>>`, error handling (`io::Result`), and converting between sync and async.

---

# Part 7: Iterators

## Choosing

| Need | Use |
|------|-----|
| Borrow elements | `.iter()` → `Iterator<Item = &T>` |
| Mutably borrow | `.iter_mut()` → `Iterator<Item = &mut T>` |
| Consume | `.into_iter()` → `Iterator<Item = T>` |
| Index pairs | `.iter().enumerate()` |
| Filter | `.filter(\|x\| *x > 0)` |
| Transform | `.map(\|x\| x * 2)` |
| Flat | `.flat_map(\|x\| x.iter())` |
| Collect to Vec | `.collect::<Vec<_>>()` |
| Collect to HashMap | `.collect::<HashMap<_, _>>()` (from `(K, V)` tuples) |
| First match | `.find(\|x\| *x == 5)` |
| Any/all | `.any(\|x\| *x > 0)`, `.all(\|x\| *x > 0)` |
| Group/sum | `.sum::<i32>()`, `.product()`, `.fold(0, \|a, b\| a + b)` |

```rust
// Borrowed iteration is the default
let v = vec![1, 2, 3];
for x in &v { /* x: &i32 */ }      // .iter()
for x in &mut v { /* x: &mut i32 */ }
for x in v { /* x: i32, v consumed */ }
```

See `references/iterators.md` for custom iterators (impl `Iterator`), lazy evaluation, and zero-cost abstractions.

---

# Part 8: Std Concurrency

The standard library provides threads, channels, and sync primitives. For async, see `rust-concurrency`.

## Threads

```rust
use std::thread;
use std::time::Duration;

let handle = thread::spawn(|| {
    thread::sleep(Duration::from_millis(500));
    "result"
});
let r = handle.join().unwrap();   // wait, get result
```

## Scoped threads (Rust 1.63+) — borrow without `'static`

```rust
let mut data = vec![1, 2, 3];
thread::scope(|s| {
    s.spawn(|| { data[0] += 1; });
    s.spawn(|| { data[1] += 1; });
});   // all threads joined here; data borrow ends
```

## mpsc channels

```rust
use std::sync::mpsc;
use std::thread;

let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    tx.send(42).unwrap();
});
println!("{}", rx.recv().unwrap());
```

## Sync primitives

| Primitive | Use |
|-----------|-----|
| `Mutex<T>` | Exclusive lock, sync interior mutability |
| `RwLock<T>` | Many readers, few writers |
| `Arc<T>` | Atomic reference counting |
| `Barrier` | Synchronize multiple threads at a point |
| `Once` | One-time initialization |
| `Condvar` | Wait/notify |
| `Atomic*` (AtomicUsize, AtomicBool, ...) | Lock-free counters, flags |

See `references/std-concurrency.md` for `Arc<Mutex<T>>` patterns, poison recovery, and when to graduate to Tokio.

---

# Part 9: Time, Path, Process

## Time

```rust
use std::time::{Duration, Instant, SystemTime};

let start = Instant::now();
expensive_op();
println!("took {:?}", start.elapsed());   // Duration

let five_secs = Duration::from_secs(5);
let mixed = Duration::new(5, 500_000_000);  // 5.5s

let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
```

- `Duration` — span of time (no specific moment)
- `Instant` — monotonic moment, for measuring elapsed
- `SystemTime` — wall-clock, for timestamps (can go backwards!)

## Path

```rust
use std::path::{Path, PathBuf};

let p = Path::new("/usr/bin/foo");
let stem = p.file_stem();      // "foo"
let ext = p.extension();       // "foo" → None; "foo.txt" → "txt"

let joined = PathBuf::from("/usr").join("bin").join("foo");
let parent = p.parent();       // "/usr/bin"
```

Always use `Path`/`PathBuf` for filesystem paths — never `String`. Cross-platform safe.

## Process

```rust
use std::process::Command;

let output = Command::new("ls")
    .arg("-l")
    .arg("/")
    .output()?;          // waits, returns Output
println!("{}", String::from_utf8_lossy(&output.stdout));

// Stream stdin/stdout
use std::process::Stdio;
let mut child = Command::new("cat")
    .stdin(Stdio::piped())
    .stdout(Stdio::piped())
    .spawn()?;
```

See `references/process-and-fs.md` for `Command` exit codes, signal handling, and `fs` module (`read`, `write`, `create_dir`, metadata).

---

## Workflow

1. **Identify the need** — collection, pointer, string, I/O, iterator, or system interface?
2. **Apply decision tree** — pick from the relevant Part above
3. **Check MSRV** — some APIs (`OnceLock` 1.70, `LazyLock` 1.80, scoped threads 1.63) need recent stable
4. **Compose with combinators** — prefer `Option`/`Result` chains over explicit `match`
5. **Verify** — `cargo check`, `cargo test`, `cargo clippy`
6. **Hand off** — async runtime → `rust-concurrency`; unsafe → `rust-unsafe-ffi`; application concerns → domain skills

## Decision Shortcuts

| Question | Answer |
|---------|--------|
| Default collection? | `Vec<T>` |
| Need key-value lookup? | `HashMap` (unordered) or `BTreeMap` (sorted) |
| Shared ownership? | `Rc` (single-thread) or `Arc` (multi-thread) |
| Mutable shared state? | `RefCell` (single) or `Mutex`/`RwLock` (multi) |
| String parameter? | `&str` always |
| File path? | `Path` / `PathBuf` |
| Lazy global? | `OnceLock` (1.70+) or `LazyLock` (1.80+) |
| Iterate borrowed? | `.iter()` |
| Two-way queue? | `VecDeque` |
| Priority queue? | `BinaryHeap` |

## Resources

- [Collections Deep Dive](references/collections.md)
- [Smart Pointers](references/smart-pointers.md)
- [String Types](references/string-types.md)
- [Option/Result Combinators](references/option-result-combinators.md)
- [I/O Streams](references/io-streams.md)
- [Iterators](references/iterators.md)
- [Std Concurrency](references/std-concurrency.md)
- [Process and Filesystem](references/process-and-fs.md)
- [Interior Mutability](references/interior-mutability.md)
- [Std Module Index](references/std-module-index.md)
- `examples/golden-stdlib/`: a crate exercising collections, pointers, channels, and iterators

## Upstream Sources

- [Rust Standard Library](https://doc.rust-lang.org/std/)
- [std::collections](https://doc.rust-lang.org/std/collections/index.html)
- [std::sync](https://doc.rust-lang.org/std/sync/index.html)
- [std::cell](https://doc.rust-lang.org/std/cell/index.html)
- [std::io](https://doc.rust-lang.org/std/io/index.html)
- [std::path](https://doc.rust-lang.org/std/path/index.html)
- [std::process](https://doc.rust-lang.org/std/process/index.html)
- [std::thread](https://doc.rust-lang.org/std/thread/index.html)
Files in this package (15)
  • SKILL.md 17 KB
  • agents/openai.yaml 1 KB
  • examples/golden-stdlib/Cargo.lock 1 KB
  • examples/golden-stdlib/Cargo.toml 1 KB
  • examples/golden-stdlib/src/lib.rs 6 KB
  • references/collections.md 7 KB
  • references/interior-mutability.md 7 KB
  • references/io-streams.md 6 KB
  • references/iterators.md 6 KB
  • references/option-result-combinators.md 6 KB
  • references/process-and-fs.md 7 KB
  • references/smart-pointers.md 6 KB
  • references/std-concurrency.md 7 KB
  • references/std-module-index.md 9 KB
  • references/string-types.md 6 KB

Versions

The database has no other skills named rust-stdlib.

Database snapshot: 13.11.2026 · package version 576b959197eb (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100rs-resource
    CRITICAL: Use for smart pointers and resource management. Triggers: Box, Rc, Arc, Weak, RefCell, Cell, smart pointer, heap allocation, reference counting, RAII, Drop, should I use Box or Rc, when to use Arc vs Rc
  • 100rs-mutability
    CRITICAL: Use for mutability issues. Triggers: E0596, E0499, E0502, cannot borrow as mutable, already borrowed as immutable, mut, &mut, interior mutability, Cell, RefCell, Mutex, RwLock
  • 100rust-patterns
    Writes and reviews idiomatic Rust - ownership and borrowing decision rules for API signatures, lifetime avoidance strategies, thiserror vs anyhow error design, iterator-first style, and when Rc/RefCell/Arc/Mutex are actually justified - with good/bad code pairs. Use when someone…
  • 95ownership-not-clone
    Use ownership and borrowing instead of reaching for clone, Rc, RefCell, or Arc<Mutex<_>> to silence the borrow checker. Every clone must be explainable. Use when code clones to make an error go away, when a borrow-checker fight is being resolved by copying data, when reviewing…
  • 100rust-stable
    Implement and explain stable Rust language semantics with explicit toolchain and MSRV checks — ownership, borrowing, lifetimes, move semantics, traits, generics, associated types, pattern matching, closures, error propagation, and Edition differences. Use as the core Rust…
  • 95port-from-cpp
    Port C++ into Rust — RAII and smart pointers onto ownership, templates onto generics and traits, exceptions onto Result, the STL onto Rust collections, and the traps (move semantics, implicit conversions, undefined behaviour, iterator invalidation). Use when porting, rewriting,…

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.