# @lume/kiwi Lume Kiwi is an efficient implementation of the Cassowary constraint solving algorithm, based on the seminal Cassowary paper. It is _not_ a refactoring or port of the original C++ solver, but has been designed from the ground up to be lightweight and fast. **Example** ```javascript import * as kiwi from '@lume/kiwi' // Create a solver const solver = new kiwi.Solver() // Adjust the max number of solver iterations before an error is thrown if // more is needed. Default is 10,000. solver.maxIterations = 20000 // Create and add some editable variables const left = new kiwi.Variable() const width = new kiwi.Variable() solver.addEditVariable(left, kiwi.Strength.strong) solver.addEditVariable(width, kiwi.Strength.strong) // Create a variable calculated through a constraint const centerX = new kiwi.Variable() const expr = new kiwi.Expression([-1, centerX], left, [0.5, width]) solver.addConstraint(new kiwi.Constraint(expr, kiwi.Operator.Eq, kiwi.Strength.required)) // Suggest some values to the solver solver.suggestValue(left, 0) solver.suggestValue(width, 500) // Lets solve the problem! solver.updateVariables() console.assert(centerX.value() === 250) ``` # API Documentation - [@lume/kiwi](#module_@lume/kiwi) - [~Variable](#module_@lume/kiwi..Variable) - [new Variable([name])](#new_module_@lume/kiwi..Variable_new) - [.name()](#module_@lume/kiwi..Variable+name) ⇒ String - [.setName(name)](#module_@lume/kiwi..Variable+setName) - [.value()](#module_@lume/kiwi..Variable+value) ⇒ Number - [.subscribe(callback)](#module_@lume/kiwi..Variable+subscribe) - [.unsubscribe()](#module_@lume/kiwi..Variable+unsubscribe) - [.plus(value)](#module_@lume/kiwi..Variable+plus) ⇒ Expression - [.minus(value)](#module_@lume/kiwi..Variable+minus) ⇒ Expression - [.multiply(coefficient)](#module_@lume/kiwi..Variable+multiply) ⇒ Expression - [.divide(coefficient)](#module_@lume/kiwi..Variable+divide) ⇒ Expression - [~Expression](#module_@lume/kiwi..Expression) - [new Expression(...args)](#new_module_@lume/kiwi..Expression_new) - [.plus(value)](#module_@lume/kiwi..Expression+plus) ⇒ Expression - [.minus(value)](#module_@lume/kiwi..Expression+minus) ⇒ Expression - [.multiply(coefficient)](#module_@lume/kiwi..Expression+multiply) ⇒ Expression - [.divide(coefficient)](#module_@lume/kiwi..Expression+divide) ⇒ Expression - [~Strength](#module_@lume/kiwi..Strength) - _instance_ - [.required](#module_@lume/kiwi..Strength+required) - [.strong](#module_@lume/kiwi..Strength+strong) - [.medium](#module_@lume/kiwi..Strength+medium) - [.weak](#module_@lume/kiwi..Strength+weak) - _static_ - [.create(a, b, c, [w])](#module_@lume/kiwi..Strength.create) ⇒ - [~Constraint](#module_@lume/kiwi..Constraint) - [new Constraint(expression, operator, [rhs], [strength])](#new_module_@lume/kiwi..Constraint_new) - [.expression()](#module_@lume/kiwi..Constraint+expression) ⇒ Expression - [.op()](#module_@lume/kiwi..Constraint+op) ⇒ Operator - [.strength()](#module_@lume/kiwi..Constraint+strength) ⇒ Number - [~Solver](#module_@lume/kiwi..Solver) - [new Solver()](#new_module_@lume/kiwi..Solver_new) - [.maxIterations](#module_@lume/kiwi..Solver+maxIterations) : number - [.createConstraint(lhs, operator, rhs, [strength])](#module_@lume/kiwi..Solver+createConstraint) - [.addConstraint(constraint)](#module_@lume/kiwi..Solver+addConstraint) - [.removeConstraint(constraint)](#module_@lume/kiwi..Solver+removeConstraint) - [.hasConstraint(constraint)](#module_@lume/kiwi..Solver+hasConstraint) ⇒ Bool - [.getConstraints()](#module_@lume/kiwi..Solver+getConstraints) ⇒ [ 'Array' ].<Constraint> - [.addEditVariable(variable, strength)](#module_@lume/kiwi..Solver+addEditVariable) - [.removeEditVariable(variable)](#module_@lume/kiwi..Solver+removeEditVariable) - [.hasEditVariable(variable)](#module_@lume/kiwi..Solver+hasEditVariable) ⇒ Bool - [.suggestValue(variable, value)](#module_@lume/kiwi..Solver+suggestValue) - [.updateVariables()](#module_@lume/kiwi..Solver+updateVariables) - [~Operator](#module_@lume/kiwi..Operator) : enum ## @lume/kiwi~Variable The primary user constraint variable. **Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi) - [~Variable](#module_@lume/kiwi..Variable) - [new Variable([name])](#new_module_@lume/kiwi..Variable_new) - [.name()](#module_@lume/kiwi..Variable+name) ⇒ String - [.setName(name)](#module_@lume/kiwi..Variable+setName) - [.value()](#module_@lume/kiwi..Variable+value) ⇒ Number - [.subscribe(callback)](#module_@lume/kiwi..Variable+subscribe) - [.unsubscribe()](#module_@lume/kiwi..Variable+unsubscribe) - [.plus(value)](#module_@lume/kiwi..Variable+plus) ⇒ Expression - [.minus(value)](#module_@lume/kiwi..Variable+minus) ⇒ Expression - [.multiply(coefficient)](#module_@lume/kiwi..Variable+multiply) ⇒ Expression - [.divide(coefficient)](#module_@lume/kiwi..Variable+divide) ⇒ Expression ### new Variable([name]) | Param | Type | Default | Description | | ------ | ------------------- | ------------------------- | ----------------------------------------- | | [name] | String | "" | The name to associated with the variable. | ### variable.name() ⇒ String Returns the name of the variable. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: String - name of the variable ### variable.setName(name) Set the name of the variable. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) | Param | Type | Description | | ----- | ------------------- | -------------------- | | name | String | Name of the variable | ### variable.value() ⇒ Number Returns the value of the variable. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: Number - Calculated value ### variable.subscribe(callback) Set a callback for whenever the value changes. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) | Param | Type | Description | | -------- | --------------------- | ------------------------------------------- | | callback | function | to call whenever the variable value changes | ### variable.unsubscribe() Stops the variable from calling the callback when the variable value changes. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) ### variable.plus(value) ⇒ Expression Creates a new Expression by adding a number, variable or expression to the variable. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: Expression - expression | Param | Type | Description | | ----- | ----------------------------------------------------------------------- | ------------- | | value | Number \| Variable \| Expression | Value to add. | ### variable.minus(value) ⇒ Expression Creates a new Expression by substracting a number, variable or expression from the variable. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: Expression - expression | Param | Type | Description | | ----- | ----------------------------------------------------------------------- | ------------------- | | value | Number \| Variable \| Expression | Value to substract. | ### variable.multiply(coefficient) ⇒ Expression Creates a new Expression by multiplying with a fixed number. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: Expression - expression | Param | Type | Description | | ----------- | ------------------- | ----------------------------- | | coefficient | Number | Coefficient to multiply with. | ### variable.divide(coefficient) ⇒ Expression Creates a new Expression by dividing with a fixed number. **Kind**: instance method of [Variable](#module_@lume/kiwi..Variable) **Returns**: Expression - expression | Param | Type | Description | | ----------- | ------------------- | ------------------------- | | coefficient | Number | Coefficient to divide by. | ## @lume/kiwi~Expression An expression of variable terms and a constant. The constructor accepts an arbitrary number of parameters, each of which must be one of the following types: - number - Variable - Expression - 2-tuple of [number, Variable|Expression] The parameters are summed. The tuples are multiplied. **Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi) - [~Expression](#module_@lume/kiwi..Expression) - [new Expression(...args)](#new_module_@lume/kiwi..Expression_new) - [.plus(value)](#module_@lume/kiwi..Expression+plus) ⇒ Expression - [.minus(value)](#module_@lume/kiwi..Expression+minus) ⇒ Expression - [.multiply(coefficient)](#module_@lume/kiwi..Expression+multiply) ⇒ Expression - [.divide(coefficient)](#module_@lume/kiwi..Expression+divide) ⇒ Expression ### new Expression(...args) | Param | Type | | ------- | --------------------------------------------------------------------------------------------- | | ...args | number \| Variable \| Expression \| Array | ### expression.plus(value) ⇒ Expression Creates a new Expression by adding a number, variable or expression to the expression. **Kind**: instance method of [Expression](#module_@lume/kiwi..Expression) **Returns**: Expression - expression | Param | Type | Description | | ----- | ----------------------------------------------------------------------- | ------------- | | value | Number \| Variable \| Expression | Value to add. | ### expression.minus(value) ⇒ Expression Creates a new Expression by substracting a number, variable or expression from the expression. **Kind**: instance method of [Expression](#module_@lume/kiwi..Expression) **Returns**: Expression - expression | Param | Type | Description | | ----- | ----------------------------------------------------------------------- | ------------------- | | value | Number \| Variable \| Expression | Value to substract. | ### expression.multiply(coefficient) ⇒ Expression Creates a new Expression by multiplying with a fixed number. **Kind**: instance method of [Expression](#module_@lume/kiwi..Expression) **Returns**: Expression - expression | Param | Type | Description | | ----------- | ------------------- | ----------------------------- | | coefficient | Number | Coefficient to multiply with. | ### expression.divide(coefficient) ⇒ Expression Creates a new Expression by dividing with a fixed number. **Kind**: instance method of [Expression](#module_@lume/kiwi..Expression) **Returns**: Expression - expression | Param | Type | Description | | ----------- | ------------------- | ------------------------- | | coefficient | Number | Coefficient to divide by. | ## @lume/kiwi~Strength **Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi) - [~Strength](#module_@lume/kiwi..Strength) - _instance_ - [.required](#module_@lume/kiwi..Strength+required) - [.strong](#module_@lume/kiwi..Strength+strong) - [.medium](#module_@lume/kiwi..Strength+medium) - [.weak](#module_@lume/kiwi..Strength+weak) - _static_ - [.create(a, b, c, [w])](#module_@lume/kiwi..Strength.create) ⇒ ### strength.required The 'required' symbolic strength. **Kind**: instance property of [Strength](#module_@lume/kiwi..Strength) ### strength.strong The 'strong' symbolic strength. **Kind**: instance property of [Strength](#module_@lume/kiwi..Strength) ### strength.medium The 'medium' symbolic strength. **Kind**: instance property of [Strength](#module_@lume/kiwi..Strength) ### strength.weak The 'weak' symbolic strength. **Kind**: instance property of [Strength](#module_@lume/kiwi..Strength) ### Strength.create(a, b, c, [w]) ⇒ Create a new symbolic strength. **Kind**: static method of [Strength](#module_@lume/kiwi..Strength) **Returns**: strength | Param | Default | Description | | ----- | -------------- | ----------- | | a | | strong | | b | | medium | | c | | weak | | [w] | 1 | weight | ## @lume/kiwi~Constraint A linear constraint equation. A constraint equation is composed of an expression, an operator, and a strength. The RHS of the equation is implicitly zero. **Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi) - [~Constraint](#module_@lume/kiwi..Constraint) - [new Constraint(expression, operator, [rhs], [strength])](#new_module_@lume/kiwi..Constraint_new) - [.expression()](#module_@lume/kiwi..Constraint+expression) ⇒ Expression - [.op()](#module_@lume/kiwi..Constraint+op) ⇒ Operator - [.strength()](#module_@lume/kiwi..Constraint+strength) ⇒ Number ### new Constraint(expression, operator, [rhs], [strength]) | Param | Type | Default | Description | | ---------- | ----------------------- | ------------------------------ | ---------------------------------- | | expression | Expression | | The constraint expression (LHS). | | operator | Operator | | The equation operator. | | [rhs] | Expression | | Right hand side of the expression. | | [strength] | Number | Strength.required | The strength of the constraint. | ### constraint.expression() ⇒ Expression Returns the expression of the constraint. **Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint) **Returns**: Expression - expression ### constraint.op() ⇒ Operator Returns the relational operator of the constraint. **Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint) **Returns**: Operator - linear constraint operator ### constraint.strength() ⇒ Number Returns the strength of the constraint. **Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint) **Returns**: Number - strength ## @lume/kiwi~Solver The constraint solver class. **Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi) - [~Solver](#module_@lume/kiwi..Solver) - [new Solver()](#new_module_@lume/kiwi..Solver_new) - [.maxIterations](#module_@lume/kiwi..Solver+maxIterations) : number - [.createConstraint(lhs, operator, rhs, [strength])](#module_@lume/kiwi..Solver+createConstraint) - [.addConstraint(constraint)](#module_@lume/kiwi..Solver+addConstraint) - [.removeConstraint(constraint)](#module_@lume/kiwi..Solver+removeConstraint) - [.hasConstraint(constraint)](#module_@lume/kiwi..Solver+hasConstraint) ⇒ Bool - [.getConstraints()](#module_@lume/kiwi..Solver+getConstraints) ⇒ [ 'Array' ].<Constraint> - [.addEditVariable(variable, strength)](#module_@lume/kiwi..Solver+addEditVariable) - [.removeEditVariable(variable)](#module_@lume/kiwi..Solver+removeEditVariable) - [.hasEditVariable(variable)](#module_@lume/kiwi..Solver+hasEditVariable) ⇒ Bool - [.suggestValue(variable, value)](#module_@lume/kiwi..Solver+suggestValue) - [.updateVariables()](#module_@lume/kiwi..Solver+updateVariables) ### new Solver() Construct a new Solver. ### solver.maxIterations : number - The max number of solver iterations before an erroris thrown, in order to prevent infinite iteration. Default: `10,000`. **Kind**: instance property of [Solver](#module_@lume/kiwi..Solver) ### solver.createConstraint(lhs, operator, rhs, [strength]) Creates and add a constraint to the solver. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Default | Description | | ---------- | ----------------------------------------------------------------------- | ------------------------------ | --------------------------------- | | lhs | Expression \| Variable | | Left hand side of the expression | | operator | Operator | | Operator | | rhs | Expression \| Variable \| Number | | Right hand side of the expression | | [strength] | Number | Strength.required | Strength | ### solver.addConstraint(constraint) Add a constraint to the solver. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Description | | ---------- | ----------------------- | ------------------------------- | | constraint | Constraint | Constraint to add to the solver | ### solver.removeConstraint(constraint) Remove a constraint from the solver. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Description | | ---------- | ----------------------- | ------------------------------------ | | constraint | Constraint | Constraint to remove from the solver | ### solver.hasConstraint(constraint) ⇒ Bool Test whether the solver contains the constraint. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) **Returns**: Bool - true or false | Param | Type | Description | | ---------- | ----------------------- | ---------------------- | | constraint | Constraint | Constraint to test for | ### solver.getConstraints() ⇒ [ 'Array' ].<Constraint> Get an array of the current constraints. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) ### solver.addEditVariable(variable, strength) Add an edit variable to the solver. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Description | | -------- | --------------------- | ------------------------------------------------- | | variable | Variable | Edit variable to add to the solver | | strength | Number | Strength, should be less than `Strength.required` | ### solver.removeEditVariable(variable) Remove an edit variable from the solver. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Description | | -------- | --------------------- | --------------------------------------- | | variable | Variable | Edit variable to remove from the solver | ### solver.hasEditVariable(variable) ⇒ Bool Test whether the solver contains the edit variable. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) **Returns**: Bool - true or false | Param | Type | Description | | -------- | --------------------- | ------------------------- | | variable | Variable | Edit variable to test for | ### solver.suggestValue(variable, value) Suggest the value of an edit variable. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) | Param | Type | Description | | -------- | --------------------- | ------------------------------------ | | variable | Variable | Edit variable to suggest a value for | | value | Number | Suggested value | ### solver.updateVariables() Update the values of the variables. **Kind**: instance method of [Solver](#module_@lume/kiwi..Solver) ## @lume/kiwi~Operator : enum An enum defining the linear constraint operators. | Value | Operator | Description | | ----- | -------- | ------------------ | | `Le` | <= | Less than equal | | `Ge` | >= | Greater than equal | | `Eq` | == | Equal | **Kind**: inner enum of [@lume/kiwi](#module_@lume/kiwi)