/*! `stan` grammar compiled for Highlight.js 11.10.0 */
var hljsGrammar = (function () {
  'use strict';

  /*
  Language: Stan
  Description: The Stan probabilistic programming language
  Author: Sean Pinkney <sean.pinkney@gmail.com>
  Website: http://mc-stan.org/
  Category: scientific
  */

  function stan(hljs) {
    const regex = hljs.regex;
    // variable names cannot conflict with block identifiers
    const BLOCKS = [
      'functions',
      'model',
      'data',
      'parameters',
      'quantities',
      'transformed',
      'generated'
    ];

    const STATEMENTS = [
      'for',
      'in',
      'if',
      'else',
      'while',
      'break',
      'continue',
      'return'
    ];

    const TYPES = [
      'array',
      'tuple',
      'complex',
      'int',
      'real',
      'vector',
      'complex_vector',
      'ordered',
      'positive_ordered',
      'simplex',
      'unit_vector',
      'row_vector',
      'complex_row_vector',
      'matrix',
      'complex_matrix',
      'cholesky_factor_corr|10',
      'cholesky_factor_cov|10',
      'corr_matrix|10',
      'cov_matrix|10',
      'void'
    ];

    // to get the functions list
    // clone the [stan-docs repo](https://github.com/stan-dev/docs)
    // then cd into it and run this bash script https://gist.github.com/joshgoebel/dcd33f82d4059a907c986049893843cf
    //
    // the output files are
    // distributions_quoted.txt
    // functions_quoted.txt

    const FUNCTIONS = [
      'abs',
      'acos',
      'acosh',
      'add_diag',
      'algebra_solver',
      'algebra_solver_newton',
      'append_array',
      'append_col',
      'append_row',
      'asin',
      'asinh',
      'atan',
      'atan2',
      'atanh',
      'bessel_first_kind',
      'bessel_second_kind',
      'binary_log_loss',
      'block',
      'cbrt',
      'ceil',
      'chol2inv',
      'cholesky_decompose',
      'choose',
      'col',
      'cols',
      'columns_dot_product',
      'columns_dot_self',
      'complex_schur_decompose',
      'complex_schur_decompose_t',
      'complex_schur_decompose_u',
      'conj',
      'cos',
      'cosh',
      'cov_exp_quad',
      'crossprod',
      'csr_extract',
      'csr_extract_u',
      'csr_extract_v',
      'csr_extract_w',
      'csr_matrix_times_vector',
      'csr_to_dense_matrix',
      'cumulative_sum',
      'dae',
      'dae_tol',
      'determinant',
      'diag_matrix',
      'diagonal',
      'diag_post_multiply',
      'diag_pre_multiply',
      'digamma',
      'dims',
      'distance',
      'dot_product',
      'dot_self',
      'eigendecompose',
      'eigendecompose_sym',
      'eigenvalues',
      'eigenvalues_sym',
      'eigenvectors',
      'eigenvectors_sym',
      'erf',
      'erfc',
      'exp',
      'exp2',
      'expm1',
      'falling_factorial',
      'fdim',
      'fft',
      'fft2',
      'floor',
      'fma',
      'fmax',
      'fmin',
      'fmod',
      'gamma_p',
      'gamma_q',
      'generalized_inverse',
      'get_imag',
      'get_real',
      'head',
      'hmm_hidden_state_prob',
      'hmm_marginal',
      'hypot',
      'identity_matrix',
      'inc_beta',
      'integrate_1d',
      'integrate_ode',
      'integrate_ode_adams',
      'integrate_ode_bdf',
      'integrate_ode_rk45',
      'int_step',
      'inv',
      'inv_cloglog',
      'inv_erfc',
      'inverse',
      'inverse_spd',
      'inv_fft',
      'inv_fft2',
      'inv_inc_beta',
      'inv_logit',
      'inv_Phi',
      'inv_sqrt',
      'inv_square',
      'is_inf',
      'is_nan',
      'lambert_w0',
      'lambert_wm1',
      'lbeta',
      'lchoose',
      'ldexp',
      'lgamma',
      'linspaced_array',
      'linspaced_int_array',
      'linspaced_row_vector',
      'linspaced_vector',
      'lmgamma',
      'lmultiply',
      'log',
      'log1m',
      'log1m_exp',
      'log1m_inv_logit',
      'log1p',
      'log1p_exp',
      'log_determinant',
      'log_diff_exp',
      'log_falling_factorial',
      'log_inv_logit',
      'log_inv_logit_diff',
      'logit',
      'log_mix',
      'log_modified_bessel_first_kind',
      'log_rising_factorial',
      'log_softmax',
      'log_sum_exp',
      'machine_precision',
      'map_rect',
      'matrix_exp',
      'matrix_exp_multiply',
      'matrix_power',
      'max',
      'mdivide_left_spd',
      'mdivide_left_tri_low',
      'mdivide_right_spd',
      'mdivide_right_tri_low',
      'mean',
      'min',
      'modified_bessel_first_kind',
      'modified_bessel_second_kind',
      'multiply_lower_tri_self_transpose',
      'negative_infinity',
      'norm',
      'norm1',
      'norm2',
      'not_a_number',
      'num_elements',
      'ode_adams',
      'ode_adams_tol',
      'ode_adjoint_tol_ctl',
      'ode_bdf',
      'ode_bdf_tol',
      'ode_ckrk',
      'ode_ckrk_tol',
      'ode_rk45',
      'ode_rk45_tol',
      'one_hot_array',
      'one_hot_int_array',
      'one_hot_row_vector',
      'one_hot_vector',
      'ones_array',
      'ones_int_array',
      'ones_row_vector',
      'ones_vector',
      'owens_t',
      'Phi',
      'Phi_approx',
      'polar',
      'positive_infinity',
      'pow',
      'print',
      'prod',
      'proj',
      'qr',
      'qr_Q',
      'qr_R',
      'qr_thin',
      'qr_thin_Q',
      'qr_thin_R',
      'quad_form',
      'quad_form_diag',
      'quad_form_sym',
      'quantile',
      'rank',
      'reduce_sum',
      'reject',
      'rep_array',
      'rep_matrix',
      'rep_row_vector',
      'rep_vector',
      'reverse',
      'rising_factorial',
      'round',
      'row',
      'rows',
      'rows_dot_product',
      'rows_dot_self',
      'scale_matrix_exp_multiply',
      'sd',
      'segment',
      'sin',
      'singular_values',
      'sinh',
      'size',
      'softmax',
      'sort_asc',
      'sort_desc',
      'sort_indices_asc',
      'sort_indices_desc',
      'sqrt',
      'square',
      'squared_distance',
      'step',
      'sub_col',
      'sub_row',
      'sum',
      'svd',
      'svd_U',
      'svd_V',
      'symmetrize_from_lower_tri',
      'tail',
      'tan',
      'tanh',
      'target',
      'tcrossprod',
      'tgamma',
      'to_array_1d',
      'to_array_2d',
      'to_complex',
      'to_int',
      'to_matrix',
      'to_row_vector',
      'to_vector',
      'trace',
      'trace_gen_quad_form',
      'trace_quad_form',
      'trigamma',
      'trunc',
      'uniform_simplex',
      'variance',
      'zeros_array',
      'zeros_int_array',
      'zeros_row_vector'
    ];

    const DISTRIBUTIONS = [
      'bernoulli',
      'bernoulli_logit',
      'bernoulli_logit_glm',
      'beta',
      'beta_binomial',
      'beta_proportion',
      'binomial',
      'binomial_logit',
      'categorical',
      'categorical_logit',
      'categorical_logit_glm',
      'cauchy',
      'chi_square',
      'dirichlet',
      'discrete_range',
      'double_exponential',
      'exp_mod_normal',
      'exponential',
      'frechet',
      'gamma',
      'gaussian_dlm_obs',
      'gumbel',
      'hmm_latent',
      'hypergeometric',
      'inv_chi_square',
      'inv_gamma',
      'inv_wishart',
      'inv_wishart_cholesky',
      'lkj_corr',
      'lkj_corr_cholesky',
      'logistic',
      'loglogistic',
      'lognormal',
      'multi_gp',
      'multi_gp_cholesky',
      'multinomial',
      'multinomial_logit',
      'multi_normal',
      'multi_normal_cholesky',
      'multi_normal_prec',
      'multi_student_cholesky_t',
      'multi_student_t',
      'multi_student_t_cholesky',
      'neg_binomial',
      'neg_binomial_2',
      'neg_binomial_2_log',
      'neg_binomial_2_log_glm',
      'normal',
      'normal_id_glm',
      'ordered_logistic',
      'ordered_logistic_glm',
      'ordered_probit',
      'pareto',
      'pareto_type_2',
      'poisson',
      'poisson_log',
      'poisson_log_glm',
      'rayleigh',
      'scaled_inv_chi_square',
      'skew_double_exponential',
      'skew_normal',
      'std_normal',
      'std_normal_log',
      'student_t',
      'uniform',
      'von_mises',
      'weibull',
      'wiener',
      'wishart',
      'wishart_cholesky'
    ];

    const BLOCK_COMMENT = hljs.COMMENT(
      /\/\*/,
      /\*\//,
      {
        relevance: 0,
        contains: [
          {
            scope: 'doctag',
            match: /@(return|param)/
          }
        ]
      }
    );

    const INCLUDE = {
      scope: 'meta',
      begin: /#include\b/,
      end: /$/,
      contains: [
        {
          match: /[a-z][a-z-._]+/,
          scope: 'string'
        },
        hljs.C_LINE_COMMENT_MODE
      ]
    };

    const RANGE_CONSTRAINTS = [
      "lower",
      "upper",
      "offset",
      "multiplier"
    ];

    return {
      name: 'Stan',
      aliases: [ 'stanfuncs' ],
      keywords: {
        $pattern: hljs.IDENT_RE,
        title: BLOCKS,
        type: TYPES,
        keyword: STATEMENTS,
        built_in: FUNCTIONS
      },
      contains: [
        hljs.C_LINE_COMMENT_MODE,
        INCLUDE,
        hljs.HASH_COMMENT_MODE,
        BLOCK_COMMENT,
        {
          scope: 'built_in',
          match: /\s(pi|e|sqrt2|log2|log10)(?=\()/,
          relevance: 0
        },
        {
          match: regex.concat(/[<,]\s*/, regex.either(...RANGE_CONSTRAINTS), /\s*=/),
          keywords: RANGE_CONSTRAINTS
        },
        {
          scope: 'keyword',
          match: /\btarget(?=\s*\+=)/,
        },
        {
          // highlights the 'T' in T[,] for only Stan language distributrions
          match: [
            /~\s*/,
            regex.either(...DISTRIBUTIONS),
            /(?:\(\))/,
            /\s*T(?=\s*\[)/
          ],
          scope: {
            2: "built_in",
            4: "keyword"
          }
        },
        {
          // highlights distributions that end with special endings
          scope: 'built_in',
          keywords: DISTRIBUTIONS,
          begin: regex.concat(/\w*/, regex.either(...DISTRIBUTIONS), /(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/)
        },
        {
          // highlights distributions after ~
          begin: [
            /~/,
            /\s*/,
            regex.concat(regex.either(...DISTRIBUTIONS), /(?=\s*[\(.*\)])/)
          ],
          scope: { 3: "built_in" }
        },
        {
          // highlights user defined distributions after ~
          begin: [
            /~/,
            /\s*\w+(?=\s*[\(.*\)])/,
            '(?!.*/\b(' + regex.either(...DISTRIBUTIONS) + ')\b)'
          ],
          scope: { 2: "title.function" }
        },
        {
          // highlights user defined distributions with special endings
          scope: 'title.function',
          begin: /\w*(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/
        },
        {
          scope: 'number',
          match: regex.concat(
            // Comes from @RunDevelopment accessed 11/29/2021 at
            // https://github.com/PrismJS/prism/blob/c53ad2e65b7193ab4f03a1797506a54bbb33d5a2/components/prism-stan.js#L56

            // start of big noncapture group which
            // 1. gets numbers that are by themselves
            // 2. numbers that are separated by _
            // 3. numbers that are separted by .
            /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)/,
            // grabs scientific notation
            // grabs complex numbers with i
            /(?:[eE][+-]?\d+(?:_\d+)*)?i?(?!\w)/
          ),
          relevance: 0
        },
        {
          scope: 'string',
          begin: /"/,
          end: /"/
        }
      ]
    };
  }

  return stan;

})();
;
export default hljsGrammar;