import { Equatable } from "@siteimprove/alfa-equatable" ; import { Hash , Hashable } from "@siteimprove/alfa-hash" ; import { Serializable } from "@siteimprove/alfa-json" ; import { Option , None } from "@siteimprove/alfa-option" ; import { Parser } from "@siteimprove/alfa-parser" ; import { Slice } from "@siteimprove/alfa-slice" ; import * as json from "@siteimprove/alfa-json" ; import { Token } from "../syntax/token" ; import { Color } from "./color" ; import { Length } from "./length" ; import { Percentage } from "./percentage" ; import { Linear , Radial } from ".." ; const { either , pair , map , option , oneOrMore , delimited , left , right } = Parser ; /**
 *  https public export type Gradient = Linear | Radial ; public export namespace Gradient { export type JSON = Linear . JSON | Radial . JSON ; /**
     *  https export class Stop < C extends Color = Color , P extends Length | Percentage = Length | Percentage > implements Equatable , Hashable , Serializable { public static of < C extends Color , P extends Length | Percentage > ( color , position = None ) { return new Stop ( color , position ) ; } private readonly _color : C ; private readonly _position : Option < P > ; private constructor ( color , position ) { this . _color = color ; this . _position = position ; } public get type ( ) : "stop" { return "stop" ; } public get color ( ) : C { return this . _color ; } public get position ( ) : Option < P > { return this . _position ; } public equals ( value ) { return ( value instanceof Stop && value . _color . equals ( this . _color ) && value . _position . equals ( this . _position ) ) ; } public hash ( hash ) { hash . writeHashable ( this . _color ) . writeHashable ( this . _position ) ; } public toJSON ( ) { return { type : "stop" , color : this . _color . toJSON ( ) , position : this . _position . map ( ( position ) => position . toJSON ( ) ) . getOr ( null ) , } ; } public toString ( ) { return `${ this . _color }${ this . _position . map ( ( position ) => ` ${ position }` ) . getOr ( "" ) }` ; } } export namespace Stop { export interface JSON { [ key ] : json . JSON ; type : "stop" ; color : Color . JSON ; position : Length . JSON | Percentage . JSON | null ; } } /**
     *  https export const parseStop = either ( map ( pair ( left ( Color . parse , Token . parseWhitespace ) , either ( Length . parse , Percentage . parse ) ) , ( result ) => { const [ color , position ] = result ; return Stop . of ( color , Option . of ( position ) ) ; } ) , map ( pair ( either ( Length . parse , Percentage . parse ) , right ( Token . parseWhitespace , Color . parse ) ) , ( result ) => { const [ position , color ] = result ; return Stop . of ( color , Option . of ( position ) ) ; } ) , map ( Color . parse , ( color ) => Stop . of ( color ) ) ) ; /**
     *  https export class Hint < P extends Length | Percentage = Length | Percentage > implements Equatable , Hashable , Serializable { public static of < P extends Length | Percentage > ( position ) { return new Hint ( position ) ; } private readonly _position : P ; private constructor ( position ) { this . _position = position ; } public get type ( ) : "hint" { return "hint" ; } public get position ( ) : P { return this . _position ; } public equals ( value ) { return value instanceof Hint && value . _position . equals ( this . _position ) ; } public hash ( hash ) { hash . writeHashable ( this . _position ) ; } public toJSON ( ) { return { type : "hint" , position : this . _position . toJSON ( ) , } ; } public toString ( ) { return `${ this . _position }` ; } } export namespace Hint { export interface JSON { [ key ] : json . JSON ; type : "hint" ; position : Length . JSON | Percentage . JSON ; } } /**
     *  https export const parseHint = map ( either ( Length . parse , Percentage . parse ) , ( position ) => Hint . of ( position ) ) ; export type Item = Stop | Hint ; export namespace Item { export type JSON = Stop . JSON | Hint . JSON ; } export const parseItem = either ( parseStop , parseHint ) ; /**
     *  https export const parseItemList = map ( pair ( parseStop , oneOrMore ( right ( delimited ( option ( Token . parseWhitespace ) , Token . parseComma ) , pair ( option ( left ( parseHint , delimited ( option ( Token . parseWhitespace ) , Token . parseComma ) ) ) , parseStop ) ) ) ) , ( [ first , rest ] ) => { const items = [ first ] ; for ( const [ hint , stop ] of rest ) { items . push ( ... hint , stop ) ; } return items ; } ) ; /**
     *  https export const parse = ( input ) => either ( Linear . parse , Radial . parse ) ( input ) ; }