{"_id":"@06parnil/cubit.js","name":"@06parnil/cubit.js","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@06parnil/cubit.js","version":"1.0.0","description":"A lightweight, dependency-free JavaScript engine for modeling, manipulating, and visualizing NxN cubes.","type":"module","main":"./src/index.js","exports":{".":"./src/index.js"},"scripts":{"test":"node tests/cubeEngine.test.js && node tests/physicalCorrectness.test.js && node tests/regression.test.js","example":"node examples/basic.js"},"keywords":["rubiks-cube","cube","cubing","speedcubing","twisty-puzzle","scramble","cube-state","cube-visualizer","visualizer","javascript"],"author":{"name":"Parnil Vyawahare"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/parnilV06/Cubit.JS.git"},"bugs":{"url":"https://github.com/parnilV06/Cubit.JS/issues"},"homepage":"https://github.com/parnilV06/Cubit.JS#readme","engines":{"node":">=16.0.0"},"dependencies":{},"_id":"@06parnil/cubit.js@1.0.0","gitHead":"1a2b41333f44a074dbe23b2cb2e80e3d26da6ca4","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-hFqdsZHTRim8UnRQnodY3uevr6HgCTrnHnvphOQJpI0281IcnVAFsU37M7CgYs9/i+WRr+p/NIgLHuS3ZXgYlQ==","shasum":"0f7ace3f8389aa3f6c235395e0dd1a3ebfdaede8","tarball":"https://registry.npmjs.org/@06parnil/cubit.js/-/cubit.js-1.0.0.tgz","fileCount":12,"unpackedSize":58876,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5gMcKhOYGpESQ0YdZs6Enc04GEdRE2tzrNvITyFedZAIhAIZpDUab+/UMloqfMYbGP0DAWJauk+7lcHu7FV2gzkcr"}]},"_npmUser":{"name":"06parnil","email":"06v.parnil@gmail.com"},"directories":{},"maintainers":[{"name":"06parnil","email":"06v.parnil@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cubit.js_1.0.0_1785692048455_0.4961939347774553"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T17:34:08.313Z","1.0.0":"2026-08-02T17:34:08.602Z","modified":"2026-08-02T17:34:08.788Z"},"maintainers":[{"name":"06parnil","email":"06v.parnil@gmail.com"}],"description":"A lightweight, dependency-free JavaScript engine for modeling, manipulating, and visualizing NxN cubes.","homepage":"https://github.com/parnilV06/Cubit.JS#readme","keywords":["rubiks-cube","cube","cubing","speedcubing","twisty-puzzle","scramble","cube-state","cube-visualizer","visualizer","javascript"],"repository":{"type":"git","url":"git+https://github.com/parnilV06/Cubit.JS.git"},"author":{"name":"Parnil Vyawahare"},"bugs":{"url":"https://github.com/parnilV06/Cubit.JS/issues"},"license":"MIT","readme":"# Cubit.js\n\n> A lightweight, dependency-free JavaScript engine for modeling, manipulating, and visualizing NxN Rubik's Cubes.\n\n**Cubit.js** is a lightweight, dependency-free JavaScript/npm library for applying Rubik’s Cube scrambles, modeling NxN cube states, and generating framework-agnostic 2D cube net data. Built from the cube engine powering [**Cubit**](https://github.com/parnilV06/Cubit), an open-source speedcubing platform, and was later extracted into an independent package so other cubing projects can use the same engine.\n\n**[API Reference](./docs/API.md)** · **[Cube Model](./docs/CUBE_MODEL.md)** · **[Visualization Guide](./docs/VISUALIZATION.md)** · **[Contributing](./CONTRIBUTING.md)**\n\nCubit.js V1 focuses on one job:\n\n```text\nScramble\n   ↓\nCube State Engine\n   ↓\nScrambled Cube State\n   ↓\n2D Net Data\n   ↓\nYour UI\n```\n\nThe package contains **zero runtime dependencies** and does not depend on React, Vue, Canvas, SVG, or any other rendering framework.\n\n---\n\n## Installation\n\n```bash\nnpm install cubit.js\n```\n\nCubit.js uses ES modules.\n\n```js\nimport {\n  applyScramble,\n  getNetData\n} from 'cubit.js';\n```\n\n---\n\n# Quick Start\n\n```js\nimport { applyScramble, getNetData } from 'cubit.js';\n\nconst scramble = \"R U R' U' F2 U2 R' U\";\n\n// Apply the scramble to a solved 3x3 cube\nconst state = applyScramble(scramble, '3x3');\n\n// Convert the resulting cube state into visualization data\nconst net = getNetData(state);\n\nconsole.log(state);\nconsole.log(net);\n```\n\nThat's the basic Cubit.js workflow:\n\n```text\n\"R U R' U'\"\n      ↓\napplyScramble()\n      ↓\nCubeState\n      ↓\ngetNetData()\n      ↓\nRenderable 2D Net Data\n```\n\n---\n\n# Features\n\n- Zero runtime dependencies\n- Pure JavaScript / ESM\n- Immutable cube-state transformations\n- 2x2, 3x3, 4x4 and 5x5 support\n- Standard face turns\n- Prime turns\n- Double turns\n- Wide moves\n- Multi-layer wide moves\n- WCA-style scramble notation parsing\n- Physically verified cube rotations\n- Framework-agnostic visualization data\n- Deterministic state transformations\n- Comprehensive physical-correctness tests\n\nCubit.js deliberately separates **cube mathematics** from **rendering**.\n\nThe package calculates the cube.\n\n**You decide how it looks.**\n\n---\n\n## Documentation\n\nCubit.js includes detailed documentation for developers who want to go beyond the quick-start examples or understand the engine internals.\n\n| Guide | Description |\n| --- | --- |\n| **[API Reference](./docs/API.md)** | Complete reference for the public Cubit.js API, including function signatures, parameters, return values, examples, and error behavior. |\n| **[Cube Model & Mathematics](./docs/CUBE_MODEL.md)** | Technical documentation for the cube-state representation, coordinate system, face orientation, rotation mathematics, layer semantics, and immutability model. |\n| **[Visualization Guide](./docs/VISUALIZATION.md)** | Learn how to turn Cubit.js net data into a visual cube net using HTML/CSS, SVG, Canvas, React, Vue, or other rendering technologies. |\n| **[Contributing](./CONTRIBUTING.md)** | Development setup, architecture guidelines, testing requirements, regression testing, and contribution workflow. |\n\n### Where should I start?\n\nIf you simply want to use Cubit.js:\n\n1. Follow the **Quick Start** below.\n2. Read the **[API Reference](./docs/API.md)** for available functions.\n3. Read the **[Visualization Guide](./docs/VISUALIZATION.md)** if you're building a cube visualizer.\n\nIf you're interested in how Cubit.js works internally, see **[Cube Model & Mathematics](./docs/CUBE_MODEL.md)**.\n\n> Most applications only need `applyScramble()` and `getNetData()` to get started.\n\n---\n\n# Supported Cubes\n\n| Puzzle | Supported |\n| --- | :---: |\n| 2x2 | ✅ |\n| 3x3 | ✅ |\n| 4x4 | ✅ |\n| 5x5 | ✅ |\n\nExample:\n\n```js\napplyScramble(scramble, '2x2');\napplyScramble(scramble, '3x3');\napplyScramble(scramble, '4x4');\napplyScramble(scramble, '5x5');\n```\n\n---\n\n# Cube Orientation\n\nCubit.js uses the following solved orientation:\n\n| Face | Color | Hex |\n| --- | --- | --- |\n| U (Up) | White | `#F8FAFC` |\n| D (Down) | Yellow | `#FACC15` |\n| F (Front) | Green | `#22C55E` |\n| B (Back) | Blue | `#3B82F6` |\n| R (Right) | Red | `#EF4444` |\n| L (Left) | Orange | `#F97316` |\n\nThe canonical orientation is therefore:\n\n```text\n        WHITE\n          U\n\nORANGE   GREEN   RED   BLUE\n   L       F      R      B\n\n        YELLOW\n          D\n```\n\nWhen comparing a Cubit.js state against a physical cube, use the same orientation.\n\n---\n\n# Supported Move Notation\n\n## Standard turns\n\n```text\nR L U D F B\n```\n\n## Counter-clockwise / prime turns\n\n```text\nR' L' U' D' F' B'\n```\n\n## Double turns\n\n```text\nR2 L2 U2 D2 F2 B2\n```\n\n## Wide moves\n\n```text\nRw Uw Fw Lw Dw Bw\n```\n\nLowercase wide notation is also supported:\n\n```text\nr u f l d b\n```\n\n## Multi-layer wide moves\n\nExamples:\n\n```text\n3Rw\n3Rw'\n3Fw2\n```\n\n---\n\n# API\n\n## `applyScramble(scrambleInput, puzzleType?)`\n\nThe primary Cubit.js API.\n\nCreates a solved cube and applies the supplied scramble.\n\n```js\nconst state = applyScramble(\n  \"R U R' U'\",\n  \"3x3\"\n);\n```\n\n### Parameters\n\n#### `scrambleInput`\n\nA scramble string or parsed move array.\n\n```js\n\"R U R' U'\"\n```\n\n#### `puzzleType`\n\nSupported values:\n\n```text\n2x2\n3x3\n4x4\n5x5\n```\n\nDefault:\n\n```text\n3x3\n```\n\n### Returns\n\nA new `CubeState`.\n\n---\n\n## `createSolvedCube(puzzleType?)`\n\nCreates a solved cube.\n\n```js\nimport { createSolvedCube } from 'cubit.js';\n\nconst cube = createSolvedCube('3x3');\n```\n\nExample state:\n\n```js\n{\n  dimension: 3,\n\n  U: [\n    ['WHITE', 'WHITE', 'WHITE'],\n    ['WHITE', 'WHITE', 'WHITE'],\n    ['WHITE', 'WHITE', 'WHITE']\n  ],\n\n  D: [...],\n  F: [...],\n  B: [...],\n  R: [...],\n  L: [...]\n}\n```\n\nEach face is represented as an `N × N` matrix.\n\n---\n\n## `parseScramble(scramble)`\n\nParses scramble notation into structured move objects.\n\n```js\nimport { parseScramble } from 'cubit.js';\n\nconst moves = parseScramble(\n  \"R U R' U'\"\n);\n\nconsole.log(moves);\n```\n\nA move follows this structure:\n\n```js\n{\n  raw: \"R'\",\n  face: \"R\",\n  amount: -1,\n  depth: 1,\n  isWide: false\n}\n```\n\n---\n\n## `parseMove(move)`\n\nParses one move.\n\n```js\nimport { parseMove } from 'cubit.js';\n\nconst move = parseMove(\"3Fw2\");\n```\n\nResult:\n\n```js\n{\n  raw: \"3Fw2\",\n  face: \"F\",\n  amount: 2,\n  depth: 3,\n  isWide: true\n}\n```\n\n---\n\n## `applyMove(cubeState, move)`\n\nApplies one parsed move to an existing cube state.\n\n```js\nimport {\n  createSolvedCube,\n  parseMove,\n  applyMove\n} from 'cubit.js';\n\nconst cube = createSolvedCube('3x3');\n\nconst move = parseMove('R');\n\nconst nextState = applyMove(cube, move);\n```\n\nCubit.js transformations are immutable.\n\n`cube` remains unchanged.\n\n---\n\n# 2D Visualization\n\nCubit.js does **not** force a rendering technology on applications.\n\nInstead, it converts the mathematical cube state into simple JavaScript data.\n\n```js\nimport {\n  applyScramble,\n  getNetData\n} from 'cubit.js';\n\nconst state = applyScramble(\n  \"R U R' U'\",\n  \"3x3\"\n);\n\nconst net = getNetData(state);\n```\n\nThe returned structure resembles:\n\n```js\n{\n  dimension: 3,\n\n  netLayout: {\n    U: [...],\n    L: [...],\n    F: [...],\n    R: [...],\n    B: [...],\n    D: [...]\n  },\n\n  faces: [\n    { face: 'U', grid: [...] },\n    { face: 'L', grid: [...] },\n    { face: 'F', grid: [...] },\n    { face: 'R', grid: [...] },\n    { face: 'B', grid: [...] },\n    { face: 'D', grid: [...] }\n  ]\n}\n```\n\nEach sticker contains rendering information:\n\n```js\n{\n  colorKey: 'WHITE',\n  hexColor: '#F8FAFC',\n  face: 'U',\n  row: 0,\n  col: 0,\n  id: 'U-0-0'\n}\n```\n\nThat means applications can render Cubit.js output using:\n\n- CSS Grid\n- HTML\n- Canvas\n- SVG\n- React\n- Vue\n- Svelte\n- mobile UI frameworks\n- custom graphics engines\n\nwithout Cubit.js depending on any of them.\n\n---\n\n# Rendering a Cube Net\n\nThe conventional unfolded layout is:\n\n```text\n            ┌─────┐\n            │  U  │\n            └─────┘\n\n┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐\n│  L  │ │  F  │ │  R  │ │  B  │\n└─────┘ └─────┘ └─────┘ └─────┘\n\n            ┌─────┐\n            │  D  │\n            └─────┘\n```\n\nCubit.js provides the sticker data for each of these faces.\n\nThe positioning and styling remain under the consumer's control.\n\n---\n\n# Vanilla JavaScript Example\n\n```html\n<div id=\"cube-net\"></div>\n\n<script type=\"module\">\n  import {\n    applyScramble,\n    getNetData\n  } from 'cubit.js';\n\n  const state = applyScramble(\n    \"R U R' U'\",\n    \"3x3\"\n  );\n\n  const net = getNetData(state);\n\n  const container =\n    document.getElementById('cube-net');\n\n  net.faces.forEach(({ face, grid }) => {\n\n    const faceElement =\n      document.createElement('div');\n\n    faceElement.dataset.face = face;\n\n    faceElement.style.display = 'grid';\n\n    faceElement.style.gridTemplateColumns =\n      `repeat(${net.dimension}, 30px)`;\n\n    grid.forEach(row => {\n\n      row.forEach(sticker => {\n\n        const element =\n          document.createElement('div');\n\n        element.style.width = '30px';\n        element.style.height = '30px';\n\n        element.style.backgroundColor =\n          sticker.hexColor;\n\n        faceElement.appendChild(element);\n      });\n\n    });\n\n    container.appendChild(faceElement);\n  });\n</script>\n```\n\nThis example intentionally keeps rendering simple.\n\nA production application can position the six face elements into the standard unfolded cube-net layout using CSS Grid, Canvas, SVG, or another rendering system.\n\n---\n\n# Validation\n\nCube states can be validated using:\n\n```js\nimport { validateCubeState } from 'cubit.js';\n\nconst valid = validateCubeState(state);\n```\n\nCubit.js validates structural properties of the state before mathematical operations where appropriate.\n\n---\n\n# Error Handling\n\nInvalid developer input produces explicit errors rather than silently changing the requested operation.\n\nExamples include:\n\n```js\ncreateSolvedCube('7x7');\n```\n\n```js\nparseMove('X');\n```\n\n```js\nparseScramble('R U SOMETHING');\n```\n\nInvalid layer depths and malformed move notation are also rejected.\n\n---\n\n# Scramble Generation\n\nCubit.js V1 **does not generate scrambles**.\n\nIt consumes them.\n\nFor example:\n\n```js\nconst scramble =\n  \"R U2 F' L2 D B2 R' U\";\n\nconst state =\n  applyScramble(scramble, '3x3');\n```\n\nScrambles may come from:\n\n- a scramble generator\n- a competition-compatible scrambling system\n- user input\n- another cubing library\n- your own application\n\nThe architecture is intentionally:\n\n```text\nScramble Generator\n       ↓\nScramble String\n       ↓\n    Cubit.js\n       ↓\nCube State\n       ↓\nNet Data\n       ↓\nApplication UI\n```\n\nThis keeps the state engine independent from scramble-generation implementations.\n\n---\n\n# Immutability\n\nCubit.js does not mutate the supplied cube state during transformations.\n\nFor example:\n\n```js\nconst solved =\n  createSolvedCube('3x3');\n\nconst afterR =\n  applyMove(\n    solved,\n    parseMove('R')\n  );\n```\n\n`solved` remains unchanged.\n\nThis makes the engine suitable for state-management systems and reactive UI architectures.\n\n---\n\n# Testing & Physical Correctness\n\nCube mathematics can easily pass algebraic tests while still representating physical rotations incorrectly.\n\nFor that reason, Cubit.js uses both mathematical invariant tests and physical-reference tests.\n\nThe suite includes:\n\n- solved-state verification\n- matrix rotation verification\n- `M⁴ = Identity`\n- move + inverse verification\n- double-turn verification\n- color conservation\n- odd-cube center stability\n- all 12 physical quarter turns\n- multi-move sequences\n- unique sticker permutation verification\n- regression scramble verification\n- multi-size verification\n- randomized scramble cross-validation against an independent cube representation\n\nRun the suite with:\n\n```bash\nnpm test\n```\n\n---\n\n# Architecture\n\nCubit.js is intentionally split into small independent modules:\n\n```text\nsrc/\n├── constants.js\n├── engine.js\n├── index.js\n├── mapper.js\n├── matrix.js\n└── parser.js\n```\n\n### Engine\n\nResponsible for cube state and physical transformations.\n\n### Parser\n\nResponsible for converting notation into move operations.\n\n### Matrix\n\nContains reusable matrix transformation utilities.\n\n### Mapper\n\nTransforms mathematical state into visualization-friendly data.\n\n### Index\n\nDefines the public package API.\n\n---\n\n# Relationship to Cubit\n\nCubit.js was born inside **Cubit**, an open-source speedcubing platform.\n\nCubit required a cube visualizer capable of taking the exact scramble shown to a user, applying that scramble mathematically to a solved cube, and displaying the resulting physical state.\n\nInstead of coupling that engine permanently to the Cubit application, the reusable cube mathematics and visualization-data layer were extracted into an independent package.\n\nThat became **Cubit.js**.\n\nCubit remains the product.\n\nCubit.js is the reusable cube engine that originated from it.\n\nThe package is maintained independently so it can be used by other timers, trainers, visualizers, educational tools, cubing applications, experiments, and developer projects.\n\n---\n\n# Roadmap\n\n## V1 — Cube State & Visualization Engine\n\nCurrent release.\n\n- Scramble parsing\n- Cube-state generation\n- Move application\n- 2x2–5x5 support\n- Wide moves\n- Multi-layer moves\n- 2D visualization data\n- Framework-independent API\n\n## V2 — Generation & Rendering\n\nPlanned areas include:\n\n- built-in scramble generation\n- higher-level visualization helpers\n- SVG output\n- Canvas rendering helpers\n- optional React components\n- possible Vue / Svelte integrations\n- visualization customization\n\n## V3 — Solving & Analysis\n\nLonger-term exploration includes:\n\n- solution generation\n- scramble analysis\n- move-sequence analysis\n- move optimization\n- cube-solving utilities\n- training-oriented APIs\n\nThe roadmap is directional and may evolve as Cubit.js develops.\n\n---\n\n# Contributing\n\nContributions, bug reports, test cases, and feature proposals are welcome.\n\nIf you discover a scramble that produces an incorrect physical state, please include:\n\n- puzzle size\n- scramble\n- expected state\n- actual state\n- reproduction steps\n\nPhysical correctness is treated as a core requirement of the project.\n\n---\n\n# License\n\nCubit.js is released under the **MIT License**.\n\nSee [`LICENSE`](./LICENSE) for details.\n\n---\n\n# Cubit.js\n\nBuilt from the cube engine behind **Cubit**.\n\n**Scramble → State → Visualize.**","readmeFilename":"README.md","_rev":"1-4fb65cf7e0b638aa0468f1e0c5235aae"}