function getIndentationForNodeWorker(
            current: Node,
            currentStart: LineAndCharacter,
            ignoreActualIndentationRange: TextRange,
            indentationDelta: number,
            sourceFile: SourceFile,
            isNextChild: boolean,
            options: EditorSettings): number {
            let parent = current.parent!;
            // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if
            // * parent and child nodes start on the same line, or
            // * parent is an IfStatement and child starts on the same line as an 'else clause'.
            while (parent) {
                let useActualIndentation = true;
                if (ignoreActualIndentationRange) {
                    const start = current.getStart(sourceFile);
                    useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
                }

                if (useActualIndentation) {
                    // check if current node is a list item - if yes, take indentation from it
                    const actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
                    if (actualIndentation !== Value.Unknown) {
                        return actualIndentation + indentationDelta;
                    }
                }

                const containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile);
                const parentAndChildShareLine =
                    containingListOrParentStart.line === currentStart.line ||
                    childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);

                if (useActualIndentation) {
                    // try to fetch actual indentation for current node from source text
                    let actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
                    if (actualIndentation !== Value.Unknown) {
                        return actualIndentation + indentationDelta;
                    }
                    actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options);
                    if (actualIndentation !== Value.Unknown) {
                        return actualIndentation + indentationDelta;
                    }
                }

                // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
                if (shouldIndentChildNode(parent, current, isNextChild) && !parentAndChildShareLine) {
                    indentationDelta += options.indentSize;
                }

                // In our AST, a call argument's `parent` is the call-expression, not the argument list.
                // We would like to increase indentation based on the relationship between an argument and its argument-list,
                // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list.
                // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression
                // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation.
                //
                // Instead, when at an argument, we unspoof the starting position of the enclosing call expression
                // *after* applying indentation for the argument.

                const useTrueStart =
                    isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile);

                current = parent;
                parent = current.parent;
                currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart(sourceFile)) : containingListOrParentStart;
            }

            return indentationDelta + getBaseIndentation(options);
        }


function getContainingListOrParentStart(parent: Node, child: Node, sourceFile: SourceFile): LineAndCharacter {
            const containingList = getContainingList(child, sourceFile);
            const startPos = containingList ? containingList.pos : parent.getStart(sourceFile);
            return sourceFile.getLineAndCharacterOfPosition(startPos);
        }


/*
         * Function returns Value.Unknown if indentation cannot be determined
         */
function getActualIndentationForListItemBeforeComma(commaToken: Node, sourceFile: SourceFile, options: EditorSettings): number {
            // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
            const commaItemInfo = findListItemInfo(commaToken);
            if (commaItemInfo && commaItemInfo.listItemIndex > 0) {
                return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
            }
            else {
                // handle broken code gracefully
                return Value.Unknown;
            }
        }


/*
         * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression)
         */
function getActualIndentationForNode(current: Node,
            parent: Node,
            currentLineAndChar: LineAndCharacter,
            parentAndChildShareLine: boolean,
            sourceFile: SourceFile,
            options: EditorSettings): number {

            // actual indentation is used for statements\declarations if one of cases below is true:
            // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
            // - parent and child are not on the same line
            const useActualIndentation =
                (isDeclaration(current) || isStatementButNotDeclaration(current)) &&
                (parent.kind === SyntaxKind.SourceFile || !parentAndChildShareLine);

            if (!useActualIndentation) {
                return Value.Unknown;
            }

            return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
        }


function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): NextTokenKind {
            const nextToken = findNextToken(precedingToken, current);
            if (!nextToken) {
                return NextTokenKind.Unknown;
            }

            if (nextToken.kind === SyntaxKind.OpenBraceToken) {
                // open braces are always indented at the parent level
                return NextTokenKind.OpenBrace;
            }
            else if (nextToken.kind === SyntaxKind.CloseBraceToken) {
                // close braces are indented at the parent level if they are located on the same line with cursor
                // this means that if new line will be added at $ position, this case will be indented
                // class A {
                //    $
                // }
                /// and this one - not
                // class A {
                // $}

                const nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
                return lineAtPosition === nextTokenStartLine ? NextTokenKind.CloseBrace : NextTokenKind.Unknown;
            }

            return NextTokenKind.Unknown;
        }


function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFileLike): LineAndCharacter {
            return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
        }


export function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFileLike): boolean {
            if (!(isCallExpression(parent) && contains(parent.arguments, child))) {
                return false;
            }

            const expressionOfCallExpressionEnd = parent.expression.getEnd();
            const expressionOfCallExpressionEndLine = getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line;
            return expressionOfCallExpressionEndLine === childStartLine;
        }


export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean {
            if (parent.kind === SyntaxKind.IfStatement && (<IfStatement>parent).elseStatement === child) {
                const elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile);
                Debug.assert(elseKeyword !== undefined);

                const elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                return elseKeywordStartLine === childStartLine;
            }

            return false;
        }


function getListIfStartEndIsInListRange(list: NodeArray<Node>, start: number, end: number) {
            return list && rangeContainsStartEnd(list, start, end) ? list : undefined;
        }


export function getContainingList(node: Node, sourceFile: SourceFile): NodeArray<Node> {
            if (node.parent) {
                switch (node.parent.kind) {
                    case SyntaxKind.TypeReference:
                        return getListIfStartEndIsInListRange((<TypeReferenceNode>node.parent).typeArguments, node.getStart(sourceFile), node.getEnd());
                    case SyntaxKind.ObjectLiteralExpression:
                        return (<ObjectLiteralExpression>node.parent).properties;
                    case SyntaxKind.ArrayLiteralExpression:
                        return (<ArrayLiteralExpression>node.parent).elements;
                    case SyntaxKind.FunctionDeclaration:
                    case SyntaxKind.FunctionExpression:
                    case SyntaxKind.ArrowFunction:
                    case SyntaxKind.MethodDeclaration:
                    case SyntaxKind.MethodSignature:
                    case SyntaxKind.CallSignature:
                    case SyntaxKind.Constructor:
                    case SyntaxKind.ConstructorType:
                    case SyntaxKind.ConstructSignature: {
                        const start = node.getStart(sourceFile);
                        return getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).typeParameters, start, node.getEnd()) ||
                            getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).parameters, start, node.getEnd());
                    }
                    case SyntaxKind.ClassDeclaration:
                        return getListIfStartEndIsInListRange((<ClassDeclaration>node.parent).typeParameters, node.getStart(sourceFile), node.getEnd());
                    case SyntaxKind.NewExpression:
                    case SyntaxKind.CallExpression: {
                        const start = node.getStart(sourceFile);
                        return getListIfStartEndIsInListRange((<CallExpression>node.parent).typeArguments, start, node.getEnd()) ||
                            getListIfStartEndIsInListRange((<CallExpression>node.parent).arguments, start, node.getEnd());
                    }
                    case SyntaxKind.VariableDeclarationList:
                        return getListIfStartEndIsInListRange((<VariableDeclarationList>node.parent).declarations, node.getStart(sourceFile), node.getEnd());
                    case SyntaxKind.NamedImports:
                    case SyntaxKind.NamedExports:
                        return getListIfStartEndIsInListRange((<NamedImportsOrExports>node.parent).elements, node.getStart(sourceFile), node.getEnd());
                }
            }
            return undefined;
        }


function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorSettings): number {
            const containingList = getContainingList(node, sourceFile);
            if (containingList) {
                const index = containingList.indexOf(node);
                if (index !== -1) {
                    return deriveActualIndentationFromList(containingList, index, sourceFile, options);
                }
            }
            return Value.Unknown;
        }


function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorSettings): number {
            // actual indentation should not be used when:
            // - node is close parenthesis - this is the end of the expression
            if (node.kind === SyntaxKind.CloseParenToken) {
                return Value.Unknown;
            }

            if (node.parent && isCallOrNewExpression(node.parent) && node.parent.expression !== node) {
                const fullCallOrNewExpression = node.parent.expression;
                const startingExpression = getStartingExpression(fullCallOrNewExpression);

                if (fullCallOrNewExpression === startingExpression) {
                    return Value.Unknown;
                }

                const fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end);
                const startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end);

                if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) {
                    return Value.Unknown;
                }

                return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options);
            }

            return Value.Unknown;

            function getStartingExpression(node: Expression) {
                while (true) {
                    switch (node.kind) {
                        case SyntaxKind.CallExpression:
                        case SyntaxKind.NewExpression:
                        case SyntaxKind.PropertyAccessExpression:
                        case SyntaxKind.ElementAccessExpression:
                            node = (<PropertyAccessExpression | CallExpression | NewExpression | ElementAccessExpression | PropertyAccessExpression>node).expression;
                            break;
                        default:
                            return node;
                    }
                }
            }
        }


function getStartingExpression(node: Expression) {
                while (true) {
                    switch (node.kind) {
                        case SyntaxKind.CallExpression:
                        case SyntaxKind.NewExpression:
                        case SyntaxKind.PropertyAccessExpression:
                        case SyntaxKind.ElementAccessExpression:
                            node = (<PropertyAccessExpression | CallExpression | NewExpression | ElementAccessExpression | PropertyAccessExpression>node).expression;
                            break;
                        default:
                            return node;
                    }
                }
            }


function deriveActualIndentationFromList(list: ReadonlyArray<Node>, index: number, sourceFile: SourceFile, options: EditorSettings): number {
            Debug.assert(index >= 0 && index < list.length);
            const node = list[index];

            // walk toward the start of the list starting from current node and check if the line is the same for all items.
            // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
            let lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
            for (let i = index - 1; i >= 0; i--) {
                if (list[i].kind === SyntaxKind.CommaToken) {
                    continue;
                }
                // skip list items that ends on the same line with the current list element
                const prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line;
                if (prevEndLine !== lineAndCharacter.line) {
                    return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
                }

                lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
            }
            return Value.Unknown;
        }


function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter: LineAndCharacter, sourceFile: SourceFile, options: EditorSettings): number {
            const lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0);
            return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
        }


/**
         * Character is the actual index of the character since the beginning of the line.
         * Column - position of the character after expanding tabs to spaces.
         * "0\t2$"
         * value of 'character' for '$' is 3
         * value of 'column' for '$' is 6 (assuming that tab size is 4)
         */
export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings) {
            let character = 0;
            let column = 0;
            for (let pos = startPos; pos < endPos; pos++) {
                const ch = sourceFile.text.charCodeAt(pos);
                if (!isWhiteSpaceSingleLine(ch)) {
                    break;
                }

                if (ch === CharacterCodes.tab) {
                    column += options.tabSize + (column % options.tabSize);
                }
                else {
                    column++;
                }

                character++;
            }
            return { column, character };
        }


export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings): number {
            return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column;
        }


function nodeContentIsAlwaysIndented(kind: SyntaxKind): boolean {
            switch (kind) {
                case SyntaxKind.ExpressionStatement:
                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.ClassExpression:
                case SyntaxKind.InterfaceDeclaration:
                case SyntaxKind.EnumDeclaration:
                case SyntaxKind.TypeAliasDeclaration:
                case SyntaxKind.ArrayLiteralExpression:
                case SyntaxKind.Block:
                case SyntaxKind.ModuleBlock:
                case SyntaxKind.ObjectLiteralExpression:
                case SyntaxKind.TypeLiteral:
                case SyntaxKind.MappedType:
                case SyntaxKind.TupleType:
                case SyntaxKind.CaseBlock:
                case SyntaxKind.DefaultClause:
                case SyntaxKind.CaseClause:
                case SyntaxKind.ParenthesizedExpression:
                case SyntaxKind.PropertyAccessExpression:
                case SyntaxKind.CallExpression:
                case SyntaxKind.NewExpression:
                case SyntaxKind.VariableStatement:
                case SyntaxKind.VariableDeclaration:
                case SyntaxKind.ExportAssignment:
                case SyntaxKind.ReturnStatement:
                case SyntaxKind.ConditionalExpression:
                case SyntaxKind.ArrayBindingPattern:
                case SyntaxKind.ObjectBindingPattern:
                case SyntaxKind.JsxOpeningElement:
                case SyntaxKind.JsxOpeningFragment:
                case SyntaxKind.JsxSelfClosingElement:
                case SyntaxKind.JsxExpression:
                case SyntaxKind.MethodSignature:
                case SyntaxKind.CallSignature:
                case SyntaxKind.ConstructSignature:
                case SyntaxKind.Parameter:
                case SyntaxKind.FunctionType:
                case SyntaxKind.ConstructorType:
                case SyntaxKind.ParenthesizedType:
                case SyntaxKind.TaggedTemplateExpression:
                case SyntaxKind.AwaitExpression:
                case SyntaxKind.NamedExports:
                case SyntaxKind.NamedImports:
                case SyntaxKind.ExportSpecifier:
                case SyntaxKind.ImportSpecifier:
                case SyntaxKind.PropertyAssignment:
                case SyntaxKind.PropertyDeclaration:
                    return true;
            }
            return false;
        }


export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind | undefined, indentByDefault: boolean): boolean {
            const childKind = child ? child.kind : SyntaxKind.Unknown;
            switch (parent.kind) {
                case SyntaxKind.DoStatement:
                case SyntaxKind.WhileStatement:
                case SyntaxKind.ForInStatement:
                case SyntaxKind.ForOfStatement:
                case SyntaxKind.ForStatement:
                case SyntaxKind.IfStatement:
                case SyntaxKind.FunctionDeclaration:
                case SyntaxKind.FunctionExpression:
                case SyntaxKind.MethodDeclaration:
                case SyntaxKind.ArrowFunction:
                case SyntaxKind.Constructor:
                case SyntaxKind.GetAccessor:
                case SyntaxKind.SetAccessor:
                    return childKind !== SyntaxKind.Block;
                case SyntaxKind.ExportDeclaration:
                    return childKind !== SyntaxKind.NamedExports;
                case SyntaxKind.ImportDeclaration:
                    return childKind !== SyntaxKind.ImportClause ||
                        (!!(<ImportClause>child).namedBindings && (<ImportClause>child).namedBindings.kind !== SyntaxKind.NamedImports);
                case SyntaxKind.JsxElement:
                    return childKind !== SyntaxKind.JsxClosingElement;
                case SyntaxKind.JsxFragment:
                    return childKind !== SyntaxKind.JsxClosingFragment;
            }
            // No explicit rule for given nodes so the result will follow the default value argument
            return indentByDefault;
        }


function isControlFlowEndingStatement(kind: SyntaxKind, parent: TextRangeWithKind): boolean {
            switch (kind) {
                case SyntaxKind.ReturnStatement:
                case SyntaxKind.ThrowStatement: {
                    if (parent.kind !== SyntaxKind.Block) {
                        return true;
                    }
                    const grandParent = (parent as Node).parent;
                    // In a function, we may want to write inner functions after this.
                    return !(grandParent && grandParent.kind === SyntaxKind.FunctionExpression || grandParent.kind === SyntaxKind.FunctionDeclaration);
                }
                case SyntaxKind.ContinueStatement:
                case SyntaxKind.BreakStatement:
                    return true;
                default:
                    return false;
            }
        }


/**
         * True when the parent node should indent the given child by an explicit rule.
         * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child.
         */
export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind, isNextChild = false): boolean {
            return (nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false))
                && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent));
        }


const enum Value {
            Unknown = -1
        }


const enum NextTokenKind {
            Unknown,
            OpenBrace,
            CloseBrace
        }


(props: AppProps) => {
  return (

          <Link to="/">主页</Link>

          <Link to="/url">url管理</Link>

          <Link to="/style">样式管理</Link>

      {/* 路由解析,传递参数 */}
      <Route path="/url" component={()


interface AppProps {
  data:ExtensionData;
  actions:ExtensionActions;
}


interface AppState {}


export function Distance({ distance }: Props) {
  const [settings] = useSettings();
  switch (settings.units) {
    case "imperial": {
      const value = distance / 1.609;
      if (value < 0.3) {
        return <>{formatNoDigits.format(value * 5280)}ft</>;
      } else {
        return <>{formatDigits.format(value)}mi</>;
      }
    }
    case "metric": {
      if (distance < 1) {
        return <>{formatNoDigits.format(distance * 1000)}m</>;
      } else {
        return <>{formatDigits.format(distance)}km</>;
      }
    }
  }
}


interface Props {
  distance: number;
}


async () => {
    // Open the CLI
    cli();
}


export interface IPaginatorResponse {
  page: number;
  take: number;
  totalCount: number;
}


export interface IDataItemResponse {
  id: number;
  firstName: string;
  lastName: string;
  gender: GenderEnum;
  result: number;
  distance: number;
  speed: number;
  birthDate: Date;
  isFinished: boolean;
}


export interface IDataResponse {
  items: IDataItemResponse[];
  displayed: IDataItemResponse[];
  paginator: IPaginatorResponse;
}


export enum GenderEnum {
  Male = 'male',
  Female = 'female',
}


(): [(post: TextilePost[]) => void, {
    error: Error | null;
    loading: boolean;
}] => {
	const { thread, client } = useTextile();

	const [loading, setLoading] = useState(false);
	const [error, setError] = useState<Error | null>(null);

	const editPost = useCallback((post: TextilePost[]) => {
		if (!client){
			return;
		}

		setLoading(true);
		setError(null);

		client.save(thread, textileCollection.POST, post)
			.catch(error => setError(error))
			.finally(() => setLoading(false));
	},[client, thread]);

	return [
		editPost,
		{
			error,
			loading
		}
	];
}


(post: TextilePost[]) => {
		if (!client){
			return;
		}

		setLoading(true);
		setError(null);

		client.save(thread, textileCollection.POST, post)
			.catch(error => setError(error))
			.finally(() => setLoading(false));
	}


error => setError(error)


() => setLoading(false)


/**
 * @class
 */
@EdmMapping.entityType('RegisterCandidateAction')
class RegisterCandidateAction extends RegisterAction {

  public electionEvent: ElectionEvent | any;
  public agreeTerms?: boolean;
  public agreeData?: boolean;
  public shareEmail?: boolean;
  public id?: number;
  /**
   * @constructor
   */
  constructor() {
    super();
  }
}


export interface DialogResult {
    confirmed?: boolean;
    prompt?: string;

    [k: string]: any;
}


export default function TechCommApp ({ basePath, className }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const { api } = useApi();
  const members = useCall<AccountId[]>(api.query.technicalCommittee.members, []);
  const proposals = useCall<Hash[]>(api.query.technicalCommittee.proposals, []);
  const items = useMemo(() => [
    {
      isRoot: true,
      name: 'overview',
      text: t('Tech. committee')
    },
    {
      name: 'proposals',
      text: t('Proposals ({{count}})', { replace: { count: (proposals && proposals.length) || 0 } })
    }
  ], [proposals, t]);

  return (
    <main className={className}>
      <header>
        <Tabs
          basePath={basePath}
          items={items}
        />
      </header>
      <Switch>
        <Route path={`${basePath}/proposals`}>
          <Proposals
            members={members}
            proposals={proposals}
          />
        </Route>
        <Route path={basePath}>
          <Overview
            members={members}
            proposals={proposals}
          />
        </Route>
      </Switch>
    </main>
  );
}


() => [
    {
      isRoot: true,
      name: 'overview',
      text: t('Tech. committee')
    },
    {
      name: 'proposals',
      text: t('Proposals ({{count}})', { replace: { count: (proposals && proposals.length) || 0 } })
    }
  ]


interface Props extends AppProps, BareProps {}


@Component({
    selector: "dismiss-button",
    template: template
})
export class DismissButton {
    public readonly label: ko.Observable<string>;
    public readonly styles: ko.Observable<StyleModel>;
    public readonly icon: ko.Observable<string>;

    constructor() {
        this.label = ko.observable<string>("DismissButton");
        this.styles = ko.observable<StyleModel>();
        this.icon = ko.observable<string>();
    }
}


() => {
  it('should return 0 on empty shape', () => {
    expect(getSize([])).toBe(0);
  });

  it('should return the first entry on shape of length 1', () => {
    expect(getSize([5])).toBe(5);
    expect(getSize([8])).toBe(8);
    expect(getSize([22])).toBe(22);
    expect(getSize([33])).toBe(33);
  });

  it('should compute the product of the shape', () => {
    expect(getSize([5, 10, 3])).toBe(5 * 10 * 3);
    expect(getSize([2, 33, 1])).toBe(2 * 33 * 1);
    expect(getSize([8, 7, 6])).toBe(8 * 7 * 6);
  });
}


() => {
    expect(getSize([])).toBe(0);
  }


() => {
    expect(getSize([5])).toBe(5);
    expect(getSize([8])).toBe(8);
    expect(getSize([22])).toBe(22);
    expect(getSize([33])).toBe(33);
  }


() => {
    expect(getSize([5, 10, 3])).toBe(5 * 10 * 3);
    expect(getSize([2, 33, 1])).toBe(2 * 33 * 1);
    expect(getSize([8, 7, 6])).toBe(8 * 7 * 6);
  }


() => {
  it('should return an array of the same length', () => {
    expect(computeStrides([]).length).toBe(0);
    expect(computeStrides([1, 2, 3]).length).toBe(3);
    expect(computeStrides([1, 2, 3, 4, 5, 6]).length).toBe(6);
    expect(computeStrides([1, 2, 3, 4, 5, 6, 7, 8, 9]).length).toBe(9);
  });

  it('should work for rank 1', () => {
    expect(computeStrides([5])).toEqual([1]);
    expect(computeStrides([22])).toEqual([1]);
    expect(computeStrides([33])).toEqual([1]);
  });

  it('should ignore the first entry', () => {
    expect(computeStrides([5, 2, 3])).toEqual([6, 3, 1]);
    expect(computeStrides([22, 2, 3])).toEqual([6, 3, 1]);
    expect(computeStrides([31, 2, 3])).toEqual([6, 3, 1]);
  });
}


() => {
    expect(computeStrides([]).length).toBe(0);
    expect(computeStrides([1, 2, 3]).length).toBe(3);
    expect(computeStrides([1, 2, 3, 4, 5, 6]).length).toBe(6);
    expect(computeStrides([1, 2, 3, 4, 5, 6, 7, 8, 9]).length).toBe(9);
  }


() => {
    expect(computeStrides([5])).toEqual([1]);
    expect(computeStrides([22])).toEqual([1]);
    expect(computeStrides([33])).toEqual([1]);
  }


() => {
    expect(computeStrides([5, 2, 3])).toEqual([6, 3, 1]);
    expect(computeStrides([22, 2, 3])).toEqual([6, 3, 1]);
    expect(computeStrides([31, 2, 3])).toEqual([6, 3, 1]);
  }


() => {
  it('should return 0 for rank 0', () => {
    const shape: number[] = [];
    const strides = computeStrides(shape);

    expect(indexToPos([], strides)).toBe(0);
  });

  it('should return the index for rank 1', () => {
    const shape = [22];
    const strides = computeStrides(shape);

    expect(indexToPos([1], strides)).toBe(1);
    expect(indexToPos([5], strides)).toBe(5);
    expect(indexToPos([21], strides)).toBe(21);
  });

  it('should work for higher ranks', () => {
    const shape = [4, 3, 2];
    const strides = computeStrides(shape);

    expect(indexToPos([0, 1, 1], strides)).toBe(3);
    expect(indexToPos([1, 0, 1], strides)).toBe(7);
    expect(indexToPos([2, 2, 1], strides)).toBe(17);
    expect(indexToPos([3, 2, 1], strides)).toBe(23);
  });
}


() => {
    const shape: number[] = [];
    const strides = computeStrides(shape);

    expect(indexToPos([], strides)).toBe(0);
  }


() => {
    const shape = [22];
    const strides = computeStrides(shape);

    expect(indexToPos([1], strides)).toBe(1);
    expect(indexToPos([5], strides)).toBe(5);
    expect(indexToPos([21], strides)).toBe(21);
  }


() => {
    const shape = [4, 3, 2];
    const strides = computeStrides(shape);

    expect(indexToPos([0, 1, 1], strides)).toBe(3);
    expect(indexToPos([1, 0, 1], strides)).toBe(7);
    expect(indexToPos([2, 2, 1], strides)).toBe(17);
    expect(indexToPos([3, 2, 1], strides)).toBe(23);
  }


() => {
  it('should return empty vector for rank 0', () => {
    const shape: number[] = [];
    const strides = computeStrides(shape);

    expect(posToIndex(0, strides)).toEqual([]);
  });

  it('should return the index for rank 1', () => {
    const shape = [22];
    const strides = computeStrides(shape);

    expect(posToIndex(1, strides)).toEqual([1]);
    expect(posToIndex(5, strides)).toEqual([5]);
    expect(posToIndex(21, strides)).toEqual([21]);
  });

  it('should work for higher ranks', () => {
    const shape = [4, 3, 2];
    const strides = computeStrides(shape);

    expect(posToIndex(3, strides)).toEqual([0, 1, 1]);
    expect(posToIndex(7, strides)).toEqual([1, 0, 1]);
    expect(posToIndex(17, strides)).toEqual([2, 2, 1]);
    expect(posToIndex(23, strides)).toEqual([3, 2, 1]);
  });
}


() => {
    const shape: number[] = [];
    const strides = computeStrides(shape);

    expect(posToIndex(0, strides)).toEqual([]);
  }


() => {
    const shape = [22];
    const strides = computeStrides(shape);

    expect(posToIndex(1, strides)).toEqual([1]);
    expect(posToIndex(5, strides)).toEqual([5]);
    expect(posToIndex(21, strides)).toEqual([21]);
  }


() => {
    const shape = [4, 3, 2];
    const strides = computeStrides(shape);

    expect(posToIndex(3, strides)).toEqual([0, 1, 1]);
    expect(posToIndex(7, strides)).toEqual([1, 0, 1]);
    expect(posToIndex(17, strides)).toEqual([2, 2, 1]);
    expect(posToIndex(23, strides)).toEqual([3, 2, 1]);
  }


() => {
  it('should return the pos for rank 1', () => {
    const shape = [22];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    incrementIndex(ix1, shape);

    const ix2 = posToIndex(5, strides);
    incrementIndex(ix2, shape);

    const ix3 = posToIndex(6, strides);
    incrementIndex(ix3, shape);

    expect(indexToPos(ix1, strides)).toEqual(2);
    expect(indexToPos(ix2, strides)).toEqual(6);
    expect(indexToPos(ix3, strides)).toEqual(7);
  });

  it('should work for higher ranks', () => {
    const shape = [2, 3, 4];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    incrementIndex(ix1, shape);
    expect(indexToPos(ix1, strides)).toEqual(2);

    const ix2 = posToIndex(3, strides);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(4);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(5);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(6);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(7);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(8);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(9);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(10);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(11);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(12);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(13);
  });
}


() => {
    const shape = [22];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    incrementIndex(ix1, shape);

    const ix2 = posToIndex(5, strides);
    incrementIndex(ix2, shape);

    const ix3 = posToIndex(6, strides);
    incrementIndex(ix3, shape);

    expect(indexToPos(ix1, strides)).toEqual(2);
    expect(indexToPos(ix2, strides)).toEqual(6);
    expect(indexToPos(ix3, strides)).toEqual(7);
  }


() => {
    const shape = [2, 3, 4];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    incrementIndex(ix1, shape);
    expect(indexToPos(ix1, strides)).toEqual(2);

    const ix2 = posToIndex(3, strides);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(4);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(5);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(6);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(7);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(8);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(9);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(10);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(11);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(12);
    incrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(13);
  }


() => {
  it('should return the pos for rank 1', () => {
    const shape = [22];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    decrementIndex(ix1, shape);

    const ix2 = posToIndex(5, strides);
    decrementIndex(ix2, shape);

    const ix3 = posToIndex(6, strides);
    decrementIndex(ix3, shape);

    expect(indexToPos(ix1, strides)).toEqual(0);
    expect(indexToPos(ix2, strides)).toEqual(4);
    expect(indexToPos(ix3, strides)).toEqual(5);
  });

  it('should work for higher ranks', () => {
    const shape = [2, 3, 4];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    decrementIndex(ix1, shape);
    expect(indexToPos(ix1, strides)).toEqual(0);

    const ix2 = posToIndex(13, strides);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(12);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(11);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(10);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(9);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(8);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(7);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(6);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(5);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(4);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(3);
  });
}


() => {
    const shape = [22];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    decrementIndex(ix1, shape);

    const ix2 = posToIndex(5, strides);
    decrementIndex(ix2, shape);

    const ix3 = posToIndex(6, strides);
    decrementIndex(ix3, shape);

    expect(indexToPos(ix1, strides)).toEqual(0);
    expect(indexToPos(ix2, strides)).toEqual(4);
    expect(indexToPos(ix3, strides)).toEqual(5);
  }


() => {
    const shape = [2, 3, 4];
    const strides = computeStrides(shape);

    const ix1 = posToIndex(1, strides);
    decrementIndex(ix1, shape);
    expect(indexToPos(ix1, strides)).toEqual(0);

    const ix2 = posToIndex(13, strides);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(12);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(11);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(10);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(9);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(8);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(7);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(6);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(5);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(4);
    decrementIndex(ix2, shape);
    expect(indexToPos(ix2, strides)).toEqual(3);
  }


export function Content({ movies, selectedGenre }: ContentProps) {
  return (

          Categoria: {selectedGenre.title}

            {movies.map(movie => (
              <MovieCard key ={movie.imdbID} title={movie.Title} poster={movie.Poster} runtime={movie.Runtime} rating={movie.Ratings[0].Value} />
            ))}

  )
}


movie => (
              <MovieCard key ={movie.imdbID}


interface GenreResponseProps {
  id: number;
  name: 'action' | 'comedy' | 'documentary' | 'drama' | 'horror' | 'family';
  title: string;
}


interface ContentProps {
  movies: MovieProps[],
  selectedGenre: GenreResponseProps;
}


function* g(): IterableIterator<Shrinkable<T | TNil>> {
      yield new Shrinkable(nil);
    }


/**
 * For either null or a value coming from `arb`
 *
 * @param arb - Arbitrary that will be called to generate a non null value
 *
 * @remarks Since 0.0.6
 * @public
 */
function option<T>(arb: Arbitrary<T>): Arbitrary<T | null>;


/**
 * For either null or a value coming from `arb` with custom frequency
 *
 * @param arb - Arbitrary that will be called to generate a non null value
 * @param freq - The probability to build a null value is of `1 / freq`
 *
 * @deprecated
 * Superceded by `fc.option(arb, {freq})` - see {@link https://github.com/dubzzz/fast-check/issues/992 | #992}.
 * Ease the migration with {@link https://github.com/dubzzz/fast-check/tree/main/codemods/unify-signatures | our codemod script}.
 *
 * @remarks Since 0.0.6
 * @public
 */
function option<T>(arb: Arbitrary<T>, freq: number): Arbitrary<T | null>;


/**
 * For either nil or a value coming from `arb` with custom frequency
 *
 * @param arb - Arbitrary that will be called to generate a non nil value
 * @param constraints - Constraints on the option
 *
 * @remarks Since 1.17.0
 * @public
 */
function option<T, TNil = null>(arb: Arbitrary<T>, constraints: OptionConstraints<TNil>): Arbitrary<T | TNil>;


function option<T, TNil>(arb: Arbitrary<T>, constraints?: number | OptionConstraints<TNil>): Arbitrary<T | TNil> {
  if (!constraints) return new OptionArbitrary(arb, 5, null as any);
  if (typeof constraints === 'number') return new OptionArbitrary(arb, constraints, null as any);

  return new OptionArbitrary(
    arb,
    constraints.freq == null ? 5 : constraints.freq,
    Object.prototype.hasOwnProperty.call(constraints, 'nil') ? constraints.nil : (null as any)
  );
}


() =>
      s
        .shrink()
        .map((v) => OptionArbitrary.extendedShrinkable(v, nil))
        .join(g())


(v) => OptionArbitrary.extendedShrinkable(v, nil)


/** @internal */
class OptionArbitrary<T, TNil> extends Arbitrary<T | TNil> {
  readonly isOptionArb: Arbitrary<number>;
  constructor(readonly arb: Arbitrary<T>, readonly frequency: number, readonly nil: TNil) {
    super();
    this.isOptionArb = nat(frequency); // 1 chance over <frequency> to have non nil
  }
  private static extendedShrinkable<T, TNil>(s: Shrinkable<T>, nil: TNil): Shrinkable<T | TNil> {
    function* g(): IterableIterator<Shrinkable<T | TNil>> {
      yield new Shrinkable(nil);
    }
    return new Shrinkable(s.value_ as T | TNil, () =>
      s
        .shrink()
        .map((v) => OptionArbitrary.extendedShrinkable(v, nil))
        .join(g())
    );
  }
  generate(mrng: Random): Shrinkable<T | TNil> {
    return this.isOptionArb.generate(mrng).value === 0
      ? new Shrinkable(this.nil)
      : OptionArbitrary.extendedShrinkable(this.arb.generate(mrng), this.nil);
  }
  withBias(freq: number) {
    return new OptionArbitrary(this.arb.withBias(freq), this.frequency, this.nil);
  }
}


/**
 * Constraints to be applied on {@link option}
 * @remarks Since 2.2.0
 * @public
 */
export interface OptionConstraints<TNil = null> {
  /**
   * The probability to build a nil value is of `1 / freq`
   * @remarks Since 1.17.0
   */
  freq?: number;
  /**
   * The nil value (default would be null)
   * @remarks Since 1.17.0
   */
  nil?: TNil;
}


private static extendedShrinkable<T, TNil>(s: Shrinkable<T>, nil: TNil): Shrinkable<T | TNil> {
    function* g(): IterableIterator<Shrinkable<T | TNil>> {
      yield new Shrinkable(nil);
    }
    return new Shrinkable(s.value_ as T | TNil, () =>
      s
        .shrink()
        .map((v) => OptionArbitrary.extendedShrinkable(v, nil))
        .join(g())
    );
  }


generate(mrng: Random): Shrinkable<T | TNil> {
    return this.isOptionArb.generate(mrng).value === 0
      ? new Shrinkable(this.nil)
      : OptionArbitrary.extendedShrinkable(this.arb.generate(mrng), this.nil);
  }


withBias(freq: number) {
    return new OptionArbitrary(this.arb.withBias(freq), this.frequency, this.nil);
  }


function resolveCommandHistory(configurationService: IConfigurationService): number {
	const config = <IWorkbenchQuickOpenConfiguration>configurationService.getValue();

	let commandHistory = config.workbench && config.workbench.commandPalette && config.workbench.commandPalette.history;
	if (typeof commandHistory !== 'number') {
		commandHistory = CommandsHistory.DEFAULT_COMMANDS_HISTORY_LENGTH;
	}

	return commandHistory;
}


(a, b) => a.value - b.value


entry => commandHistory.set(entry.key, entry.value)


e => this.updateConfiguration()


reason => this.save()


(value, key) => serializedCache.entries.push({ key, value })


() => {
			if (action && (!(action instanceof Action) || action.enabled)) {
				try {
					/* __GDPR__
						"workbenchActionExecuted" : {
							"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
							"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
						}
					*/
					this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'quick open' });
					(action.run() || TPromise.as(null)).done(() => {
						if (action instanceof Action) {
							action.dispose();
						}
					}, err => this.onError(err));
				} catch (error) {
					this.onError(error);
				}
			} else {
				this.notificationService.info(nls.localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel()));
			}
		}


() => {
						if (action instanceof Action) {
							action.dispose();
						}
					}


err => this.onError(err)


accessor => this.menuService.createMenu(MenuId.CommandPalette, accessor.get(IContextKeyService))


(r, [, actions]) => [...r, ...actions]


entry => `${entry.getLabel()}${entry.getGroupLabel()}${entry.getCommandId()}`


entry => {
			const commandLabel = `${entry.getLabel()}${entry.getGroupLabel()}`;
			if (commandLabels.has(commandLabel)) {
				entry.setDescription(entry.getCommandId());
			} else {
				commandLabels.add(commandLabel);
			}
		}


(elementA, elementB) => {
			const counterA = this.commandsHistory.peek(elementA.getCommandId());
			const counterB = this.commandsHistory.peek(elementB.getCommandId());

			if (counterA && counterB) {
				return counterA > counterB ? -1 : 1; // use more recently used command before older
			}

			if (counterA) {
				return -1; // first command was used, so it wins over the non used one
			}

			if (counterB) {
				return 1; // other command was used so it wins over the command
			}

			// both commands were never used, so we sort by name
			return elementA.getSortLabel().localeCompare(elementB.getSortLabel());
		}


(id: string) => this.onBeforeRunCommand(id)


class CommandsHistory {

	public static readonly DEFAULT_COMMANDS_HISTORY_LENGTH = 50;

	private static readonly PREF_KEY_CACHE = 'commandPalette.mru.cache';
	private static readonly PREF_KEY_COUNTER = 'commandPalette.mru.counter';

	private commandHistoryLength: number;

	constructor(
		@IStorageService private storageService: IStorageService,
		@ILifecycleService private lifecycleService: ILifecycleService,
		@IConfigurationService private configurationService: IConfigurationService
	) {
		this.updateConfiguration();
		this.load();

		this.registerListeners();
	}

	private updateConfiguration(): void {
		this.commandHistoryLength = resolveCommandHistory(this.configurationService);

		if (commandHistory) {
			commandHistory.limit = this.commandHistoryLength;
		}
	}

	private load(): void {
		const raw = this.storageService.get(CommandsHistory.PREF_KEY_CACHE);
		let serializedCache: ISerializedCommandHistory;
		if (raw) {
			try {
				serializedCache = JSON.parse(raw);
			} catch (error) {
				// invalid data
			}
		}

		commandHistory = new LRUCache<string, number>(this.commandHistoryLength, 1);
		if (serializedCache) {
			let entries: { key: string; value: number }[];
			if (serializedCache.usesLRU) {
				entries = serializedCache.entries;
			} else {
				entries = serializedCache.entries.sort((a, b) => a.value - b.value);
			}
			entries.forEach(entry => commandHistory.set(entry.key, entry.value));
		}
		commandCounter = this.storageService.getInteger(CommandsHistory.PREF_KEY_COUNTER, void 0, commandCounter);
	}

	private registerListeners(): void {
		this.configurationService.onDidChangeConfiguration(e => this.updateConfiguration());
		once(this.lifecycleService.onShutdown)(reason => this.save());
	}

	private save(): void {
		let serializedCache: ISerializedCommandHistory = { usesLRU: true, entries: [] };
		commandHistory.forEach((value, key) => serializedCache.entries.push({ key, value }));
		this.storageService.store(CommandsHistory.PREF_KEY_CACHE, JSON.stringify(serializedCache));
		this.storageService.store(CommandsHistory.PREF_KEY_COUNTER, commandCounter);
	}

	public push(commandId: string): void {
		// set counter to command
		commandHistory.set(commandId, commandCounter++);
	}

	public peek(commandId: string): number {
		return commandHistory.peek(commandId);
	}
}


export class ShowAllCommandsAction extends Action {

	public static readonly ID = 'workbench.action.showCommands';
	public static readonly LABEL = nls.localize('showTriggerActions', "Show All Commands");

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@IConfigurationService private configurationService: IConfigurationService
	) {
		super(id, label);
	}

	public run(context?: any): TPromise<void> {
		const config = <IWorkbenchQuickOpenConfiguration>this.configurationService.getValue();
		const restoreInput = config.workbench && config.workbench.commandPalette && config.workbench.commandPalette.preserveInput === true;

		// Show with last command palette input if any and configured
		let value = ALL_COMMANDS_PREFIX;
		if (restoreInput && lastCommandPaletteInput) {
			value = `${value}${lastCommandPaletteInput}`;
		}

		this.quickOpenService.show(value, { inputSelection: lastCommandPaletteInput ? { start: 1 /* after prefix */, end: value.length } : void 0 });

		return TPromise.as(null);
	}
}


export class ClearCommandHistoryAction extends Action {

	public static readonly ID = 'workbench.action.clearCommandHistory';
	public static readonly LABEL = nls.localize('clearCommandHistory', "Clear Command History");

	constructor(
		id: string,
		label: string,
		@IConfigurationService private configurationService: IConfigurationService
	) {
		super(id, label);
	}

	public run(context?: any): TPromise<void> {
		const commandHistoryLength = resolveCommandHistory(this.configurationService);
		if (commandHistoryLength > 0) {
			commandHistory = new LRUCache<string, number>(commandHistoryLength);
			commandCounter = 1;
		}

		return TPromise.as(null);
	}
}


class CommandPaletteEditorAction extends EditorAction {

	constructor() {
		super({
			id: ShowAllCommandsAction.ID,
			label: nls.localize('showCommands.label', "Command Palette..."),
			alias: 'Command Palette',
			precondition: null,
			menuOpts: {
			}
		});
	}

	public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise<void> {
		const quickOpenService = accessor.get(IQuickOpenService);

		// Show with prefix
		quickOpenService.show(ALL_COMMANDS_PREFIX);

		return TPromise.as(null);
	}
}


abstract class BaseCommandEntry extends QuickOpenEntryGroup {
	private description: string;
	private alias: string;
	private labelLowercase: string;
	private keybindingAriaLabel: string;

	constructor(
		private commandId: string,
		private keybinding: ResolvedKeybinding,
		private label: string,
		alias: string,
		highlights: { label: IHighlight[], alias: IHighlight[] },
		private onBeforeRun: (commandId: string) => void,
		@INotificationService private notificationService: INotificationService,
		@ITelemetryService protected telemetryService: ITelemetryService
	) {
		super();

		this.labelLowercase = this.label.toLowerCase();
		this.keybindingAriaLabel = keybinding ? keybinding.getAriaLabel() : void 0;

		if (this.label !== alias) {
			this.alias = alias;
		} else {
			highlights.alias = null;
		}

		this.setHighlights(highlights.label, null, highlights.alias);
	}

	public getCommandId(): string {
		return this.commandId;
	}

	public getLabel(): string {
		return this.label;
	}

	public getSortLabel(): string {
		return this.labelLowercase;
	}

	public getDescription(): string {
		return this.description;
	}

	public setDescription(description: string): void {
		this.description = description;
	}

	public getKeybinding(): ResolvedKeybinding {
		return this.keybinding;
	}

	public getDetail(): string {
		return this.alias;
	}

	public getAriaLabel(): string {
		if (this.keybindingAriaLabel) {
			return nls.localize('entryAriaLabelWithKey', "{0}, {1}, commands", this.getLabel(), this.keybindingAriaLabel);
		}

		return nls.localize('entryAriaLabel', "{0}, commands", this.getLabel());
	}

	public run(mode: Mode, context: IEntryRunContext): boolean {
		if (mode === Mode.OPEN) {
			this.runAction(this.getAction());

			return true;
		}

		return false;
	}

	protected abstract getAction(): Action | IEditorAction;

	protected runAction(action: Action | IEditorAction): void {

		// Indicate onBeforeRun
		this.onBeforeRun(this.commandId);

		// Use a timeout to give the quick open widget a chance to close itself first
		TPromise.timeout(50).done(() => {
			if (action && (!(action instanceof Action) || action.enabled)) {
				try {
					/* __GDPR__
						"workbenchActionExecuted" : {
							"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
							"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
						}
					*/
					this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'quick open' });
					(action.run() || TPromise.as(null)).done(() => {
						if (action instanceof Action) {
							action.dispose();
						}
					}, err => this.onError(err));
				} catch (error) {
					this.onError(error);
				}
			} else {
				this.notificationService.info(nls.localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel()));
			}
		}, err => this.onError(err));
	}

	private onError(error?: Error): void {
		if (isPromiseCanceledError(error)) {
			return;
		}

		this.notificationService.error(error || nls.localize('canNotRun', "Command '{0}' resulted in an error.", this.label));
	}
}


class EditorActionCommandEntry extends BaseCommandEntry {

	constructor(
		commandId: string,
		keybinding: ResolvedKeybinding,
		label: string,
		meta: string,
		highlights: { label: IHighlight[], alias: IHighlight[] },
		private action: IEditorAction,
		onBeforeRun: (commandId: string) => void,
		@INotificationService notificationService: INotificationService,
		@ITelemetryService telemetryService: ITelemetryService
	) {
		super(commandId, keybinding, label, meta, highlights, onBeforeRun, notificationService, telemetryService);
	}

	protected getAction(): Action | IEditorAction {
		return this.action;
	}
}


class ActionCommandEntry extends BaseCommandEntry {

	constructor(
		commandId: string,
		keybinding: ResolvedKeybinding,
		label: string,
		alias: string,
		highlights: { label: IHighlight[], alias: IHighlight[] },
		private action: Action,
		onBeforeRun: (commandId: string) => void,
		@INotificationService notificationService: INotificationService,
		@ITelemetryService telemetryService: ITelemetryService
	) {
		super(commandId, keybinding, label, alias, highlights, onBeforeRun, notificationService, telemetryService);
	}

	protected getAction(): Action | IEditorAction {
		return this.action;
	}
}


interface ISerializedCommandHistory {
	usesLRU?: boolean;
	entries: { key: string; value: number }[];
}


private updateConfiguration(): void {
		this.commandHistoryLength = resolveCommandHistory(this.configurationService);

		if (commandHistory) {
			commandHistory.limit = this.commandHistoryLength;
		}
	}


private load(): void {
		const raw = this.storageService.get(CommandsHistory.PREF_KEY_CACHE);
		let serializedCache: ISerializedCommandHistory;
		if (raw) {
			try {
				serializedCache = JSON.parse(raw);
			} catch (error) {
				// invalid data
			}
		}

		commandHistory = new LRUCache<string, number>(this.commandHistoryLength, 1);
		if (serializedCache) {
			let entries: { key: string; value: number }[];
			if (serializedCache.usesLRU) {
				entries = serializedCache.entries;
			} else {
				entries = serializedCache.entries.sort((a, b) => a.value - b.value);
			}
			entries.forEach(entry => commandHistory.set(entry.key, entry.value));
		}
		commandCounter = this.storageService.getInteger(CommandsHistory.PREF_KEY_COUNTER, void 0, commandCounter);
	}


private registerListeners(): void {
		this.configurationService.onDidChangeConfiguration(e => this.updateConfiguration());
		once(this.lifecycleService.onShutdown)(reason => this.save());
	}


private save(): void {
		let serializedCache: ISerializedCommandHistory = { usesLRU: true, entries: [] };
		commandHistory.forEach((value, key) => serializedCache.entries.push({ key, value }));
		this.storageService.store(CommandsHistory.PREF_KEY_CACHE, JSON.stringify(serializedCache));
		this.storageService.store(CommandsHistory.PREF_KEY_COUNTER, commandCounter);
	}


public push(commandId: string): void {
		// set counter to command
		commandHistory.set(commandId, commandCounter++);
	}


public peek(commandId: string): number {
		return commandHistory.peek(commandId);
	}


public run(context?: any): TPromise<void> {
		const config = <IWorkbenchQuickOpenConfiguration>this.configurationService.getValue();
		const restoreInput = config.workbench && config.workbench.commandPalette && config.workbench.commandPalette.preserveInput === true;

		// Show with last command palette input if any and configured
		let value = ALL_COMMANDS_PREFIX;
		if (restoreInput && lastCommandPaletteInput) {
			value = `${value}${lastCommandPaletteInput}`;
		}

		this.quickOpenService.show(value, { inputSelection: lastCommandPaletteInput ? { start: 1 /* after prefix */, end: value.length } : void 0 });

		return TPromise.as(null);
	}


public run(context?: any): TPromise<void> {
		const commandHistoryLength = resolveCommandHistory(this.configurationService);
		if (commandHistoryLength > 0) {
			commandHistory = new LRUCache<string, number>(commandHistoryLength);
			commandCounter = 1;
		}

		return TPromise.as(null);
	}


public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise<void> {
		const quickOpenService = accessor.get(IQuickOpenService);

		// Show with prefix
		quickOpenService.show(ALL_COMMANDS_PREFIX);

		return TPromise.as(null);
	}


public getCommandId(): string {
		return this.commandId;
	}


public getLabel(): string {
		return this.label;
	}


public getSortLabel(): string {
		return this.labelLowercase;
	}


public getDescription(): string {
		return this.description;
	}


public setDescription(description: string): void {
		this.description = description;
	}


public getKeybinding(): ResolvedKeybinding {
		return this.keybinding;
	}


public getDetail(): string {
		return this.alias;
	}


public getAriaLabel(): string {
		if (this.keybindingAriaLabel) {
			return nls.localize('entryAriaLabelWithKey', "{0}, {1}, commands", this.getLabel(), this.keybindingAriaLabel);
		}

		return nls.localize('entryAriaLabel', "{0}, commands", this.getLabel());
	}


public run(mode: Mode, context: IEntryRunContext): boolean {
		if (mode === Mode.OPEN) {
			this.runAction(this.getAction());

			return true;
		}

		return false;
	}


protected abstract getAction(): Action | IEditorAction;


protected runAction(action: Action | IEditorAction): void {

		// Indicate onBeforeRun
		this.onBeforeRun(this.commandId);

		// Use a timeout to give the quick open widget a chance to close itself first
		TPromise.timeout(50).done(() => {
			if (action && (!(action instanceof Action) || action.enabled)) {
				try {
					/* __GDPR__
						"workbenchActionExecuted" : {
							"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
							"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
						}
					*/
					this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'quick open' });
					(action.run() || TPromise.as(null)).done(() => {
						if (action instanceof Action) {
							action.dispose();
						}
					}, err => this.onError(err));
				} catch (error) {
					this.onError(error);
				}
			} else {
				this.notificationService.info(nls.localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel()));
			}
		}, err => this.onError(err));
	}


private onError(error?: Error): void {
		if (isPromiseCanceledError(error)) {
			return;
		}

		this.notificationService.error(error || nls.localize('canNotRun', "Command '{0}' resulted in an error.", this.label));
	}


protected getAction(): Action | IEditorAction {
		return this.action;
	}


private updateConfiguration(): void {
		this.commandHistoryEnabled = resolveCommandHistory(this.configurationService) > 0;
	}


public getResults(searchValue: string): TPromise<QuickOpenModel> {
		searchValue = searchValue.trim();
		this.lastSearchValue = searchValue;

		// Editor Actions
		const activeEditor = this.editorService.getActiveEditor();
		const activeEditorControl = activeEditor ? activeEditor.getControl() : null;

		let editorActions: IEditorAction[] = [];
		if (activeEditorControl) {
			const editor = <IEditor>activeEditorControl;
			if (types.isFunction(editor.getSupportedActions)) {
				editorActions = editor.getSupportedActions();
			}
		}

		const editorEntries = this.editorActionsToEntries(editorActions, searchValue);

		// Other Actions
		const menu = this.editorGroupService.invokeWithinEditorContext(accessor => this.menuService.createMenu(MenuId.CommandPalette, accessor.get(IContextKeyService)));
		const menuActions = menu.getActions().reduce((r, [, actions]) => [...r, ...actions], <MenuItemAction[]>[]);
		const commandEntries = this.menuItemActionsToEntries(menuActions, searchValue);

		// Concat
		let entries = [...editorEntries, ...commandEntries];

		// Remove duplicates
		entries = arrays.distinct(entries, entry => `${entry.getLabel()}${entry.getGroupLabel()}${entry.getCommandId()}`);

		// Handle label clashes
		const commandLabels = new Set<string>();
		entries.forEach(entry => {
			const commandLabel = `${entry.getLabel()}${entry.getGroupLabel()}`;
			if (commandLabels.has(commandLabel)) {
				entry.setDescription(entry.getCommandId());
			} else {
				commandLabels.add(commandLabel);
			}
		});

		// Sort by MRU order and fallback to name otherwie
		entries = entries.sort((elementA, elementB) => {
			const counterA = this.commandsHistory.peek(elementA.getCommandId());
			const counterB = this.commandsHistory.peek(elementB.getCommandId());

			if (counterA && counterB) {
				return counterA > counterB ? -1 : 1; // use more recently used command before older
			}

			if (counterA) {
				return -1; // first command was used, so it wins over the non used one
			}

			if (counterB) {
				return 1; // other command was used so it wins over the command
			}

			// both commands were never used, so we sort by name
			return elementA.getSortLabel().localeCompare(elementB.getSortLabel());
		});

		// Introduce group marker border between recently used and others
		// only if we have recently used commands in the result set
		const firstEntry = entries[0];
		if (firstEntry && this.commandsHistory.peek(firstEntry.getCommandId())) {
			firstEntry.setGroupLabel(nls.localize('recentlyUsed', "recently used"));
			for (let i = 1; i < entries.length; i++) {
				const entry = entries[i];
				if (!this.commandsHistory.peek(entry.getCommandId())) {
					entry.setShowBorder(true);
					entry.setGroupLabel(nls.localize('morecCommands', "other commands"));
					break;
				}
			}
		}

		return TPromise.as(new QuickOpenModel(entries));
	}


private editorActionsToEntries(actions: IEditorAction[], searchValue: string): EditorActionCommandEntry[] {
		const entries: EditorActionCommandEntry[] = [];

		for (let i = 0; i < actions.length; i++) {
			const action = actions[i];
			if (action.id === ShowAllCommandsAction.ID) {
				continue; // avoid duplicates
			}

			const label = action.label;
			if (label) {

				// Alias for non default languages
				const alias = (language !== LANGUAGE_DEFAULT) ? action.alias : null;
				const labelHighlights = wordFilter(searchValue, label);
				const aliasHighlights = alias ? wordFilter(searchValue, alias) : null;

				if (labelHighlights || aliasHighlights) {
					entries.push(this.instantiationService.createInstance(EditorActionCommandEntry, action.id, this.keybindingService.lookupKeybinding(action.id), label, alias, { label: labelHighlights, alias: aliasHighlights }, action, (id: string) => this.onBeforeRunCommand(id)));
				}
			}
		}

		return entries;
	}


private onBeforeRunCommand(commandId: string): void {

		// Remember as last command palette input
		lastCommandPaletteInput = this.lastSearchValue;

		// Remember in commands history
		this.commandsHistory.push(commandId);
	}


private menuItemActionsToEntries(actions: MenuItemAction[], searchValue: string): ActionCommandEntry[] {
		const entries: ActionCommandEntry[] = [];

		for (let action of actions) {
			const title = typeof action.item.title === 'string' ? action.item.title : action.item.title.value;
			let category, label = title;
			if (action.item.category) {
				category = typeof action.item.category === 'string' ? action.item.category : action.item.category.value;
				label = nls.localize('cat.title', "{0}: {1}", category, title);
			}

			if (label) {
				const labelHighlights = wordFilter(searchValue, label);

				// Add an 'alias' in original language when running in different locale
				const aliasTitle = (language !== LANGUAGE_DEFAULT && typeof action.item.title !== 'string') ? action.item.title.original : null;
				const aliasCategory = (language !== LANGUAGE_DEFAULT && category && typeof action.item.category !== 'string') ? action.item.category.original : null;
				let alias;
				if (aliasTitle && category) {
					alias = aliasCategory ? `${aliasCategory}: ${aliasTitle}` : `${category}: ${aliasTitle}`;
				} else if (aliasTitle) {
					alias = aliasTitle;
				}
				const aliasHighlights = alias ? wordFilter(searchValue, alias) : null;

				if (labelHighlights || aliasHighlights) {
					entries.push(this.instantiationService.createInstance(ActionCommandEntry, action.id, this.keybindingService.lookupKeybinding(action.item.id), label, alias, { label: labelHighlights, alias: aliasHighlights }, action, (id: string) => this.onBeforeRunCommand(id)));
				}
			}
		}

		return entries;
	}


public getAutoFocus(searchValue: string, context: { model: IModel<QuickOpenEntry>, quickNavigateConfiguration?: IQuickNavigateConfiguration }): IAutoFocus {
		let autoFocusPrefixMatch = searchValue.trim();

		if (autoFocusPrefixMatch && this.commandHistoryEnabled) {
			const firstEntry = context.model && context.model.entries[0];
			if (firstEntry instanceof BaseCommandEntry && this.commandsHistory.peek(firstEntry.getCommandId())) {
				autoFocusPrefixMatch = void 0; // keep focus on MRU element if we have history elements
			}
		}

		return {
			autoFocusFirstEntry: true,
			autoFocusPrefixMatch
		};
	}


public getEmptyLabel(searchString: string): string {
		return nls.localize('noCommandsMatching', "No commands matching");
	}


public onClose(canceled: boolean): void {
		if (canceled) {
			lastCommandPaletteInput = void 0; // clear last input when user canceled quick open
		}
	}


@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}


() => {
    const hotelsNames = useSelector((state: TypeAppProps) => state.hotels.data.names);
    const hotelsDetails = useSelector((state: TypeAppProps) => state.hotels.data.details);
    const cart = useSelector((state: TypeCartDetails) => state.cart);
    const roomDetails = getRoomDetails(cart, hotelsDetails);
    const selectedHotel = hotelsNames.find((hotel: TypeHotel) => hotel.id === cart.hotelId);

    let selectedHotelDetails: TypeHotelDetails | undefined;
    if (hotelsDetails) {
        selectedHotelDetails = hotelsDetails.find((item) => item.id === cart.hotelId);
    }

    return {
        hotels: {
            names: hotelsNames || [],
            details: hotelsDetails || []
        },
        roomDetails,
        selectedHotel: {
            name: selectedHotel?.hotel_name || '',
            details: selectedHotelDetails
        }
    };
}


(state: TypeAppProps) => state.hotels.data.names


(state: TypeAppProps) => state.hotels.data.details


(state: TypeCartDetails) => state.cart


(hotel: TypeHotel) => hotel.id === cart.hotelId


(item) => item.id === cart.hotelId


function resetMocks() {
        console.debug = jest.fn()
        console.info = jest.fn()
        console.log = jest.fn()
        console.warn = jest.fn()
        console.error = jest.fn()
    }


async () => {
    const buffer = Buffer.from(tgz, 'base64')

    const packageJson1 = await getFileFromTGZ(buffer, 'package.json')
    expect(packageJson1).toBeDefined()
    expect(JSON.parse(packageJson1!.toString())['version']).toEqual('0.0.0')

    const packageJson2 = await getFileFromArchive(buffer, 'package.json')
    expect(packageJson2).toBeDefined()
    expect(JSON.parse(packageJson2!.toString())['version']).toEqual('0.0.0')

    const missingJson1 = await getFileFromTGZ(buffer, 'missing.json')
    expect(missingJson1).toEqual(null)

    const missingJson2 = await getFileFromArchive(buffer, 'missing.json')
    expect(missingJson2).toEqual(null)

    await expect(getFileFromTGZ(Buffer.from('ha!@#!@2ha'), 'broken.json')).rejects.toThrow()
    await expect(getFileFromArchive(Buffer.from('haha'), 'broken.json')).rejects.toThrow()
}


async () => {
    const buffer = Buffer.from(zip, 'base64')

    const packageJson1 = getFileFromZip(buffer, 'package.json')
    expect(packageJson1).toBeDefined()
    expect(JSON.parse(packageJson1!.toString())['version']).toEqual('0.0.1')

    const packageJson2 = await getFileFromArchive(buffer, 'package.json')
    expect(packageJson2).toBeDefined()
    expect(JSON.parse(packageJson2!.toString())['version']).toEqual('0.0.1')

    const missingJson1 = getFileFromZip(buffer, 'missing.json')
    expect(missingJson1).toEqual(null)

    const missingJson2 = await getFileFromArchive(buffer, 'missing.json')
    expect(missingJson2).toEqual(null)

    expect(() => getFileFromZip(Buffer.from('haha'), 'broken.json')).toThrow()
    await expect(getFileFromArchive(Buffer.from('haha'), 'broken.json')).rejects.toThrow()
}


() => getFileFromZip(Buffer.from('haha'), 'broken.json')


() => {
    const buffer = Buffer.from(zip, 'base64')
    const stream = bufferToStream(buffer)
    expect(stream.read()).toEqual(buffer)
}


() => {
    function resetMocks() {
        console.debug = jest.fn()
        console.info = jest.fn()
        console.log = jest.fn()
        console.warn = jest.fn()
        console.error = jest.fn()
    }

    resetMocks()
    setLogLevel(LogLevel.Debug)
    console.debug('debug')
    console.info('debug')
    console.log('debug')
    console.warn('debug')
    console.error('debug')
    expect(console.debug).toHaveBeenCalledWith('debug')
    expect(console.info).toHaveBeenCalledWith('debug')
    expect(console.log).toHaveBeenCalledWith('debug')
    expect(console.warn).toHaveBeenCalledWith('debug')
    expect(console.error).toHaveBeenCalledWith('debug')

    resetMocks()
    setLogLevel(LogLevel.Info)
    console.debug('info')
    console.info('info')
    console.log('info')
    console.warn('info')
    console.error('info')
    expect((console.debug as any)._original).toBeDefined()
    expect(console.info).toHaveBeenCalledWith('info')
    expect(console.log).toHaveBeenCalledWith('info')
    expect(console.warn).toHaveBeenCalledWith('info')
    expect(console.error).toHaveBeenCalledWith('info')

    resetMocks()
    setLogLevel(LogLevel.Log)
    console.debug('log')
    console.info('log')
    console.log('log')
    console.warn('log')
    console.error('log')
    expect((console.debug as any)._original).toBeDefined()
    expect((console.info as any)._original).toBeDefined()
    expect(console.log).toHaveBeenCalledWith('log')
    expect(console.warn).toHaveBeenCalledWith('log')
    expect(console.error).toHaveBeenCalledWith('log')

    resetMocks()
    setLogLevel(LogLevel.Warn)
    console.debug('warn')
    console.info('warn')
    console.log('warn')
    console.warn('warn')
    console.error('warn')
    expect((console.debug as any)._original).toBeDefined()
    expect((console.info as any)._original).toBeDefined()
    expect((console.log as any)._original).toBeDefined()
    expect(console.warn).toHaveBeenCalledWith('warn')
    expect(console.error).toHaveBeenCalledWith('warn')

    resetMocks()
    setLogLevel(LogLevel.Error)
    console.debug('error')
    console.info('error')
    console.log('error')
    console.warn('error')
    console.error('error')
    expect((console.debug as any)._original).toBeDefined()
    expect((console.info as any)._original).toBeDefined()
    expect((console.log as any)._original).toBeDefined()
    expect((console.warn as any)._original).toBeDefined()
    expect(console.error).toHaveBeenCalledWith('error')

    resetMocks()
    setLogLevel(LogLevel.None)
    console.debug('none')
    console.info('none')
    console.log('none')
    console.warn('none')
    console.error('none')
    expect((console.debug as any)._original).toBeDefined()
    expect((console.info as any)._original).toBeDefined()
    expect((console.log as any)._original).toBeDefined()
    expect((console.warn as any)._original).toBeDefined()
    expect((console.error as any)._original).toBeDefined()
}


() => {
    const o1 = ['string', 'value']
    expect(cloneObject(o1)).toEqual(o1)
    expect(cloneObject(o1) === o1).toBe(false)

    const o2 = { key: 'value' }
    expect(cloneObject(o2)).toEqual(o2)
    expect(cloneObject(o2) === o2).toBe(false)

    const o3 = { key: 'value', nested: ['a1', 'a2'], nestedObj: { key: 'other' } }
    expect(cloneObject(o3)).toEqual(o3)
    expect(cloneObject(o3) === o3).toBe(false)
    expect((cloneObject(o3) as typeof o3).nested === o3.nested).toBe(false)
    expect((cloneObject(o3) as typeof o3).nestedObj === o3.nestedObj).toBe(false)

    const o4 = null
    expect(cloneObject(o4)).toEqual(o4)
    expect(cloneObject(o4) === o4).toBe(true)

    const o5 = 'string'
    expect(cloneObject(o5)).toEqual(o5)
    expect(cloneObject(o5) === o5).toBe(true)
}


() => {
    describe('#constructor', () => {
        it('works with a valid string', () => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            expect(uuid.array).toStrictEqual(
                new Uint8Array([
                    0x99,
                    0xab,
                    0xcd,
                    0xef,
                    0x12,
                    0x34,
                    0x43,
                    0x21,
                    0,
                    0,
                    0xdc,
                    0xba,
                    0x87,
                    0x65,
                    0x43,
                    0x21,
                ])
            )
        })

        it('throws on an invalid string', () => {
            expect(() => new UUID('99aBcDeF-1234-4321-WXyz-dcba87654321')).toThrow() // "WXyz" are not hexadecimal
            expect(() => new UUID('99aBcDeF123443210000dcba87654321')).toThrow() // lack of hyphens
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba87654321A')).toThrow() // one character too many
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba8765432')).toThrow() // one character too few
            expect(() => new UUID('')).toThrow() // empty string
        })

        it('works with a Uint8Array', () => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
                expect(uuid.array).toStrictEqual(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
            }
        })

        it('works with a random buffer', () => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(randomBytes(16))
                expect(uuid.array).toHaveLength(16)
            }
        })
    })

    describe('#valueOf', () => {
        it('returns the right big integer', () => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            expect(uuid.valueOf()).toStrictEqual(0x99abcdef123443210000dcba87654321n)
        })
    })

    describe('#toString', () => {
        it('returns the right string', () => {
            const original = '99aBcDeF-1234-4321-0000-dcba87654321'
            const uuid = new UUID(original)
            const uuidString = uuid.toString()
            // 32 hexadecimal digits + 4 hyphens
            expect(uuidString).toHaveLength(36)
            expect(uuidString).toStrictEqual(original.toLowerCase())
        })
    })
}


() => {
        it('works with a valid string', () => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            expect(uuid.array).toStrictEqual(
                new Uint8Array([
                    0x99,
                    0xab,
                    0xcd,
                    0xef,
                    0x12,
                    0x34,
                    0x43,
                    0x21,
                    0,
                    0,
                    0xdc,
                    0xba,
                    0x87,
                    0x65,
                    0x43,
                    0x21,
                ])
            )
        })

        it('throws on an invalid string', () => {
            expect(() => new UUID('99aBcDeF-1234-4321-WXyz-dcba87654321')).toThrow() // "WXyz" are not hexadecimal
            expect(() => new UUID('99aBcDeF123443210000dcba87654321')).toThrow() // lack of hyphens
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba87654321A')).toThrow() // one character too many
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba8765432')).toThrow() // one character too few
            expect(() => new UUID('')).toThrow() // empty string
        })

        it('works with a Uint8Array', () => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
                expect(uuid.array).toStrictEqual(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
            }
        })

        it('works with a random buffer', () => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(randomBytes(16))
                expect(uuid.array).toHaveLength(16)
            }
        })
    }


() => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            expect(uuid.array).toStrictEqual(
                new Uint8Array([
                    0x99,
                    0xab,
                    0xcd,
                    0xef,
                    0x12,
                    0x34,
                    0x43,
                    0x21,
                    0,
                    0,
                    0xdc,
                    0xba,
                    0x87,
                    0x65,
                    0x43,
                    0x21,
                ])
            )
        }


() => {
            expect(() => new UUID('99aBcDeF-1234-4321-WXyz-dcba87654321')).toThrow() // "WXyz" are not hexadecimal
            expect(() => new UUID('99aBcDeF123443210000dcba87654321')).toThrow() // lack of hyphens
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba87654321A')).toThrow() // one character too many
            expect(() => new UUID('99aBcDeF-1234-4321-0000-dcba8765432')).toThrow() // one character too few
            expect(() => new UUID('')).toThrow() // empty string
        }


() => new UUID('99aBcDeF-1234-4321-WXyz-dcba87654321')


() => new UUID('99aBcDeF123443210000dcba87654321')


() => new UUID('99aBcDeF-1234-4321-0000-dcba87654321A')


() => new UUID('99aBcDeF-1234-4321-0000-dcba8765432')


() => new UUID('')


() => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
                expect(uuid.array).toStrictEqual(
                    new Uint8Array([
                        0x99,
                        0xab,
                        0xcd,
                        0xef,
                        0x12,
                        0x34,
                        0x43,
                        0x21,
                        0,
                        0,
                        0xdc,
                        0xba,
                        0x87,
                        0x65,
                        0x43,
                        0x21,
                    ])
                )
            }
        }


() => {
            for (let i = 0; i < 10; i++) {
                const uuid = new UUID(randomBytes(16))
                expect(uuid.array).toHaveLength(16)
            }
        }


() => {
        it('returns the right big integer', () => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            expect(uuid.valueOf()).toStrictEqual(0x99abcdef123443210000dcba87654321n)
        })
    }


() => {
            const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321')
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            expect(uuid.valueOf()).toStrictEqual(0x99abcdef123443210000dcba87654321n)
        }


() => {
        it('returns the right string', () => {
            const original = '99aBcDeF-1234-4321-0000-dcba87654321'
            const uuid = new UUID(original)
            const uuidString = uuid.toString()
            // 32 hexadecimal digits + 4 hyphens
            expect(uuidString).toHaveLength(36)
            expect(uuidString).toStrictEqual(original.toLowerCase())
        })
    }


() => {
            const original = '99aBcDeF-1234-4321-0000-dcba87654321'
            const uuid = new UUID(original)
            const uuidString = uuid.toString()
            // 32 hexadecimal digits + 4 hyphens
            expect(uuidString).toHaveLength(36)
            expect(uuidString).toStrictEqual(original.toLowerCase())
        }


() => {
    it('is well-formed', () => {
        const uuidt = new UUIDT()
        const uuidtString = uuidt.toString()
        // UTC timestamp matching (roughly, only comparing the beginning as the timestamp's end inevitably drifts away)
        expect(uuidtString.slice(0, 8)).toEqual(Date.now().toString(16).padStart(12, '0').slice(0, 8))
        // series matching
        expect(uuidtString.slice(14, 18)).toEqual('0000')
    })
}


() => {
        const uuidt = new UUIDT()
        const uuidtString = uuidt.toString()
        // UTC timestamp matching (roughly, only comparing the beginning as the timestamp's end inevitably drifts away)
        expect(uuidtString.slice(0, 8)).toEqual(Date.now().toString(16).padStart(12, '0').slice(0, 8))
        // series matching
        expect(uuidtString.slice(14, 18)).toEqual('0000')
    }


() => {
    it('removes all characters that are neither letter, digit or underscore and adds quotes around identifier', () => {
        const rawIdentifier = 'some_field"; DROP TABLE actually_an_injection-9;'

        const sanitizedIdentifier = sanitizeSqlIdentifier(rawIdentifier)

        expect(sanitizedIdentifier).toStrictEqual('some_fieldDROPTABLEactually_an_injection9')
    })
}


() => {
        const rawIdentifier = 'some_field"; DROP TABLE actually_an_injection-9;'

        const sanitizedIdentifier = sanitizeSqlIdentifier(rawIdentifier)

        expect(sanitizedIdentifier).toStrictEqual('some_fieldDROPTABLEactually_an_injection9')
    }


() => {
    it('escapes single quotes and slashes', () => {
        const rawString = "insert'escape \\"

        const sanitizedString = escapeClickHouseString(rawString)

        expect(sanitizedString).toStrictEqual("insert\\'escape \\\\")
    })
}


() => {
        const rawString = "insert'escape \\"

        const sanitizedString = escapeClickHouseString(rawString)

        expect(sanitizedString).toStrictEqual("insert\\'escape \\\\")
    }


() => {
    it('groups simple objects', () => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 2, foo: 'y' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        const groupingByI = groupBy(objects, 'i')
        expect(groupingByI).toEqual({
            2: [
                { i: 2, foo: 'x' },
                { i: 2, foo: 'y' },
            ],
            4: [{ i: 4, foo: 'x' }],
            7: [{ i: 7, foo: 'z' }],
        })

        const groupingByFoo = groupBy(objects, 'foo')
        expect(groupingByFoo).toEqual({
            x: [
                { i: 2, foo: 'x' },
                { i: 4, foo: 'x' },
            ],
            y: [{ i: 2, foo: 'y' }],
            z: [{ i: 7, foo: 'z' }],
        })
    })

    it('handles undefineds', () => {
        const objects = [{ i: 2, foo: 'x' }, { i: 2, foo: 'y' }, { i: 4, foo: 'x' }, { foo: 'z' }]

        const groupingByI = groupBy(objects, 'i')
        expect(groupingByI).toEqual({
            2: [
                { i: 2, foo: 'x' },
                { i: 2, foo: 'y' },
            ],
            4: [{ i: 4, foo: 'x' }],
            undefined: [{ foo: 'z' }],
        })
    })

    it('works in flat mode', () => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        const groupingByI = groupBy(objects, 'i', true)
        expect(groupingByI).toEqual({
            2: { i: 2, foo: 'x' },
            4: { i: 4, foo: 'x' },
            7: { i: 7, foo: 'z' },
        })
    })

    it("doesn't work in flat mode if multiple values match a single key", () => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 2, foo: 'y' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        expect(() => groupBy(objects, 'i', true)).toThrowError(
            'Key "i" has more than one matching value, which is not allowed in flat groupBy!'
        )
    })
}


() => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 2, foo: 'y' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        const groupingByI = groupBy(objects, 'i')
        expect(groupingByI).toEqual({
            2: [
                { i: 2, foo: 'x' },
                { i: 2, foo: 'y' },
            ],
            4: [{ i: 4, foo: 'x' }],
            7: [{ i: 7, foo: 'z' }],
        })

        const groupingByFoo = groupBy(objects, 'foo')
        expect(groupingByFoo).toEqual({
            x: [
                { i: 2, foo: 'x' },
                { i: 4, foo: 'x' },
            ],
            y: [{ i: 2, foo: 'y' }],
            z: [{ i: 7, foo: 'z' }],
        })
    }


() => {
        const objects = [{ i: 2, foo: 'x' }, { i: 2, foo: 'y' }, { i: 4, foo: 'x' }, { foo: 'z' }]

        const groupingByI = groupBy(objects, 'i')
        expect(groupingByI).toEqual({
            2: [
                { i: 2, foo: 'x' },
                { i: 2, foo: 'y' },
            ],
            4: [{ i: 4, foo: 'x' }],
            undefined: [{ foo: 'z' }],
        })
    }


() => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        const groupingByI = groupBy(objects, 'i', true)
        expect(groupingByI).toEqual({
            2: { i: 2, foo: 'x' },
            4: { i: 4, foo: 'x' },
            7: { i: 7, foo: 'z' },
        })
    }


() => {
        const objects = [
            { i: 2, foo: 'x' },
            { i: 2, foo: 'y' },
            { i: 4, foo: 'x' },
            { i: 7, foo: 'z' },
        ]

        expect(() => groupBy(objects, 'i', true)).toThrowError(
            'Key "i" has more than one matching value, which is not allowed in flat groupBy!'
        )
    }


() => groupBy(objects, 'i', true)


/**
     * WARNING: This is an autogenerated component.
     * Do not make any changes to this file or they will be overwritten on build.
     * The template for this file is located in the generate-icons.js util file.
     * /

    /** @internal **/
@Component({
    tag: 'rux-icon-vpn-lock',
    shadow: false,
})
export class RuxIconVpnLock {
    /**
     * The fill color for the icon
     */
    @Prop() color?: string

    /**
     * The size of the icon. Can be 'extra-small', 'small', 'normal', 'large', 'auto' or any custom value ('30px', '1rem', '3.321em')
     */

    @Prop() size:
        | 'extra-small'
        | 'small'
        | 'normal'
        | 'large'
        | 'auto'
        | string = 'auto'

    get iconSize() {
        const sizes: { [key: string]: any } = {
            'extra-small': '1rem',
            small: '2rem',
            normal: '3rem',
            large: '4rem',
        }

        if (sizes[this.size]) {
            return sizes[this.size]
        } else {
            return this.size
        }
    }
    render() {
        const style = {
            fill: this.color,
            height: this.iconSize,
            width: this.iconSize,
        }

        return

    }
}


render() {
        const style = {
            fill: this.color,
            height: this.iconSize,
            width: this.iconSize,
        }

        return

    }


export function initCron(): void {
  if (config.config.cronFunctions.length > 0) {
    createCrond()
  } else {
    logger.log('no cron functions.')
  }
}


/** Argument details. */
export interface IArgument extends IFlagArgument {
  /** Argument name. */
  name: string;
  /** Shell completion action. */
  action: string;
  /** Arguments type. */
  type: string;
}


/** Result of `cmd.parse()` method. */
export interface IParseResult<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> {
  options: PG & G & O;
  args: A;
  literal: string[];
  cmd: Command<O, A, G, PG, P>;
}


/** Command option options. */
export interface ICommandOption<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> extends Omit<IFlagOptions, ExcludedCommandOptions> {
  override?: boolean;
  hidden?: boolean;
  global?: boolean;
  action?: IAction<O, A, G, PG, P>;
  prepend?: boolean;
}


/** Command option settings. */
export interface IOption<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> extends ICommandOption<O, A, G, PG, P>, IFlagOptions {
  description: string;
  flags: Array<string>;
  typeDefinition?: string;
  args: IArgument[];
}


/* ENV VARS TYPES */
/** Environment variable options */
export interface IEnvVarOptions {
  hidden?: boolean;
  global?: boolean;
}


/** Environment variable settings. */
export interface IEnvVar extends IEnvVarOptions {
  names: string[];
  description: string;
  type: string;
  details: IArgument;
}


/* TYPE TYPES */
/** Type options. */
export interface ITypeOptions {
  override?: boolean;
  global?: boolean;
}


/** Type settings. */
export interface IType extends ITypeOptions {
  name: string;
  handler: Type<unknown> | ITypeHandler<unknown>;
}


/* EXAMPLE TYPES */
/** Example settings. */
export interface IExample {
  name: string;
  description: string;
}


/* COMPLETION TYPES */
/** Completion options. */
export interface ICompleteOptions {
  override?: boolean;
  global?: boolean;
}


/** Completion settings. */
export interface ICompletion<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> extends ICompleteOptions {
  name: string;
  complete: ICompleteHandler<O, A, G, PG, P>;
}


type Merge<T, V> = T extends void ? V : (V extends void ? T : T & V);


/* COMMAND TYPES */
/** Description handler. */
export type IDescription<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> = string | ((this: Command<O, A, G, PG, P>) => string);


/** Action handler for commands and options. */
export type IAction<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> = (
  this: Command<O, A, G, PG, P>,
  options: Merge<Merge<PG, G>, O>,
  ...args: A
) => void | Promise<void>;


/* OPTION TYPES */
type ExcludedCommandOptions =
  | "name"
  | "args"
  | "type"
  | "optionalValue"
  | "aliases"
  | "variadic"
  | "list";


/** Type parser method. */
export type ICompleteHandler<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
> = (
  cmd: Command<O, A, G, PG, P>,
  parent?: Command,
) => string[] | Promise<string[]>;


/** Help callback method to print the help. Invoked by the `--help` option and `help` command and the `.getHelp()` and `.showHelp()` method's. */
export type IHelpHandler<
  // deno-lint-ignore no-explicit-any
  O extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  A extends Array<unknown> = any,
  // deno-lint-ignore no-explicit-any
  G extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  PG extends Record<string, any> | void = any,
  // deno-lint-ignore no-explicit-any
  P extends Command | undefined = any,
  C extends Command<O, A, G, PG, P> = Command<O, A, G, PG, P>,
> = (this: C, cmd: C) => string;


export function getInlineOverrideStyle() {
    return overridesList.map(({dataAttr, customProp, cssProp}) => {
        return [
            `[${dataAttr}] {`,
            `  ${cssProp}: var(${customProp}) !important;`,
            '}',
        ].join('\n');
    }).join('\n');
}


function expand(nodes: Node[], selector: string) {
    const results: Node[] = [];
    nodes.forEach((n) => {
        if (n instanceof Element) {
            if (n.matches(selector)) {
                results.push(n);
            }
            results.push(...Array.from(n.querySelectorAll(selector)));
        }
    });
    return results;
}