Commit Graph
108 Commits
Author SHA1 Message Date
bflatastic fd0f4d8b60 Merge main into #664
Main's class_name takes the node kind (#1372); Vue's slot names pass slot.
2026-10-27 00:30:42 +07:00
bflatastic 4176400e09 Merge main into #664
# Conflicts:
#	crates/engine/src/code_connect.rs
#	crates/engine/src/codegen.rs
#	crates/engine/src/component_codegen.rs
#	crates/engine/src/lib.rs
#	crates/engine/src/playground.rs
#	crates/ui-egui/locales/bn.toml
#	crates/ui-egui/locales/cs.toml
#	crates/ui-egui/locales/de.toml
#	crates/ui-egui/locales/en.toml
#	crates/ui-egui/locales/es.toml
#	crates/ui-egui/locales/fi.toml
#	crates/ui-egui/locales/fr.toml
#	crates/ui-egui/locales/id.toml
#	crates/ui-egui/locales/ja.toml
#	crates/ui-egui/locales/ka.toml
#	crates/ui-egui/locales/ko.toml
#	crates/ui-egui/locales/nl.toml
#	crates/ui-egui/locales/pl.toml
#	crates/ui-egui/locales/pt-BR.toml
#	crates/ui-egui/locales/ru.toml
#	crates/ui-egui/locales/sv.toml
#	crates/ui-egui/locales/tr.toml
#	crates/ui-egui/locales/zh-Hans.toml
#	crates/ui-egui/src/dev_mode.rs
#	docs/dev-mode-parity.md
#	docs/gaps.md
#	docs/mcp.md
#	docs/target-app-parity.md
2026-10-26 23:52:51 +07:00
Muamer MustaficandCursor b6d3e002df M4: truncated text fills its last line, keeps truncating when resized, and auto height takes max lines (#1375, #1376, #1377)
- The last line shown runs on into the word wrapped after it, so the ellipsis
  fills the line ("Lorem consec…") instead of following the last whole word.
- An explicit height (node.set, transform.resize, a resize handle, fixed
  sizing) on truncating text keeps it truncating (TextData::fix_size).
- Max lines on auto-height text hugs up to that many lines and ends in an
  ellipsis; text.maxLines keeps auto height, Type settings show it as
  truncating, .fig export writes textTruncation and import keeps auto height.
- node.get reports maxLines; text.fit measures every line.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 13:14:51 +01:00
BFlat 8d60360173 M11: widgets take text input and a property menu (plugin API 4) (#1365)
* M8: widgets take text input and a property menu

Plugin API 4 (gap 6). A widget's text layer can be an editable field:
a double-click edits it like any text, and when editing ends the value
(cleaned, at most 1,000 characters) goes into the widget's state under
the field's name and its plugin redraws, as one undo step. A widget can
also carry a property menu of up to 8 actions, toggles and colour
choices, shown in a small bar over it while it's selected.

- widget.setText and widget.menu drive the same paths from scripts,
  the CLI and MCP; widget.insert/list also report fields and menu
- descriptions, values and stored menus are validated as untrusted;
  an API 3 plugin drawing a field or menu is refused, older hosts
  refuse API 4 manifests; no new host imports
- SDK reads the new events; the Counter example gains a label field
  and a menu (reset, steps of ten, a colour)
- tests for fields, menus, canvas editing, rollback, forged data and
  live sync; junk sweep extended; labels in every command catalog
- docs: plugins, mcp, gaps, target-app-parity, ROADMAP, roadmap

* M8: widget property menu on egui 0.37

Id::new and Ui::id are deprecated in egui 0.37: the widget bar's area uses Id::unique and its buttons' interaction ids come from ui.scope_id().

* M11: a double-click a board object or a widget field takes, in a function of its own (Sonar)
2026-10-26 13:31:53 +07:00
BFlat d3782fdc43 M12: board templates and tables (#1363)
* M12: board templates and tables

Five built-in board templates (retrospective, brainstorm, weekly planner,
flow chart, kanban board) placed as ordinary board objects in one undo step
(board.template, board.templates) from a toolbar picker with pictures, and
board tables made of auto layout frames (board.table, board.tableEdit; up to
50 x 20), typed into with a double-click and edited by row and column from
the bar over the selection. Docs: boards-parity, gap 24, ROADMAP, mcp.

* M12: board templates picker on egui 0.37

Id::new and Ui::id are deprecated in egui 0.37: the templates picker's area uses Id::unique, its buttons' interaction ids come from ui.scope_id(), and its test reads the board bar's area by Id::unique.
2026-10-26 12:52:39 +07:00
BFlat 4fad29a66e M12: board timer and voting sessions (#1361)
* M12: board timer and voting

A countdown everyone on a board sees (board.timer, board.timerState), synced as its end time or the
time left while paused, and voting sessions (board.vote, board.voteResults): votes per person, on
everything, stickies or the selection; clicks vote, your badge takes a vote back; your own votes
show while it runs, everyone's with a ranked list once it ends. Timer and vote sync as document
properties and ballots as one entry per voter; neither is an undo step. A pill at the top right
of the board, new Timer, Pause and Vote icons, labels and strings in every catalog, docs.

* M12: board timer and voting on egui 0.37

Id::new is deprecated in egui 0.37: the timer and voting area and its memory ids use Id::unique.

* M12: board.vote's start and ballot changes in functions of their own (Sonar)
2026-10-26 12:28:59 +07:00
BFlat 26291aff2c M12: boards dot grid, re-attaching connector ends, curved connectors (#1249)
* M12: boards dot grid, re-attaching connector ends, curved connectors

Board pages draw a dot grid in the canvas render, after the page colour
and under the layers (figcraft_render::Dots), thinned out when zoomed out
and coloured from the theme's ink against the page. A selected connector
shows its ends as handles; dragging one onto an object re-attaches it,
onto empty canvas leaves it free (board.reattach, one undo step, also
over MCP). Connectors can be curved, and elbows go around the objects
they join when the short way would cross them.

* M12: boards dot grid: blending a dot in a function of its own (Sonar)
2026-10-26 11:52:16 +07:00
BFlat 8e79ffc3d7 Merge pull request #1021 from sarsonj/feat/sketch-import
M6: .sketch import (Sketch 48 and newer)
2026-10-26 11:10:16 +07:00
BFlat 3a641026ad Merge pull request #1202 from culiulemon/main
Vector editing, property copy/paste, dev-mode assets, ArkUI codegen and shape-builder fixes
2026-10-26 10:53:13 +07:00
bflatastic 27d1089847 Merge main into #1021
# Conflicts:
#	ROADMAP.md
#	docs/target-app-parity.md
2026-10-26 10:43:34 +07:00
bflatastic 9c57ba1beb Merge main into #1202 2026-10-26 08:43:07 +07:00
midasdf b3242d8eaf Merge origin/main into jp/kinsoku-jis 2026-10-26 00:28:52 +09:00
Jindřich ŠaršonandClaude Opus 5.5 e712b359fc M6: Sketch import: merge main
Conflicts were only in the Change notes of docs/file-format-parity.md and
docs/target-app-parity.md: main's notes kept, the `.sketch` note added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:22:06 +01:00
aiongg b5ed2913d7 Merge #1307 2026-10-25 02:21:44 +00:00
aiongg c104757f59 Merge #1286 2026-10-25 02:21:08 +00:00
dotCooCoo 4f0649ad52 M7: the export settings name Ignore overlapping layers and offer Include bounding box for text layers only
The export setting's advanced options name the contentsOnly option
"Ignore overlapping layers" and offer Include bounding box only when
every selected layer is a text layer. A setting that already has Include
bounding box on still shows the option, so it can be turned off, and the
export still applies it. The saved keys and the contentsOnly and
includeBoundingBox params of export.add, export.update and file.export
are unchanged.

Every catalog's "Contents only" row becomes an "Ignore overlapping
layers" row.
2026-10-24 17:21:42 -07:00
Jindřich ŠaršonandClaude Opus 5.5 87db9522b4 M6: Sketch import: merge main (Boards M12 and community fixes)
Conflicts resolved keeping both sides: `.sketch` stays in `is_document`
(now via `OsStr::to_str`); ROADMAP and the parity, roadmap and
file-format docs keep main's headers and rows with the `.sketch` notes
and history rows added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 19:13:03 +02:00
dotCooCoo 954f9036da Docs: parity rows for mouse-trigger delays, outline options and missing fonts
Three parity rows still listed work that has landed on main. The
prototyping Triggers row listed delays on mouse enter, leave, down and
up as missing; they landed on 2026-10-13. Canvas & navigation's
remaining work in target-app-parity listed outline mode's Include
hidden layers and Include object bounds, which View > Outlines has.
The file-format Fonts row said missing fonts give warnings only; the
desktop app lists them in the Missing fonts window, and replacing them
is still missing.

Each file gets its status line and a revision-history row. The
percentages and hours are unchanged.
2026-10-24 09:19:45 -07:00
dotCooCoo 811d599960 M4: corner smoothing on polygons and stars
Polygon and star outlines did not use their corner smoothing: the value
was stored, imported and exported, but `shape_path` drew their corners
as plain circular arcs, and the Design panel showed the Corner
smoothing field only for rectangles and frames. Rounded polygon and
star corners now take smoothing the way rectangle corners do. Each
corner keeps a circular arc over the unsmoothed part of its turn and
eases into both edges, and it starts (1 + smoothing) times the plain
corner's length from the vertex. When a smoothed corner does not fit
in half of its shorter edge, smoothing is reduced first, then the
radius, as for rectangles. The Individual corners button opens the
panel for polygons and stars too, with the Corner smoothing row and no
field per corner.
2026-10-24 07:22:36 -07:00
BFlat e3e39bbc4d M6: Dev Mode measurements kept on the canvas, a read-only layers panel (#1248)
* M6: Dev Mode measurements kept on the canvas, a read-only layers panel

Measurements placed between two layers, along a side or to the layer
around one (devMode.addMeasurement / removeMeasurement / measurements),
stored on the layer they start from (saved, synced, undoable; old files
open without them), drawn in Dev Mode as labelled redlines that follow
the layers and listed, placed and removed in the Inspect tab. In Dev Mode
the layers panel only selects and expands.

* M6: Dev Mode measurements: explicit imports, a measurement row of its own (Sonar)
2026-10-24 13:33:26 +07:00
bflatastic 62a3072134 Merge main and the community batch into #1202
# Conflicts:
#	crates/engine/src/component_codegen.rs
#	crates/engine/src/tools.rs
#	crates/ui-egui/locales/fi.toml
#	crates/ui-egui/locales/nl.toml
#	crates/ui-egui/src/dev_mode_tests.rs
#	crates/ui-egui/src/shortcuts.rs
#	docs/dev-mode-parity.md
#	docs/file-format-parity.md
#	docs/ui-parity.md
2026-10-24 09:39:52 +07:00
bflatastic 1e4a31a303 Merge #1199: M3: instance-swap properties in the Dev Mode component playground (@marcoarnulfo) 2026-10-24 09:15:41 +07:00
bflatastic 6063d3e9a9 Merge #1189: M4: vector edit transform box around points of several layers (@marcoarnulfo)
# Conflicts:
#	docs/target-app-parity.md
#	docs/ui-parity.md
2026-10-24 09:15:11 +07:00
midasdf 18832c620e Merge remote-tracking branch 'origin/main' into jp/kinsoku-jis
# Conflicts:
#	ROADMAP.md
#	docs/target-app-parity.md
2026-10-24 09:44:03 +09:00
BFlat 8167f13a6a M12: Boards: a collaborative whiteboard file kind (#1229)
Board files (File > New board) with sticky notes, shapes with text, connectors that follow what they join (straight or elbow, arrowheads, labels), marker, highlighter and eraser, and stamps; a board toolbar and a contextual bar; the Design panel hidden on boards, Prototype and Dev Mode refused there. Boards are ordinary FigCraft files built from ordinary layers, so saving, undo, export, MCP and live sessions work unchanged. File tabs, recent files and Open files show a pen nib for design files and a note for boards (original icons drawn in code).
2026-10-24 04:18:55 +07:00
midasdf 04e60e23bc Merge remote-tracking branch 'origin/main' into jp/kinsoku-jis
# Conflicts:
#	ROADMAP.md
#	docs/target-app-parity.md
2026-10-24 04:11:13 +09:00
BFlat d6e8a6e874 Docs: roadmap entries for the community PRs in #507, #510, #529 and #530 (#587)
Roadmap, milestone and parity rows for the 93 community PRs landed in batches #507, #510, #529 and #530.
2026-10-24 02:02:19 +07:00
Marco Arnulfo af0b150736 M3: instance-swap properties in the Dev Mode component playground 2026-10-23 03:28:55 +02:00
Marco Arnulfo 1f2a8104bf M4: vector edit transform box around points of several layers
With points selected in more than one edited layer the transform box now
wraps them all, in the page's axes since the layers can be turned
differently. Its corners and edges scale them, outside a corner rotates
them and inside drags them; each layer's points are mapped in its own
coordinates and the whole drag is one undo step. A click inside clears
every layer's points.
2026-10-22 23:37:49 +02:00
Nicek 7e28d58b3f feat: 新增 ArkUI 代码生成和代码连接支持
添加 ArkUI 作为新的代码语言支持,包括:
- 代码生成:支持生成 ArkTS 组件代码,包括 `@Component` 结构体、`@Prop` 参数、`@BuilderParam` 构建器等
- 代码连接:支持将组件连接到 ArkTS 代码,包括导入路径和模板配置
- 测试:添加 ArkUI 相关测试用例,验证代码生成和连接功能的正确性
- 更新文档:更新开发模式 parity 文档、文件格式一致性文档等,添加 ArkUI 相关说明
- 更新国际化:在所有支持的语言中添加 ArkUI 选项提示
2026-10-22 20:36:45 +08:00
phonedu 8787f46205 M6: a Vue code target (single-file components)
Dev Mode generates React, Leptos, SwiftUI and Compose; a Vue project had to translate the HTML
instead. `inspect.code {language: "vue"}` now writes a single-file component: a `<template>`, a
`<script setup>` with `defineProps` and its defaults, and a `<style scoped>`.

A Vue template holds no arbitrary expressions, so what the web targets write as a braced
expression has its own spelling. Text is `{{ prop }}`, and braces in text are escaped; a boolean
property's layer carries `v-if="prop"` rather than a wrapper element; a slot becomes Vue's own
`<slot name="…">` with its fallback content, which takes no prop, and an instance's content in one
is a `<template #name>`. Variants switch on the root's `data-*` attributes, as on the web.

`codeConnect` links a component to its code as a single-file component: a default import, and a
quoted binding, so `:size={size}` gives `:size="Large"` and a component swap passes the component
itself. A value that needs escapes keeps them inside the quotes, where the attribute's own quotes
become `&quot;`.

`inspect.componentCode` kept a second copy of the code-language list, which is how Vue was missed
when `inspect.code` learned it; it now asks `code_connect::language`, the one list, as
`codeConnect` does.

Eleven tests in `vue_codegen_tests` and a `codeConnect` case; the Inspect panel's language picker
picks Vue up from `CodeLang::ALL`, and the language lists in the docs, the Dev Mode hint and its
thirteen catalogs name it.
2026-10-22 14:12:45 +08:00
Jindřich ŠaršonandClaude Opus 5.5 03c5324305 M6: Sketch import: count it in the parity assessment
Figma imports Sketch files from its file browser (desktop app too); the
area table hadn't listed it. Import/export breadth 86% → 87%, file
formats 60% → 61%; headline numbers unchanged after rounding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 00:27:20 +02:00
Jindřich ŠaršonandClaude Opus 5.5 5f5b802127 M6: Sketch import: roadmap and parity rows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 00:27:20 +02:00
midasdf 42bdfcce34 M4: CJK kinsoku completed to JIS X 4051
JIS X 4051's line-start (行頭禁則) and line-end (行末禁則) sets were mostly
there — closing punctuation and brackets, small kana, the prolonged sound
mark, iteration marks and opening brackets already never start or end a line —
but a few categories fell through:

- the halfwidth small kana ァ–ッ (U+FF67..U+FF6F) and the halfwidth voicing
  marks ゙゚ (U+FF9E/U+FF9F) were not line-start prohibited, so a wrapped line
  could begin with them;
- the spacing (semi-)voiced sound marks ゛゜ (U+309B/U+309C) and the kana
  iteration marks 〱〲〳〴〵 (U+3031..U+3035) likewise;
- the halfwidth parentheses ⦅⦆ were missing from the line-end/line-start
  sets.

Add them (ranges in `class`, the two parentheses in the OPEN and CLOSE
strings), and pin every JIS category in the behaviour suite: the existing 22
cases stay and 9 join them (halfwidth small kana and small tsu, halfwidth and
spacing voicing marks, kana and vertical kana iteration marks, both halfwidth
parentheses), plus a wrap case where a halfwidth small kana moves down with
its base (キャ) and a case showing a manual newline may still start a line with
a prohibited character (禁則 is for automatic wrapping only).
`break_opportunities` fails on the old sets at the first new halfwidth
small-kana case.

Latin wrapping, ideograph breaks and the rest of the behaviour suite are
unchanged, and the headline numbers stay as they are.

Verified: cargo test -p figcraft-text --lib 92 passed; cargo clippy
-p figcraft-text --all-targets -- -D warnings clean; rustfmt clean on the
touched files.

Docs: docs/target-app-parity.md text behaviour row and ROADMAP progress log,
revision history and header.
2026-10-22 01:37:55 +09:00
bflatastic 05da6b2125 M1: node.get reports layer data (pluginData) (#879)
Layer data written with node.set {props: {pluginData}} was saved but no
command read it back. node.get (the command, the control method and MCP
get_node) and document.inspect now report pluginData as {key: value}
when a layer or page has any, so a tool keeping state in a file can
read it on its next run. Widget keys are included: the plugin rules
only stop plugins writing them, and widget.list already reports that
state.
2026-10-20 04:58:32 +07:00
BFlat c6d6433473 Docs: parity rows for the 2026-10-17 landings (#756)
Brings the progress docs up to date with what landed on 2026-10-17: community batches #727, #728, #733, #735, #736 and #753, plus #729, #745, #746 and #751. Docs only.
2026-10-17 21:56:26 +07:00
BFlat ac4b98dbd7 M8: confine MCP file access with --automation-read-root/--automation-write-root (#715) (#746)
- `figcraft-cli mcp --automation-read-root DIR --automation-write-root DIR` (each repeatable, `--flag=DIR` works too). When either is given, every file an agent's tool call reads must lie inside a read root or a write root, and every file it writes inside a write root. Anything else is an ordinary tool error (`automation path rejected: … is outside the folders that may be written: …`); nothing is written and the server keeps serving. Without the flags nothing changes.
- The desktop app takes the same flags (`figcraft --control PORT --automation-read-root DIR …`) and confines every control request and every frame of every window to them, so `figcraft-cli mcp --attach` drives a confined app. `--attach` together with the flags is a usage error, because the app runs the commands and only the app can confine them.
- New engine module `crates/engine/src/file_access.rs`: `Roots` (resolution and comparison), a thread-scoped `confined(roots, f)`, and the file primitives (`read`, `read_capped`, `open`, `metadata`, `read_dir`, `write` (atomic), `create_dir_all`, `exists`, `is_dir`). Every engine file access now goes through it. `crates/engine/clippy.toml` denies `std::fs::*`, `File::open/create`, `OpenOptions::open`, `Path::exists/is_file/is_dir/metadata/read_dir/canonicalize` and `figcraft_format::{write_file_atomic, save_file, load_file}` everywhere else in the engine, so a command added later is confined without a check of its own.
- `ui.screenshot` and `ui.render` return the PNG as base64 `data` when no `path` is given (before, `ui.screenshot` wrote `figcraft-screenshot.png` in the working directory and `ui.render` required a path). The attached MCP backend uses that, so it no longer writes and deletes temporary PNGs, and a confined app needs no exemption for them.
- `initialize`'s `instructions` name the folders the agent may read and write.
- `figcraft-cli` options may be given more than once (`Args::values`); single-valued options keep the last value, as before.
- Docs: `docs/mcp.md` › Confining file access (options, semantics, coverage, resolution, limits), `docs/control-protocol.md` › Confining file access and the optional `path` of `ui.screenshot` / `ui.render`, `docs/cli.md`, `figcraft-cli --help`, and the Automation line plus a revision row in `docs/target-app-parity.md`.

Fixes #715, fixes #481.
2026-10-17 19:56:20 +07:00
BFlat 9e28e11954 M3: number variables in the text content picker (#629) (#725)
The Typography section's variable picker also lists number variables for a text layer's content (shown as the number), as the engine already accepted; other text fields keep their own types (#629).
2026-10-17 14:03:59 +07:00
BFlat 40c744da10 M1: convert frames to sections and sections to frames (#719) (#721)
Frames on the page or in a section convert to sections (object.convertToSection) and sections back to frames (object.convertToFrame), in place, one undo step each, from the canvas context menu; nested frames, instances, main components and sections holding sections are refused.
2026-10-17 13:03:49 +07:00
VanTan 7a0bd980c6 M9: add Russian interface translation 2026-10-14 09:33:58 +03:00
rcoenenandClaude Opus 5.5 6267ae5638 Vector edit mode: hover, hatch, select and drag filled regions (#243)
With the Move tool, the filled area under the pointer is hatched with "/" lines in the selection colour (1.4 px), clipped by the area's own fill rule so holes stay clear. The hatch goes when the pointer is 3.5 px from a point or 2 px from a segment (screen pixels at any zoom); between those clearances and the 6 px hit radius the area wins. Bezier handles, the transform box's handles and other edited layers' parts come first. Line spacing follows octave folding: 8 px at every power-of-two zoom, growing with the zoom and stepping back at sqrt(2) * 2^n. The pattern is anchored to the vector's origin, so it stays on the shape when panning, and several selected areas share one pattern. The last area listed wins where areas overlap, and only vectors with a visible fill have areas.

A click selects an area with its points; they move with it (drags, nudges, the Design panel) but keep the unselected look and show no handles. Shift adds an area or takes a selected one out (its own points go, points selected on their own or shared with another selected area stay). A press on a selected area drags everything selected, as one undo step; Escape puts it back. Drags show no hover hatch. Any other press without Shift drops the areas and the points selected only through them, and a click on an empty spot such as a hole clears them and stays in edit mode. Inside the transform box around points selected on their own, the box keeps its drag unless the area is already selected. Area indexes are dropped when the network's topology changes; moving points keeps them.

The network gets region walking, an inside test per region by its own fill rule, the region under a point, a region's points and a topology fingerprint (vector_regions.rs). The engine does hit testing and lays out and clips the hatch in screen space (vectoredit/regions.rs); the canvas only draws the lines. vector.edit.select takes regions, and vector.edit.state reports regions, regionVertices and regionHover. Tests: vector_regions_tests (doc) and regions_tests (engine), covering fill rules, overlap, curves, reversed segments, clearances at 100% and 400%, selection, drags, undo and cancel, and the hatch spacing at seven zoom levels, its direction, anchoring, coverage and clipping.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:17:17 +07:00
YTwsy 0efbd55564 Bound plugin logs before allocation and host forwarding (#216)
Plugin log lines are admitted before guest memory is copied: a line over 8 KiB, more than 1,000 lines or more than 1 MiB of log bytes in a run fails the run with a limit error, and the same budgets bound what is forwarded to the host logger. Fixes #191.
2026-10-14 05:49:32 +07:00
bflatastic e56856f401 M3: component playground: variant, boolean and text properties 2026-10-13 13:36:54 +07:00
bflatastic e02ad435b3 M2: auto layout: dragging an automatic gap's handle fixes the gap 2026-10-13 13:36:54 +07:00
bflatastic a399ff8934 M3: variables inside styles 2026-10-13 13:36:54 +07:00
bflatastic d7f76246d3 M3: effects on groups: inner shadows and background blur 2026-10-13 13:36:54 +07:00
bflatastic fca70a6063 M1: text made by commands in the app is readable on dark pages 2026-10-13 13:36:54 +07:00
bflatastic 2c35c7bd21 M1: frames and groups: one-step convert 2026-10-13 13:36:54 +07:00
bflatastic 5548284c65 M5: prototyping: delays on mouse triggers, manual overlay offsets 2026-10-13 13:36:54 +07:00
bflatastic a2a0f80252 M2: auto layout: wrapped-line alignment 2026-10-13 13:36:54 +07:00