diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd6fceaddbfcd..8bec924fac1fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,8 @@ release. -14.1.0
+14.2.0
+14.1.0
14.0.0
diff --git a/common.gypi b/common.gypi index fec140bbae983b..5e4f9b6dba1dce 100644 --- a/common.gypi +++ b/common.gypi @@ -26,6 +26,7 @@ 'uv_library%': 'static_library', 'clang%': 0, + 'error_on_warn%': 'false', 'openssl_fips%': '', 'openssl_no_asm%': 0, @@ -35,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.32', + 'v8_embedder_string': '-node.33', ##### V8 defaults for Node.js ##### @@ -218,7 +219,14 @@ # Forcibly disable -Werror. We support a wide range of compilers, it's # simply not feasible to squelch all warnings, never mind that the # libraries in deps/ are not under our control. - 'cflags!': ['-Werror'], + 'conditions': [ + [ 'error_on_warn=="false"', { + 'cflags!': ['-Werror'], + }, '(_target_name!="<(node_lib_target_name)" or ' + '_target_name!="<(node_core_target_name)")', { + 'cflags!': ['-Werror'], + }], + ], 'msvs_settings': { 'VCCLCompilerTool': { 'BufferSecurityCheck': 'true', diff --git a/configure.py b/configure.py index 2e7deb5a15ef11..ac26f62916cd06 100755 --- a/configure.py +++ b/configure.py @@ -117,6 +117,11 @@ choices=valid_os, help='operating system to build for ({0})'.format(', '.join(valid_os))) +parser.add_option('--error-on-warn', + action='store_true', + dest='error_on_warn', + help='Turn compiler warnings into errors for node core sources.') + parser.add_option('--gdb', action='store_true', dest='gdb', @@ -1018,6 +1023,7 @@ def configure_node(o): o['variables']['node_install_npm'] = b(not options.without_npm) o['variables']['debug_node'] = b(options.debug_node) o['default_configuration'] = 'Debug' if options.debug else 'Release' + o['variables']['error_on_warn'] = b(options.error_on_warn) host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc() target_arch = options.dest_cpu or host_arch diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/include/fd_table.h index f29b1adf88d6f0..474a0231e03baf 100644 --- a/deps/uvwasi/include/fd_table.h +++ b/deps/uvwasi/include/fd_table.h @@ -13,6 +13,7 @@ struct uvwasi_fd_wrap_t { uv_file fd; char* path; char* real_path; + char* normalized_path; uvwasi_filetype_t type; uvwasi_rights_t rights_base; uvwasi_rights_t rights_inheriting; diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h index 39ee2f0ceb6609..f2d2d1a9fd8945 100644 --- a/deps/uvwasi/include/uvwasi.h +++ b/deps/uvwasi/include/uvwasi.h @@ -11,7 +11,7 @@ extern "C" { #define UVWASI_VERSION_MAJOR 0 #define UVWASI_VERSION_MINOR 0 -#define UVWASI_VERSION_PATCH 6 +#define UVWASI_VERSION_PATCH 8 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \ (UVWASI_VERSION_MINOR << 8) | \ (UVWASI_VERSION_PATCH)) @@ -66,7 +66,7 @@ typedef struct uvwasi_options_s { const uvwasi_mem_t* allocator; } uvwasi_options_t; -// Embedder API. +/* Embedder API. */ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options); void uvwasi_destroy(uvwasi_t* uvwasi); uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi, @@ -75,7 +75,7 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi, const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code); -// WASI system call API. +/* WASI system call API. */ uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf); uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi, size_t* argc, diff --git a/deps/uvwasi/include/wasi_types.h b/deps/uvwasi/include/wasi_types.h index ec1013663f6a76..2f93b412624c06 100644 --- a/deps/uvwasi/include/wasi_types.h +++ b/deps/uvwasi/include/wasi_types.h @@ -4,7 +4,7 @@ #include #include -/* API: https://github.com/WebAssembly/WASI/blob/master/phases/unstable/docs/wasi_unstable_preview0.md */ +/* API: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md */ typedef uint8_t uvwasi_advice_t; #define UVWASI_ADVICE_NORMAL 0 diff --git a/deps/uvwasi/src/clocks.c b/deps/uvwasi/src/clocks.c index fd42b9e50e4d8e..b59cbd6bb192c0 100644 --- a/deps/uvwasi/src/clocks.c +++ b/deps/uvwasi/src/clocks.c @@ -153,7 +153,7 @@ uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time) { UVWASI__WIN_TIME_AND_RETURN(GetCurrentThread(), *time); #elif defined(__APPLE__) UVWASI__OSX_THREADTIME_AND_RETURN(*time); -#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) +#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__) UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time); #else # if defined(RUSAGE_LWP) @@ -185,7 +185,7 @@ uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time) { UVWASI__WIN_GETRES_AND_RETURN(*time); #elif defined(__APPLE__) UVWASI__SLOW_GETRES_AND_RETURN(*time); -#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) +#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__) UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time); #elif defined(RUSAGE_THREAD) || defined(RUSAGE_LWP) UVWASI__SLOW_GETRES_AND_RETURN(*time); diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c index f6e530d9591df2..3d134e3b7e5e2e 100644 --- a/deps/uvwasi/src/fd_table.c +++ b/deps/uvwasi/src/fd_table.c @@ -8,6 +8,7 @@ #include "uv.h" #include "fd_table.h" +#include "path_resolver.h" #include "wasi_types.h" #include "wasi_rights.h" #include "uv_mapping.h" @@ -75,20 +76,33 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, char* mp_copy; size_t rp_len; char* rp_copy; + char* np_copy; mp_len = strlen(mapped_path); rp_len = strlen(real_path); + /* Reserve room for the mapped path, real path, and normalized mapped path. */ entry = (struct uvwasi_fd_wrap_t*) - uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + rp_len + 2); - if (entry == NULL) return UVWASI_ENOMEM; + uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + mp_len + rp_len + 3); + if (entry == NULL) + return UVWASI_ENOMEM; mp_copy = (char*)(entry + 1); rp_copy = mp_copy + mp_len + 1; + np_copy = rp_copy + rp_len + 1; memcpy(mp_copy, mapped_path, mp_len); mp_copy[mp_len] = '\0'; memcpy(rp_copy, real_path, rp_len); rp_copy[rp_len] = '\0'; + /* Calculate the normalized version of the mapped path, as it will be used for + any path calculations on this fd. Use the length of the mapped path as an + upper bound for the normalized path length. */ + err = uvwasi__normalize_path(mp_copy, mp_len, np_copy, mp_len); + if (err) { + uvwasi__free(uvwasi, entry); + goto exit; + } + uv_rwlock_wrlock(&table->rwlock); /* Check that there is room for a new item. If there isn't, grow the table. */ @@ -138,6 +152,7 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, entry->fd = fd; entry->path = mp_copy; entry->real_path = rp_copy; + entry->normalized_path = np_copy; entry->type = type; entry->rights_base = rights_base; entry->rights_inheriting = rights_inheriting; diff --git a/deps/uvwasi/src/path_resolver.c b/deps/uvwasi/src/path_resolver.c new file mode 100644 index 00000000000000..ee0e60f7e8f4ea --- /dev/null +++ b/deps/uvwasi/src/path_resolver.c @@ -0,0 +1,492 @@ +#include + +#include "uv.h" +#include "uvwasi.h" +#include "uvwasi_alloc.h" +#include "uv_mapping.h" +#include "path_resolver.h" + +#define UVWASI__MAX_SYMLINK_FOLLOWS 32 + +#ifndef _WIN32 +# define IS_SLASH(c) ((c) == '/') +#else +# define IS_SLASH(c) ((c) == '/' || (c) == '\\') +#endif /* _WIN32 */ + + +static int uvwasi__is_absolute_path(const char* path, size_t path_len) { + /* It's expected that only Unix style paths will be generated by WASI. */ + return path != NULL && path_len > 0 && path[0] == '/'; +} + + +static char* uvwasi__strchr_slash(const char* s) { + /* strchr() that identifies /, as well as \ on Windows. */ + do { + if (IS_SLASH(*s)) + return (char*) s; + } while (*s++); + + return NULL; +} + + +uvwasi_errno_t uvwasi__normalize_path(const char* path, + size_t path_len, + char* normalized_path, + size_t normalized_len) { + const char* cur; + char* ptr; + char* next; + char* last; + size_t cur_len; + int is_absolute; + + if (path_len > normalized_len) + return UVWASI_ENOBUFS; + + is_absolute = uvwasi__is_absolute_path(path, path_len); + normalized_path[0] = '\0'; + ptr = normalized_path; + for (cur = path; cur != NULL; cur = next + 1) { + next = uvwasi__strchr_slash(cur); + cur_len = (next == NULL) ? strlen(cur) : (size_t) (next - cur); + + if (cur_len == 0) { + if (ptr == normalized_path && next != NULL && is_absolute) { + *ptr = '/'; + ptr++; + } + + *ptr = '\0'; + } else if (cur_len == 1 && cur[0] == '.') { + /* No-op. Just consume the '.' */ + } else if (cur_len == 2 && cur[0] == '.' && cur[1] == '.') { + /* Identify the path segment that preceded the current one. */ + last = ptr; + while (!IS_SLASH(*last) && last != normalized_path) { + last--; + } + + /* If the result is currently empty, or the last prior path is also '..' + then output '..'. Otherwise, remove the last path segment. */ + if (ptr == normalized_path || + (last == ptr - 2 && last[0] == '.' && last[1] == '.') || + (last == ptr - 3 && last[0] == '/' && + last[1] == '.' && last[2] == '.')) { + if (ptr != normalized_path && *(ptr - 1) != '/') { + *ptr = '/'; + ptr++; + } + + *ptr = '.'; + ptr++; + *ptr = '.'; + ptr++; + } else { + /* Strip the last segment, but make sure not to strip the '/' if that + is the entire path. */ + if (last == normalized_path && *last == '/') + ptr = last + 1; + else + ptr = last; + } + + *ptr = '\0'; + } else { + if (ptr != normalized_path && *(ptr - 1) != '/') { + *ptr = '/'; + ptr++; + } + + memcpy(ptr, cur, cur_len); + ptr += cur_len; + *ptr = '\0'; + } + + if (next == NULL) + break; + } + + /* Normalized the path to the empty string. Return either '/' or '.'. */ + if (ptr == normalized_path) { + if (1 == is_absolute) + *ptr = '/'; + else + *ptr = '.'; + + ptr++; + *ptr = '\0'; + } + + return UVWASI_ESUCCESS; +} + + +static int uvwasi__is_path_sandboxed(const char* path, + size_t path_len, + const char* fd_path, + size_t fd_path_len) { + char* ptr; + int remaining_len; + + if (1 == uvwasi__is_absolute_path(fd_path, fd_path_len)) + return path == strstr(path, fd_path) ? 1 : 0; + + /* Handle relative fds that normalized to '.' */ + if (fd_path_len == 1 && fd_path[0] == '.') { + /* If the fd's path is '.', then any path does not begin with '..' is OK. */ + if ((path_len == 2 && path[0] == '.' && path[1] == '.') || + (path_len > 2 && path[0] == '.' && path[1] == '.' && path[2] == '/')) { + return 0; + } + + return 1; + } + + if (path != strstr(path, fd_path)) + return 0; + + /* Fail if the remaining path starts with '..', '../', '/..', or '/../'. */ + ptr = (char*) path + fd_path_len; + remaining_len = path_len - fd_path_len; + if (remaining_len < 2) + return 1; + + /* Strip a leading slash so the check is only for '..' and '../'. */ + if (*ptr == '/') { + ptr++; + remaining_len--; + } + + if ((remaining_len == 2 && ptr[0] == '.' && ptr[1] == '.') || + (remaining_len > 2 && ptr[0] == '.' && ptr[1] == '.' && ptr[2] == '/')) { + return 0; + } + + return 1; +} + + +static uvwasi_errno_t uvwasi__normalize_absolute_path( + const uvwasi_t* uvwasi, + const struct uvwasi_fd_wrap_t* fd, + const char* path, + size_t path_len, + char** normalized_path, + size_t* normalized_len + ) { + /* This function resolves an absolute path to the provided file descriptor. + If the file descriptor's path is relative, then this operation will fail + with UVWASI_ENOTCAPABLE since it doesn't make sense to resolve an absolute + path to a relative prefix. If the file desciptor's path is also absolute, + then we just need to verify that the normalized path still starts with + the file descriptor's path. */ + uvwasi_errno_t err; + char* abs_path; + int abs_size; + + *normalized_path = NULL; + *normalized_len = 0; + abs_size = path_len + 1; + abs_path = uvwasi__malloc(uvwasi, abs_size); + if (abs_path == NULL) { + err = UVWASI_ENOMEM; + goto exit; + } + + /* Normalize the input path first. */ + err = uvwasi__normalize_path(path, path_len, abs_path, path_len); + if (err != UVWASI_ESUCCESS) + goto exit; + + /* Once the input is normalized, ensure that it is still sandboxed. */ + if (0 == uvwasi__is_path_sandboxed(abs_path, + path_len, + fd->normalized_path, + strlen(fd->normalized_path))) { + err = UVWASI_ENOTCAPABLE; + goto exit; + } + + *normalized_path = abs_path; + *normalized_len = abs_size - 1; + return UVWASI_ESUCCESS; + +exit: + uvwasi__free(uvwasi, abs_path); + return err; +} + + +static uvwasi_errno_t uvwasi__normalize_relative_path( + const uvwasi_t* uvwasi, + const struct uvwasi_fd_wrap_t* fd, + const char* path, + size_t path_len, + char** normalized_path, + size_t* normalized_len + ) { + /* This function resolves a relative path to the provided file descriptor. + The relative path is concatenated to the file descriptor's path, and then + normalized. */ + uvwasi_errno_t err; + char* combined; + char* normalized; + int combined_size; + int fd_path_len; + int norm_len; + int r; + + *normalized_path = NULL; + *normalized_len = 0; + + /* The max combined size is the path length + the file descriptor's path + length + 2 for a terminating NULL and a possible path separator. */ + fd_path_len = strlen(fd->normalized_path); + combined_size = path_len + fd_path_len + 2; + combined = uvwasi__malloc(uvwasi, combined_size); + if (combined == NULL) + return UVWASI_ENOMEM; + + normalized = uvwasi__malloc(uvwasi, combined_size); + if (normalized == NULL) { + err = UVWASI_ENOMEM; + goto exit; + } + + r = snprintf(combined, combined_size, "%s/%s", fd->normalized_path, path); + if (r <= 0) { + err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); + goto exit; + } + + /* Normalize the input path. */ + err = uvwasi__normalize_path(combined, + combined_size - 1, + normalized, + combined_size - 1); + if (err != UVWASI_ESUCCESS) + goto exit; + + norm_len = strlen(normalized); + + /* Once the path is normalized, ensure that it is still sandboxed. */ + if (0 == uvwasi__is_path_sandboxed(normalized, + norm_len, + fd->normalized_path, + fd_path_len)) { + err = UVWASI_ENOTCAPABLE; + goto exit; + } + + err = UVWASI_ESUCCESS; + *normalized_path = normalized; + *normalized_len = norm_len; + +exit: + if (err != UVWASI_ESUCCESS) + uvwasi__free(uvwasi, normalized); + + uvwasi__free(uvwasi, combined); + return err; +} + + +static uvwasi_errno_t uvwasi__resolve_path_to_host( + const uvwasi_t* uvwasi, + const struct uvwasi_fd_wrap_t* fd, + const char* path, + size_t path_len, + char** resolved_path, + size_t* resolved_len + ) { + /* Return the normalized path, but resolved to the host's real path. */ + char* res_path; + char* stripped_path; + int real_path_len; + int fake_path_len; + int stripped_len; +#ifdef _WIN32 + size_t i; +#endif /* _WIN32 */ + + real_path_len = strlen(fd->real_path); + fake_path_len = strlen(fd->normalized_path); + + /* If the fake path is '.' just ignore it. */ + if (fake_path_len == 1 && fd->normalized_path[0] == '.') { + fake_path_len = 0; + } + + stripped_len = path_len - fake_path_len; + + /* The resolved path's length is calculated as: the length of the fd's real + path, + 1 for a path separator, and the length of the input path (with the + fake path stripped off). */ + *resolved_len = stripped_len + real_path_len + 1; + *resolved_path = uvwasi__malloc(uvwasi, *resolved_len + 1); + + if (*resolved_path == NULL) + return UVWASI_ENOMEM; + + res_path = *resolved_path; + stripped_path = (char*) path + fake_path_len; + memcpy(res_path, fd->real_path, real_path_len); + res_path += real_path_len; + + if (stripped_len > 1 || + (stripped_len == 1 && stripped_path[0] != '/')) { + if (stripped_path[0] != '/') { + *res_path = '/'; + res_path++; + } + + memcpy(res_path, stripped_path, stripped_len); + res_path += stripped_len; + } + + *res_path = '\0'; + +#ifdef _WIN32 + /* Replace / with \ on Windows. */ + for (i = real_path_len; i < *resolved_len; i++) { + if (res_path[i] == '/') + res_path[i] = '\\'; + } +#endif /* _WIN32 */ + + return UVWASI_ESUCCESS; +} + + +uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, + const struct uvwasi_fd_wrap_t* fd, + const char* path, + size_t path_len, + char* resolved_path, + uvwasi_lookupflags_t flags) { + uv_fs_t req; + uvwasi_errno_t err; + const char* input; + char* host_path; + char* normalized_path; + char* link_target; + size_t input_len; + size_t host_path_len; + size_t normalized_len; + int follow_count; + int r; + + input = path; + input_len = path_len; + link_target = NULL; + follow_count = 0; + host_path = NULL; + +start: + normalized_path = NULL; + err = UVWASI_ESUCCESS; + + if (1 == uvwasi__is_absolute_path(input, input_len)) { + err = uvwasi__normalize_absolute_path(uvwasi, + fd, + input, + input_len, + &normalized_path, + &normalized_len); + } else { + err = uvwasi__normalize_relative_path(uvwasi, + fd, + input, + input_len, + &normalized_path, + &normalized_len); + } + + if (err != UVWASI_ESUCCESS) + goto exit; + + uvwasi__free(uvwasi, host_path); + err = uvwasi__resolve_path_to_host(uvwasi, + fd, + normalized_path, + normalized_len, + &host_path, + &host_path_len); + if (err != UVWASI_ESUCCESS) + goto exit; + + /* TODO(cjihrig): Currently performing a bounds check here. The TODO is to + stop allocating resolved_path in every caller and instead return the + path allocated in this function. */ + if (host_path_len > PATH_MAX_BYTES) { + err = UVWASI_ENOBUFS; + goto exit; + } + + if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) { + r = uv_fs_readlink(NULL, &req, host_path, NULL); + + if (r != 0) { +#ifdef _WIN32 + /* uv_fs_readlink() returns UV__UNKNOWN on Windows. Try to get a better + error using uv_fs_stat(). */ + if (r == UV__UNKNOWN) { + uv_fs_req_cleanup(&req); + r = uv_fs_stat(NULL, &req, host_path, NULL); + + if (r == 0) { + if (uvwasi__stat_to_filetype(&req.statbuf) != + UVWASI_FILETYPE_SYMBOLIC_LINK) { + r = UV_EINVAL; + } + } + + /* Fall through. */ + } +#endif /* _WIN32 */ + + /* Don't report UV_EINVAL or UV_ENOENT. They mean that either the file + does not exist, or it is not a symlink. Both are OK. */ + if (r != UV_EINVAL && r != UV_ENOENT) + err = uvwasi__translate_uv_error(r); + + uv_fs_req_cleanup(&req); + goto exit; + } + + /* Clean up memory and follow the link, unless it's time to return ELOOP. */ + follow_count++; + if (follow_count >= UVWASI__MAX_SYMLINK_FOLLOWS) { + uv_fs_req_cleanup(&req); + err = UVWASI_ELOOP; + goto exit; + } + + input_len = strlen(req.ptr); + uvwasi__free(uvwasi, link_target); + link_target = uvwasi__malloc(uvwasi, input_len + 1); + if (link_target == NULL) { + uv_fs_req_cleanup(&req); + err = UVWASI_ENOMEM; + goto exit; + } + + memcpy(link_target, req.ptr, input_len + 1); + input = link_target; + uvwasi__free(uvwasi, normalized_path); + uv_fs_req_cleanup(&req); + goto start; + } + +exit: + if (err == UVWASI_ESUCCESS) + memcpy(resolved_path, host_path, host_path_len + 1); + + uvwasi__free(uvwasi, link_target); + uvwasi__free(uvwasi, normalized_path); + uvwasi__free(uvwasi, host_path); + return err; +} diff --git a/deps/uvwasi/src/path_resolver.h b/deps/uvwasi/src/path_resolver.h new file mode 100644 index 00000000000000..d5f95eafbfbf83 --- /dev/null +++ b/deps/uvwasi/src/path_resolver.h @@ -0,0 +1,28 @@ +#ifndef __UVWASI_PATH_RESOLVER_H__ +#define __UVWASI_PATH_RESOLVER_H__ + +#include "uvwasi.h" + +/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths + can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */ +#ifdef _WIN32 +/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ +# define PATH_MAX_BYTES (MAX_PATH * 4) +#else +# include +# define PATH_MAX_BYTES (PATH_MAX) +#endif + +uvwasi_errno_t uvwasi__normalize_path(const char* path, + size_t path_len, + char* normalized_path, + size_t normalized_len); + +uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, + const struct uvwasi_fd_wrap_t* fd, + const char* path, + size_t path_len, + char* resolved_path, + uvwasi_lookupflags_t flags); + +#endif /* __UVWASI_PATH_RESOLVER_H__ */ diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c index c80fc7715c1dc0..0ee66be36a3951 100644 --- a/deps/uvwasi/src/uvwasi.c +++ b/deps/uvwasi/src/uvwasi.c @@ -7,14 +7,11 @@ # include # include # include -# define IS_SLASH(c) ((c) == '/') #else # include -# define IS_SLASH(c) ((c) == '/' || (c) == '\\') #endif /* _WIN32 */ #define UVWASI__READDIR_NUM_ENTRIES 1 -#define UVWASI__MAX_SYMLINK_FOLLOWS 32 #include "uvwasi.h" #include "uvwasi_alloc.h" @@ -22,18 +19,9 @@ #include "uv_mapping.h" #include "fd_table.h" #include "clocks.h" +#include "path_resolver.h" #include "wasi_rights.h" -/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths - can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */ -#ifdef _WIN32 -/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ -# define PATH_MAX_BYTES (MAX_PATH * 4) -#else -# include -# define PATH_MAX_BYTES (PATH_MAX) -#endif - /* IBMi PASE does not support posix_fadvise() */ #ifdef __PASE__ # undef POSIX_FADV_NORMAL @@ -84,322 +72,6 @@ static const uvwasi_mem_t default_allocator = { }; -static int uvwasi__is_absolute_path(const char* path, size_t path_len) { - /* It's expected that only Unix style paths will be generated by WASI. */ - return path != NULL && path_len > 0 && path[0] == '/'; -} - - -static char* uvwasi__strchr_slash(const char* s) { - /* strchr() that identifies /, as well as \ on Windows. */ - do { - if (IS_SLASH(*s)) - return (char*) s; - } while (*s++); - - return NULL; -} - - -static uvwasi_errno_t uvwasi__normalize_path(const char* path, - size_t path_len, - char* normalized_path, - size_t normalized_len) { - const char* cur; - char* ptr; - char* next; - size_t cur_len; - - if (path_len > normalized_len) - return UVWASI_ENOBUFS; - - normalized_path[0] = '\0'; - ptr = normalized_path; - for (cur = path; cur != NULL; cur = next + 1) { - next = uvwasi__strchr_slash(cur); - cur_len = (next == NULL) ? strlen(cur) : (size_t) (next - cur); - - if (cur_len == 0 || (cur_len == 1 && cur[0] == '.')) - continue; - - if (cur_len == 2 && cur[0] == '.' && cur[1] == '.') { - while (!IS_SLASH(*ptr) && ptr != normalized_path) - ptr--; - *ptr = '\0'; - continue; - } - - *ptr = '/'; - ptr++; - memcpy(ptr, cur, cur_len); - ptr += cur_len; - *ptr = '\0'; - - if (next == NULL) - break; - } - - return UVWASI_ESUCCESS; -} - - -static uvwasi_errno_t uvwasi__resolve_path_to_host( - const uvwasi_t* uvwasi, - const struct uvwasi_fd_wrap_t* fd, - const char* path, - size_t path_len, - char** resolved_path, - size_t* resolved_len - ) { - /* Return the normalized path, but resolved to the host's real path. */ - int real_path_len; - int fake_path_len; -#ifdef _WIN32 - size_t i; -#endif /* _WIN32 */ - - real_path_len = strlen(fd->real_path); - fake_path_len = strlen(fd->path); - *resolved_len = path_len - fake_path_len + real_path_len; - *resolved_path = uvwasi__malloc(uvwasi, *resolved_len + 1); - - if (*resolved_path == NULL) - return UVWASI_ENOMEM; - - memcpy(*resolved_path, fd->real_path, real_path_len); - memcpy(*resolved_path + real_path_len, - path + fake_path_len, - path_len - fake_path_len + 1); - -#ifdef _WIN32 - /* Replace / with \ on Windows. */ - for (i = real_path_len; i < *resolved_len; i++) { - if ((*resolved_path)[i] == '/') - (*resolved_path)[i] = '\\'; - } -#endif /* _WIN32 */ - - return UVWASI_ESUCCESS; -} - - -static uvwasi_errno_t uvwasi__normalize_absolute_path( - const uvwasi_t* uvwasi, - const struct uvwasi_fd_wrap_t* fd, - const char* path, - size_t path_len, - char** normalized_path, - size_t* normalized_len - ) { - uvwasi_errno_t err; - char* abs_path; - int abs_size; - - *normalized_path = NULL; - *normalized_len = 0; - abs_size = path_len + 1; - abs_path = uvwasi__malloc(uvwasi, abs_size); - if (abs_path == NULL) { - err = UVWASI_ENOMEM; - goto exit; - } - - /* Normalize the input path first. */ - err = uvwasi__normalize_path(path, - path_len, - abs_path, - path_len); - if (err != UVWASI_ESUCCESS) - goto exit; - - /* Once the input is normalized, ensure that it is still sandboxed. */ - if (abs_path != strstr(abs_path, fd->path)) { - err = UVWASI_ENOTCAPABLE; - goto exit; - } - - *normalized_path = abs_path; - *normalized_len = abs_size - 1; - return UVWASI_ESUCCESS; - -exit: - uvwasi__free(uvwasi, abs_path); - return err; -} - - -static uvwasi_errno_t uvwasi__normalize_relative_path( - const uvwasi_t* uvwasi, - const struct uvwasi_fd_wrap_t* fd, - const char* path, - size_t path_len, - char** normalized_path, - size_t* normalized_len - ) { - uvwasi_errno_t err; - char* abs_path; - int abs_size; - int r; - - *normalized_path = NULL; - *normalized_len = 0; - abs_size = path_len + strlen(fd->path) + 2; - abs_path = uvwasi__malloc(uvwasi, abs_size); - if (abs_path == NULL) { - err = UVWASI_ENOMEM; - goto exit; - } - - /* Resolve the relative path to an absolute path based on fd's fake path. */ - r = snprintf(abs_path, abs_size, "%s/%s", fd->path, path); - if (r <= 0) { - err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); - goto exit; - } - - err = uvwasi__normalize_absolute_path(uvwasi, - fd, - abs_path, - abs_size - 1, - normalized_path, - normalized_len); -exit: - uvwasi__free(uvwasi, abs_path); - return err; -} - - -static uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, - const struct uvwasi_fd_wrap_t* fd, - const char* path, - size_t path_len, - char* resolved_path, - uvwasi_lookupflags_t flags) { - uv_fs_t req; - uvwasi_errno_t err; - const char* input; - char* host_path; - char* normalized_path; - char* link_target; - size_t input_len; - size_t host_path_len; - size_t normalized_len; - int follow_count; - int r; - - input = path; - input_len = path_len; - link_target = NULL; - follow_count = 0; - host_path = NULL; - -start: - normalized_path = NULL; - err = UVWASI_ESUCCESS; - - if (1 == uvwasi__is_absolute_path(input, input_len)) { - err = uvwasi__normalize_absolute_path(uvwasi, - fd, - input, - input_len, - &normalized_path, - &normalized_len); - } else { - err = uvwasi__normalize_relative_path(uvwasi, - fd, - input, - input_len, - &normalized_path, - &normalized_len); - } - - if (err != UVWASI_ESUCCESS) - goto exit; - - uvwasi__free(uvwasi, host_path); - err = uvwasi__resolve_path_to_host(uvwasi, - fd, - normalized_path, - normalized_len, - &host_path, - &host_path_len); - if (err != UVWASI_ESUCCESS) - goto exit; - - /* TODO(cjihrig): Currently performing a bounds check here. The TODO is to - stop allocating resolved_path in every caller and instead return the - path allocated in this function. */ - if (host_path_len > PATH_MAX_BYTES) { - err = UVWASI_ENOBUFS; - goto exit; - } - - if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) { - r = uv_fs_readlink(NULL, &req, host_path, NULL); - - if (r != 0) { -#ifdef _WIN32 - /* uv_fs_readlink() returns UV__UNKNOWN on Windows. Try to get a better - error using uv_fs_stat(). */ - if (r == UV__UNKNOWN) { - uv_fs_req_cleanup(&req); - r = uv_fs_stat(NULL, &req, host_path, NULL); - - if (r == 0) { - if (uvwasi__stat_to_filetype(&req.statbuf) != - UVWASI_FILETYPE_SYMBOLIC_LINK) { - r = UV_EINVAL; - } - } - - // Fall through. - } -#endif /* _WIN32 */ - - /* Don't report UV_EINVAL or UV_ENOENT. They mean that either the file - does not exist, or it is not a symlink. Both are OK. */ - if (r != UV_EINVAL && r != UV_ENOENT) - err = uvwasi__translate_uv_error(r); - - uv_fs_req_cleanup(&req); - goto exit; - } - - /* Clean up memory and follow the link, unless it's time to return ELOOP. */ - follow_count++; - if (follow_count >= UVWASI__MAX_SYMLINK_FOLLOWS) { - uv_fs_req_cleanup(&req); - err = UVWASI_ELOOP; - goto exit; - } - - input_len = strlen(req.ptr); - uvwasi__free(uvwasi, link_target); - link_target = uvwasi__malloc(uvwasi, input_len + 1); - if (link_target == NULL) { - uv_fs_req_cleanup(&req); - err = UVWASI_ENOMEM; - goto exit; - } - - memcpy(link_target, req.ptr, input_len + 1); - input = link_target; - uvwasi__free(uvwasi, normalized_path); - uv_fs_req_cleanup(&req); - goto start; - } - -exit: - if (err == UVWASI_ESUCCESS) - memcpy(resolved_path, host_path, host_path_len + 1); - - uvwasi__free(uvwasi, link_target); - uvwasi__free(uvwasi, normalized_path); - uvwasi__free(uvwasi, host_path); - return err; -} - - static uvwasi_errno_t uvwasi__lseek(uv_file fd, uvwasi_filedelta_t offset, uvwasi_whence_t whence, diff --git a/deps/uvwasi/uvwasi.gyp b/deps/uvwasi/uvwasi.gyp index 6963cbf20a7923..42769095ecbafd 100644 --- a/deps/uvwasi/uvwasi.gyp +++ b/deps/uvwasi/uvwasi.gyp @@ -11,6 +11,7 @@ 'sources': [ 'src/clocks.c', 'src/fd_table.c', + 'src/path_resolver.c', 'src/uv_mapping.c', 'src/uvwasi.c', 'src/wasi_rights.c', diff --git a/deps/v8/src/objects/backing-store.cc b/deps/v8/src/objects/backing-store.cc index 8d604ba35d8d06..c9a5c2e4c8ec20 100644 --- a/deps/v8/src/objects/backing-store.cc +++ b/deps/v8/src/objects/backing-store.cc @@ -164,7 +164,10 @@ void BackingStore::Clear() { BackingStore::~BackingStore() { GlobalBackingStoreRegistry::Unregister(this); - if (buffer_start_ == nullptr) return; // nothing to deallocate + if (buffer_start_ == nullptr) { + Clear(); + return; + } if (is_wasm_memory_) { DCHECK(free_on_destruct_); diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc index e8e026f156053d..eeddbcca1003be 100644 --- a/deps/v8/test/cctest/test-api-array-buffer.cc +++ b/deps/v8/test/cctest/test-api-array-buffer.cc @@ -729,6 +729,46 @@ TEST(BackingStore_HoldAllocatorAlive_UntilIsolateShutdown) { CHECK(allocator_weak.expired()); } +class NullptrAllocator final : public v8::ArrayBuffer::Allocator { + public: + void* Allocate(size_t length) override { + CHECK_EQ(length, 0); + return nullptr; + } + void* AllocateUninitialized(size_t length) override { + CHECK_EQ(length, 0); + return nullptr; + } + void Free(void* data, size_t length) override { CHECK_EQ(data, nullptr); } +}; + +TEST(BackingStore_ReleaseAllocator_NullptrBackingStore) { + std::shared_ptr allocator = + std::make_shared(); + std::weak_ptr allocator_weak(allocator); + + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator_shared = allocator; + v8::Isolate* isolate = v8::Isolate::New(create_params); + isolate->Enter(); + + allocator.reset(); + create_params.array_buffer_allocator_shared.reset(); + CHECK(!allocator_weak.expired()); + + { + std::shared_ptr backing_store = + v8::ArrayBuffer::NewBackingStore(isolate, 0); + // This should release a reference to the allocator, even though the + // buffer is empty/nullptr. + backing_store.reset(); + } + + isolate->Exit(); + isolate->Dispose(); + CHECK(allocator_weak.expired()); +} + TEST(BackingStore_HoldAllocatorAlive_AfterIsolateShutdown) { std::shared_ptr allocator = std::make_shared(); diff --git a/doc/api/assert.md b/doc/api/assert.md index 9731ddaa13f315..9ad01a48f0fd9a 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -149,6 +149,144 @@ try { } ``` +## Class: `assert.CallTracker` + + +> Stability: 1 - Experimental + +This feature is currently experimental and behavior might still change. + +### `new assert.CallTracker()` + + +Creates a new [`CallTracker`][] object which can be used to track if functions +were called a specific number of times. The `tracker.verify()` must be called +for the verification to take place. The usual pattern would be to call it in a +[`process.on('exit')`][] handler. + +```js +const assert = require('assert'); + +const tracker = new assert.CallTracker(); + +function func() {} + +// callsfunc() must be called exactly 1 time before tracker.verify(). +const callsfunc = tracker.calls(func, 1); + +callsfunc(); + +// Calls tracker.verify() and verifies if all tracker.calls() functions have +// been called exact times. +process.on('exit', () => { + tracker.verify(); +}); +``` + +### `tracker.calls([fn][, exact])` + + +* `fn` {Function} **Default** A no-op function. +* `exact` {number} **Default** `1`. +* Returns: {Function} that wraps `fn`. + +The wrapper function is expected to be called exactly `exact` times. If the +function has not been called exactly `exact` times when +[`tracker.verify()`][] is called, then [`tracker.verify()`][] will throw an +error. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func); +``` + +### `tracker.report()` + + +* Returns: {Array} of objects containing information about the wrapper functions +returned by [`tracker.calls()`][]. +* Object {Object} + * `message` {string} + * `actual` {number} The actual number of times the function was called. + * `expected` {number} The number of times the function was expected to be + called. + * `operator` {string} The name of the function that is wrapped. + * `stack` {Object} A stack trace of the function. + +The arrays contains information about the expected and actual number of calls of +the functions that have not been called the expected number of times. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +function foo() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func, 2); + +// Returns an array containing information on callsfunc() +tracker.report(); +// [ +// { +// message: 'Expected the func function to be executed 2 time(s) but was +// executed 0 time(s).', +// actual: 0, +// expected: 2, +// operator: 'func', +// stack: stack trace +// } +// ] +``` + +### `tracker.verify()` + + +Iterates through the list of functions passed to +[`tracker.calls()`][] and will throw an error for functions that +have not been called the expected number of times. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func, 2); + +callsfunc(); + +// Will throw an error since callsfunc() was only called once. +tracker.verify(); +``` + ## `assert(value[, message])` * `options` {Object} @@ -107,6 +110,8 @@ changes: **Default:** `'auto'`. * `inspectOptions` {Object} Specifies options that are passed along to [`util.inspect()`][]. + * `groupIndentation` {number} Set group indentation. + **Default:** `2`. Creates a new `Console` with one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` is used for warning or @@ -306,7 +311,8 @@ added: v8.5.0 * `...label` {any} -Increases indentation of subsequent lines by two spaces. +Increases indentation of subsequent lines by spaces for `groupIndentation` +length. If one or more `label`s are provided, those are printed first without the additional indentation. @@ -323,7 +329,8 @@ An alias for [`console.group()`][]. added: v8.5.0 --> -Decreases indentation of subsequent lines by two spaces. +Decreases indentation of subsequent lines by spaces for `groupIndentation` +length. ### `console.info([data][, ...args])` +> Stability: 0 - Deprecated: Use [`request.destroy()`][] instead. + Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed. diff --git a/doc/api/http2.md b/doc/api/http2.md index c4365f4e20e869..6f3b70be3a03f4 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -913,8 +913,9 @@ the value is `undefined`, the stream is not yet ready for use. All [`Http2Stream`][] instances are destroyed either when: * An `RST_STREAM` frame for the stream is received by the connected peer, - and pending data has been read. -* The `http2stream.close()` method is called, and pending data has been read. + and (for client streams only) pending data has been read. +* The `http2stream.close()` method is called, and (for client streams only) + pending data has been read. * The `http2stream.destroy()` or `http2session.destroy()` methods are called. When an `Http2Stream` instance is destroyed, an attempt will be made to send an diff --git a/doc/api/os.md b/doc/api/os.md index e2cce1f8a5580f..d70bd2d260b3ac 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -389,7 +389,7 @@ operating system response. Throws a [`SystemError`][] if a user has no `username` or `homedir`. -## `os.version()` +## `os.version()` diff --git a/doc/api/stream.md b/doc/api/stream.md index e8993849090199..6229704eb91bc4 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1442,7 +1442,7 @@ If the loop terminates with a `break` or a `throw`, the stream will be destroyed. In other terms, iterating over a stream will consume the stream fully. The stream will be read in chunks of size equal to the `highWaterMark` option. In the code example above, data will be in a single chunk if the file -has less then 64kb of data because no `highWaterMark` option is provided to +has less then 64KB of data because no `highWaterMark` option is provided to [`fs.createReadStream()`][]. ### Duplex and Transform Streams @@ -1700,7 +1700,8 @@ added: --> * `iterable` {Iterable} Object implementing the `Symbol.asyncIterator` or - `Symbol.iterator` iterable protocol. + `Symbol.iterator` iterable protocol. Emits an 'error' event if a null + value is passed. * `options` {Object} Options provided to `new stream.Readable([options])`. By default, `Readable.from()` will set `options.objectMode` to `true`, unless this is explicitly opted out by setting `options.objectMode` to `false`. @@ -1829,7 +1830,7 @@ changes: * `options` {Object} * `highWaterMark` {number} Buffer level when [`stream.write()`][stream-write] starts returning `false`. **Default:** - `16384` (16kb), or `16` for `objectMode` streams. + `16384` (16KB), or `16` for `objectMode` streams. * `decodeStrings` {boolean} Whether to encode `string`s passed to [`stream.write()`][stream-write] to `Buffer`s (with the encoding specified in the [`stream.write()`][stream-write] call) before passing @@ -2111,7 +2112,7 @@ changes: * `options` {Object} * `highWaterMark` {number} The maximum [number of bytes][hwm-gotcha] to store in the internal buffer before ceasing to read from the underlying resource. - **Default:** `16384` (16kb), or `16` for `objectMode` streams. + **Default:** `16384` (16KB), or `16` for `objectMode` streams. * `encoding` {string} If specified, then buffers will be decoded to strings using the specified encoding. **Default:** `null`. * `objectMode` {boolean} Whether this stream should behave diff --git a/doc/api/util.md b/doc/api/util.md index 757c6a48f6ece9..567ac5f7523260 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1259,6 +1259,25 @@ util.types.isAnyArrayBuffer(new ArrayBuffer()); // Returns true util.types.isAnyArrayBuffer(new SharedArrayBuffer()); // Returns true ``` +### `util.types.isArrayBufferView(value)` + + +* `value` {any} +* Returns: {boolean} + +Returns `true` if the value is an instance of one of the [`ArrayBuffer`][] +views, such as typed array objects or [`DataView`][]. Equivalent to +[`ArrayBuffer.isView()`][]. + +```js +util.types.isArrayBufferView(new Int8Array()); // true +util.types.isArrayBufferView(Buffer.from('hello world')); // true +util.types.isArrayBufferView(new DataView(new ArrayBuffer(16))); // true +util.types.isArrayBufferView(new ArrayBuffer()); // false +``` + ### `util.types.isArgumentsObject(value)` +```js +const assert = require('assert'); + +const tracker = new assert.CallTracker(); + +function func() {} +const callsfunc = tracker.calls(func); + +console.log(tracker.report()); +/* +[ + { + message: 'Expected the func function to be executed 1 time(s) but was executed 0 time(s).', + actual: 0, + expected: 1, + operator: 'func', + stack: Error + ... + } +] +*/ +``` + +Contributed by ConorDavenport - [#31982](https://github.com/nodejs/node/pull/31982). + +#### Console `groupIndentation` option + +The Console constructor (`require('console').Console`) now supports different group indentations. + +This is useful in case you want different grouping width than 2 spaces. + +```js +const { Console } = require('console'); +const customConsole = new Console({ + stdout: process.stdout, + stderr: process.stderr, + groupIndentation: 10 +}); + +customConsole.log('foo'); +// 'foo' +customConsole.group(); +customConsole.log('foo'); +// 'foo' +``` + +Contributed by rickyes - [#32964](https://github.com/nodejs/node/pull/32964). + +### Commits + +#### Semver-minor commits + +* [[`c87ed21fdf`](https://github.com/nodejs/node/commit/c87ed21fdf)] - **(SEMVER-MINOR)** **assert**: port common.mustCall() to assert (ConorDavenport) [#31982](https://github.com/nodejs/node/pull/31982) +* [[`c49e3ea20c`](https://github.com/nodejs/node/commit/c49e3ea20c)] - **(SEMVER-MINOR)** **console**: support console constructor groupIndentation option (rickyes) [#32964](https://github.com/nodejs/node/pull/32964) +* [[`bc9e413dae`](https://github.com/nodejs/node/commit/bc9e413dae)] - **(SEMVER-MINOR)** **worker**: add stack size resource limit option (Anna Henningsen) [#33085](https://github.com/nodejs/node/pull/33085) + +#### Semver-patch commits + +* [[`f62d92b900`](https://github.com/nodejs/node/commit/f62d92b900)] - **build**: add --error-on-warn configure flag (Daniel Bevenius) [#32685](https://github.com/nodejs/node/pull/32685) +* [[`db293c47dd`](https://github.com/nodejs/node/commit/db293c47dd)] - **cluster**: fix error on worker disconnect/destroy (Santiago Gimeno) [#32793](https://github.com/nodejs/node/pull/32793) +* [[`83e165bf88`](https://github.com/nodejs/node/commit/83e165bf88)] - **crypto**: check DiffieHellman p and g params (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`e07cca6af6`](https://github.com/nodejs/node/commit/e07cca6af6)] - **crypto**: generator must be int32 in DiffieHellman() (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`637442fec9`](https://github.com/nodejs/node/commit/637442fec9)] - **crypto**: key size must be int32 in DiffieHellman() (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`c5a4534d5c`](https://github.com/nodejs/node/commit/c5a4534d5c)] - **deps**: V8: backport e29c62b74854 (Anna Henningsen) [#33125](https://github.com/nodejs/node/pull/33125) +* [[`8325c29e92`](https://github.com/nodejs/node/commit/8325c29e92)] - **deps**: update to uvwasi 0.0.8 (Colin Ihrig) [#33078](https://github.com/nodejs/node/pull/33078) +* [[`2174159598`](https://github.com/nodejs/node/commit/2174159598)] - **esm**: improve commonjs hint on module not found (Daniele Belardi) [#31906](https://github.com/nodejs/node/pull/31906) +* [[`74b0e8c3a8`](https://github.com/nodejs/node/commit/74b0e8c3a8)] - **http**: ensure client request emits close (Robert Nagy) [#33178](https://github.com/nodejs/node/pull/33178) +* [[`a4ec01c55b`](https://github.com/nodejs/node/commit/a4ec01c55b)] - **http**: simplify sending header (Robert Nagy) [#33200](https://github.com/nodejs/node/pull/33200) +* [[`451993ea94`](https://github.com/nodejs/node/commit/451993ea94)] - **http**: set default timeout in agent keepSocketAlive (Owen Smith) [#33127](https://github.com/nodejs/node/pull/33127) +* [[`3cb1713a59`](https://github.com/nodejs/node/commit/3cb1713a59)] - **http2,doc**: minor fixes (Alba Mendez) [#28044](https://github.com/nodejs/node/pull/28044) +* [[`eab4be1b93`](https://github.com/nodejs/node/commit/eab4be1b93)] - **lib**: cosmetic change to builtinLibs list for maintainability (James M Snell) [#33106](https://github.com/nodejs/node/pull/33106) +* [[`542da430ff`](https://github.com/nodejs/node/commit/542da430ff)] - **lib**: fix validateport error message when allowZero is false (rickyes) [#32861](https://github.com/nodejs/node/pull/32861) +* [[`5eccf1e9ad`](https://github.com/nodejs/node/commit/5eccf1e9ad)] - **module**: no type module resolver side effects (Guy Bedford) [#33086](https://github.com/nodejs/node/pull/33086) +* [[`466213d726`](https://github.com/nodejs/node/commit/466213d726)] - **n-api**: simplify uv\_idle wrangling (Ben Noordhuis) [#32997](https://github.com/nodejs/node/pull/32997) +* [[`ed45b51642`](https://github.com/nodejs/node/commit/ed45b51642)] - **path**: fix comment grammar (thecodrr) [#32942](https://github.com/nodejs/node/pull/32942) +* [[`bb2d2f6e0e`](https://github.com/nodejs/node/commit/bb2d2f6e0e)] - **src**: remove unused v8 Message namespace (Adrian Estrada) [#33180](https://github.com/nodejs/node/pull/33180) +* [[`de643bc325`](https://github.com/nodejs/node/commit/de643bc325)] - **src**: use unique\_ptr for CachedData in ContextifyScript::New (Anna Henningsen) [#33113](https://github.com/nodejs/node/pull/33113) +* [[`f61928ba35`](https://github.com/nodejs/node/commit/f61928ba35)] - **src**: return undefined when validation err == 0 (James M Snell) [#33107](https://github.com/nodejs/node/pull/33107) +* [[`f4e5ab14da`](https://github.com/nodejs/node/commit/f4e5ab14da)] - **src**: crypto::UseSNIContext to use BaseObjectPtr (James M Snell) [#33107](https://github.com/nodejs/node/pull/33107) +* [[`541ea035bf`](https://github.com/nodejs/node/commit/541ea035bf)] - **src**: separate out NgLibMemoryManagerBase (James M Snell) [#33104](https://github.com/nodejs/node/pull/33104) +* [[`10a87c81cf`](https://github.com/nodejs/node/commit/10a87c81cf)] - **src**: remove unnecessary fully qualified names (rickyes) [#33077](https://github.com/nodejs/node/pull/33077) +* [[`45032a39e8`](https://github.com/nodejs/node/commit/45032a39e8)] - **stream**: fix stream.finished on Duplex (Robert Nagy) [#33133](https://github.com/nodejs/node/pull/33133) +* [[`4cfa7e0716`](https://github.com/nodejs/node/commit/4cfa7e0716)] - **stream**: simplify Readable push/unshift logic (himself65) [#32899](https://github.com/nodejs/node/pull/32899) +* [[`bc40ed31b3`](https://github.com/nodejs/node/commit/bc40ed31b3)] - **stream**: add null check in Readable.from (Pranshu Srivastava) [#32873](https://github.com/nodejs/node/pull/32873) +* [[`b183d0a18a`](https://github.com/nodejs/node/commit/b183d0a18a)] - **stream**: let Duplex re-use Writable properties (Robert Nagy) [#33079](https://github.com/nodejs/node/pull/33079) +* [[`ec24577406`](https://github.com/nodejs/node/commit/ec24577406)] - **v8**: use AliasedBuffers for passing heap statistics around (Joyee Cheung) [#32929](https://github.com/nodejs/node/pull/32929) +* [[`d39254ada6`](https://github.com/nodejs/node/commit/d39254ada6)] - **vm**: fix vm.measureMemory() and introduce execution option (Joyee Cheung) [#32988](https://github.com/nodejs/node/pull/32988) +* [[`4423304ac4`](https://github.com/nodejs/node/commit/4423304ac4)] - **vm**: throw error when duplicated exportNames in SyntheticModule (himself65) [#32810](https://github.com/nodejs/node/pull/32810) +* [[`3866dc1311`](https://github.com/nodejs/node/commit/3866dc1311)] - **wasi**: use free() to release preopen array (Anna Henningsen) [#33110](https://github.com/nodejs/node/pull/33110) +* [[`d7d9960d38`](https://github.com/nodejs/node/commit/d7d9960d38)] - **wasi**: update start() behavior to match spec (Colin Ihrig) [#33073](https://github.com/nodejs/node/pull/33073) +* [[`8d5ac1bbf0`](https://github.com/nodejs/node/commit/8d5ac1bbf0)] - **wasi**: rename \_\_wasi\_unstable\_reactor\_start() (Colin Ihrig) [#33073](https://github.com/nodejs/node/pull/33073) +* [[`c6d632a72a`](https://github.com/nodejs/node/commit/c6d632a72a)] - **worker**: unify custom error creation (Anna Henningsen) [#33084](https://github.com/nodejs/node/pull/33084) + +#### Documentation commits + +* [[`6925b358f9`](https://github.com/nodejs/node/commit/6925b358f9)] - **doc**: mark assert.CallTracker experimental (Ruben Bridgewater) [#33124](https://github.com/nodejs/node/pull/33124) +* [[`413f5d3581`](https://github.com/nodejs/node/commit/413f5d3581)] - **doc**: add missing deprecation not (Robert Nagy) [#33203](https://github.com/nodejs/node/pull/33203) +* [[`7893bde07e`](https://github.com/nodejs/node/commit/7893bde07e)] - **doc**: fix a typo in crypto.generateKeyPairSync() (himself65) [#33187](https://github.com/nodejs/node/pull/33187) +* [[`d02ced8af6`](https://github.com/nodejs/node/commit/d02ced8af6)] - **doc**: add util.types.isArrayBufferView() (Kevin Locke) [#33092](https://github.com/nodejs/node/pull/33092) +* [[`36d50027af`](https://github.com/nodejs/node/commit/36d50027af)] - **doc**: clarify when not to run CI on docs (Juan José Arboleda) [#33101](https://github.com/nodejs/node/pull/33101) +* [[`a99013718c`](https://github.com/nodejs/node/commit/a99013718c)] - **doc**: fix the spelling error in stream.md (白一梓) [#31561](https://github.com/nodejs/node/pull/31561) +* [[`23962191c1`](https://github.com/nodejs/node/commit/23962191c1)] - **doc**: correct Nodejs to Node.js spelling (Nick Schonning) [#33088](https://github.com/nodejs/node/pull/33088) +* [[`de15edcfc0`](https://github.com/nodejs/node/commit/de15edcfc0)] - **doc**: improve worker pool example (Ranjan Purbey) [#33082](https://github.com/nodejs/node/pull/33082) +* [[`289a5c8dfb`](https://github.com/nodejs/node/commit/289a5c8dfb)] - **doc**: some grammar fixes (Chris Holland) [#33081](https://github.com/nodejs/node/pull/33081) +* [[`82e459d9af`](https://github.com/nodejs/node/commit/82e459d9af)] - **doc**: don't check links in tmp dirs (Ben Noordhuis) [#32996](https://github.com/nodejs/node/pull/32996) +* [[`c5a2f9a02a`](https://github.com/nodejs/node/commit/c5a2f9a02a)] - **doc**: fix markdown parsing on doc/api/os.md (Juan José Arboleda) [#33067](https://github.com/nodejs/node/pull/33067) + +#### Other commits + +* [[`60ebbc4386`](https://github.com/nodejs/node/commit/60ebbc4386)] - **test**: update c8 ignore comment (Benjamin Coe) [#33151](https://github.com/nodejs/node/pull/33151) +* [[`e276524fcc`](https://github.com/nodejs/node/commit/e276524fcc)] - **test**: skip memory usage tests when ASAN is enabled (Anna Henningsen) [#33129](https://github.com/nodejs/node/pull/33129) +* [[`89ed7a5862`](https://github.com/nodejs/node/commit/89ed7a5862)] - **test**: move test-process-title to sequential (Anna Henningsen) [#33150](https://github.com/nodejs/node/pull/33150) +* [[`af7da46d9b`](https://github.com/nodejs/node/commit/af7da46d9b)] - **test**: fix out-of-bound reads from invalid sizeof usage (Anna Henningsen) [#33115](https://github.com/nodejs/node/pull/33115) +* [[`9ccb6b2e8c`](https://github.com/nodejs/node/commit/9ccb6b2e8c)] - **test**: add missing calls to napi\_async\_destroy (Anna Henningsen) [#33114](https://github.com/nodejs/node/pull/33114) +* [[`3c2f608a8d`](https://github.com/nodejs/node/commit/3c2f608a8d)] - **test**: correct typo in test name (Colin Ihrig) [#33083](https://github.com/nodejs/node/pull/33083) +* [[`92c7e0620f`](https://github.com/nodejs/node/commit/92c7e0620f)] - **test**: check args on SourceTextModule cachedData (Juan José Arboleda) [#32956](https://github.com/nodejs/node/pull/32956) +* [[`f79ef96fea`](https://github.com/nodejs/node/commit/f79ef96fea)] - **test**: mark test flaky on freebsd (Sam Roberts) [#32849](https://github.com/nodejs/node/pull/32849) +* [[`aced1f5d70`](https://github.com/nodejs/node/commit/aced1f5d70)] - **test**: flaky test-stdout-close-catch on freebsd (Sam Roberts) [#32849](https://github.com/nodejs/node/pull/32849) +* [[`6734cc43df`](https://github.com/nodejs/node/commit/6734cc43df)] - **tools**: bump remark-preset-lint-node to 1.15.0 (Rich Trott) [#33157](https://github.com/nodejs/node/pull/33157) +* [[`a87d371014`](https://github.com/nodejs/node/commit/a87d371014)] - **tools**: fix redundant-move warning in inspector (Daniel Bevenius) [#32685](https://github.com/nodejs/node/pull/32685) +* [[`12426f59f5`](https://github.com/nodejs/node/commit/12426f59f5)] - **tools**: update remark-preset-lint-node@1.14.0 (Rich Trott) [#33072](https://github.com/nodejs/node/pull/33072) +* [[`8c40ffc329`](https://github.com/nodejs/node/commit/8c40ffc329)] - **tools**: update broken types in type parser (Colin Ihrig) [#33068](https://github.com/nodejs/node/pull/33068) + ## 2020-04-29, Version 14.1.0 (Current), @BethGriggs diff --git a/doc/guides/backporting-to-release-lines.md b/doc/guides/backporting-to-release-lines.md index 55fbcb7e5bc344..6fcbdc43f72396 100644 --- a/doc/guides/backporting-to-release-lines.md +++ b/doc/guides/backporting-to-release-lines.md @@ -31,9 +31,9 @@ release line. All commands will use the `v10.x-staging` branch as the target branch. In order to submit a backport pull request to another branch, simply replace that with the staging branch for the targeted release line. -1. Checkout the staging branch for the targeted release line -2. Make sure that the local staging branch is up to date with the remote -3. Create a new branch off of the staging branch +1. Checkout the staging branch for the targeted release line. +2. Make sure that the local staging branch is up to date with the remote. +3. Create a new branch off of the staging branch, as shown below. ```shell # Assuming your fork of Node.js is checked out in $NODE_DIR, @@ -68,17 +68,17 @@ replace that with the staging branch for the targeted release line. using `git add`, and then commit the changes. That can be done with `git cherry-pick --continue`. 6. Leave the commit message as is. If you think it should be modified, comment - in the Pull Request. The `Backport-PR-URL` metadata does need to be added to + in the pull request. The `Backport-PR-URL` metadata does need to be added to the commit, but this will be done later. 7. Make sure `make -j4 test` passes. -8. Push the changes to your fork +8. Push the changes to your fork. 9. Open a pull request: 1. Be sure to target the `v10.x-staging` branch in the pull request. 1. Include the backport target in the pull request title in the following format: `[v10.x backport] `. Example: `[v10.x backport] process: improve performance of nextTick` 1. Check the checkbox labeled "Allow edits from maintainers". - 1. In the description add a reference to the original PR. + 1. In the description add a reference to the original pull request. 1. Amend the commit message and include a `Backport-PR-URL:` metadata and re-push the change to your fork. 1. Run a [`node-test-pull-request`][] CI job (with `REBASE_ONTO` set to the @@ -86,8 +86,8 @@ replace that with the staging branch for the targeted release line. 10. If during the review process conflicts arise, use the following to rebase: `git pull --rebase upstream v10.x-staging` -After the PR lands replace the `backport-requested-v10.x` label on the original -PR with `backported-to-v10.x`. +After the pull request lands, replace the `backport-requested-v10.x` label +on the original pull request with `backported-to-v10.x`. [Release Schedule]: https://github.com/nodejs/Release#release-schedule1 [Release Plan]: https://github.com/nodejs/Release#release-plan diff --git a/doc/guides/collaborator-guide.md b/doc/guides/collaborator-guide.md index c08834ea4a1352..128f06857b8f0a 100644 --- a/doc/guides/collaborator-guide.md +++ b/doc/guides/collaborator-guide.md @@ -177,8 +177,10 @@ All pull requests must pass continuous integration tests. Code changes must pass on [project CI server](https://ci.nodejs.org/). Pull requests that only change documentation and comments can use GitHub Actions results. -Do not land any pull requests without passing (green or yellow) CI runs. If -there are CI failures unrelated to the change in the pull request, try "Resume +Do not land any pull requests without a passing (green or yellow) CI run. +For documentation-only changes, GitHub Actions CI is sufficient. +For all other code changes, Jenkins CI must pass as well. If there are +Jenkins CI failures unrelated to the change in the pull request, try "Resume Build". It is in the left navigation of the relevant `node-test-pull-request` job. It will preserve all the green results from the current job but re-run everything else. Start a fresh CI if more than seven days have elapsed since diff --git a/doc/guides/diagnostic-tooling-support-tiers.md b/doc/guides/diagnostic-tooling-support-tiers.md index 254f90ecadd5fd..5d935a29369a88 100644 --- a/doc/guides/diagnostic-tooling-support-tiers.md +++ b/doc/guides/diagnostic-tooling-support-tiers.md @@ -25,7 +25,7 @@ the following tiers. * The tool must have a guide or other documentation in the Node.js GitHub organization or website; * The tool must be working on all supported platforms; - * The tool must only be using APIs exposed by Nodejs as opposed to + * The tool must only be using APIs exposed by Node.js as opposed to its dependencies; and * The tool must be open source. diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 2618c6c3cb8223..b9d2c0c2c04a7c 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -138,11 +138,6 @@ function Agent(options) { socket._httpMessage = null; this.removeSocket(socket, options); - const agentTimeout = this.options.timeout || 0; - if (socket.timeout !== agentTimeout) { - socket.setTimeout(agentTimeout); - } - socket.once('error', freeSocketErrorListener); freeSockets.push(socket); }); @@ -247,7 +242,12 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, } else if (sockLen < this.maxSockets) { debug('call onSocket', sockLen, freeLen); // If we are under maxSockets create a new one. - this.createSocket(req, options, handleSocketCreation(this, req, true)); + this.createSocket(req, options, (err, socket) => { + if (err) + req.onSocket(socket, err); + else + setRequestSocket(this, req, socket); + }); } else { debug('wait for socket'); // We are over limit so we'll add it to the queue. @@ -393,8 +393,12 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { debug('removeSocket, have a request, make a socket'); const req = this.requests[name][0]; // If we have pending requests and a socket gets closed make a new one - const socketCreationHandler = handleSocketCreation(this, req, false); - this.createSocket(req, options, socketCreationHandler); + this.createSocket(req, options, (err, socket) => { + if (err) + req.onSocket(socket, err); + else + socket.emit('free'); + }); } }; @@ -402,6 +406,11 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) { socket.setKeepAlive(true, this.keepAliveMsecs); socket.unref(); + const agentTimeout = this.options.timeout || 0; + if (socket.timeout !== agentTimeout) { + socket.setTimeout(agentTimeout); + } + return true; }; @@ -422,19 +431,6 @@ Agent.prototype.destroy = function destroy() { } }; -function handleSocketCreation(agent, request, informRequest) { - return function handleSocketCreation_Inner(err, socket) { - if (err) { - process.nextTick(emitErrorNT, request, err); - return; - } - if (informRequest) - setRequestSocket(agent, request, socket); - else - socket.emit('free'); - }; -} - function setRequestSocket(agent, req, socket) { req.onSocket(socket); const agentTimeout = agent.options.timeout || 0; @@ -444,10 +440,6 @@ function setRequestSocket(agent, req, socket) { socket.setTimeout(req.timeout); } -function emitErrorNT(emitter, err) { - emitter.emit('error', err); -} - module.exports = { Agent, globalAgent: new Agent() diff --git a/lib/_http_client.js b/lib/_http_client.js index 73a6409c411cc1..c78289138e756a 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -371,10 +371,12 @@ function _destroy(req, socket, err) { // TODO (ronag): Check if socket was used at all (e.g. headersSent) and // re-use it in that case. `req.socket` just checks whether the socket was // assigned to the request and *might* have been used. - if (!req.agent || req.socket) { + if (socket && (!req.agent || req.socket)) { socket.destroy(err); } else { - socket.emit('free'); + if (socket) { + socket.emit('free'); + } if (!req.aborted && !err) { err = connResetException('socket hang up'); } @@ -776,15 +778,18 @@ function listenSocketTimeout(req) { } } -ClientRequest.prototype.onSocket = function onSocket(socket) { +ClientRequest.prototype.onSocket = function onSocket(socket, err) { // TODO(ronag): Between here and onSocketNT the socket // has no 'error' handler. - process.nextTick(onSocketNT, this, socket); + process.nextTick(onSocketNT, this, socket, err); }; -function onSocketNT(req, socket) { +function onSocketNT(req, socket, err) { if (req.destroyed) { _destroy(req, socket, req[kError]); + } else if (err) { + req.destroyed = true; + _destroy(req, null, err); } else { tickOnSocket(req, socket); } diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index a22621ea4319dc..5fd462b0194387 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -304,19 +304,11 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) { data = this._header + data; } else { const header = this._header; - if (this.outputData.length === 0) { - this.outputData = [{ - data: header, - encoding: 'latin1', - callback: null - }]; - } else { - this.outputData.unshift({ - data: header, - encoding: 'latin1', - callback: null - }); - } + this.outputData.unshift({ + data: header, + encoding: 'latin1', + callback: null + }); this.outputSize += header.length; this._onPendingData(header.length); } diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index 07a16175ffcd73..ced361c8d60898 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -71,7 +71,20 @@ function Duplex(options) { } ObjectDefineProperties(Duplex.prototype, { - writable: ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writable'), + writable: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writable'), + writableHighWaterMark: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableHighWaterMark'), + writableBuffer: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableBuffer'), + writableLength: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableLength'), + writableFinished: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableFinished'), + writableCorked: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableCorked'), + writableEnded: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableEnded'), destroyed: { get() { @@ -89,41 +102,5 @@ ObjectDefineProperties(Duplex.prototype, { this._writableState.destroyed = value; } } - }, - - writableHighWaterMark: { - get() { - return this._writableState && this._writableState.highWaterMark; - } - }, - - writableBuffer: { - get() { - return this._writableState && this._writableState.getBuffer(); - } - }, - - writableLength: { - get() { - return this._writableState && this._writableState.length; - } - }, - - writableFinished: { - get() { - return this._writableState ? this._writableState.finished : false; - } - }, - - writableCorked: { - get() { - return this._writableState ? this._writableState.corked : 0; - } - }, - - writableEnded: { - get() { - return this._writableState ? this._writableState.ending : false; - } } }); diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index ec9f86d7eacf4a..f39c49867805d3 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -230,13 +230,15 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { if (!state.objectMode) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; - if (addToFront && state.encoding && state.encoding !== encoding) { - // When unshifting, if state.encoding is set, we have to save - // the string in the BufferList with the state encoding. - chunk = Buffer.from(chunk, encoding).toString(state.encoding); - } else if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; + if (state.encoding !== encoding) { + if (addToFront && state.encoding) { + // When unshifting, if state.encoding is set, we have to save + // the string in the BufferList with the state encoding. + chunk = Buffer.from(chunk, encoding).toString(state.encoding); + } else { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } } } else if (chunk instanceof Buffer) { encoding = ''; diff --git a/lib/assert.js b/lib/assert.js index 45c4644279de33..6ad672d698602d 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -51,6 +51,7 @@ const { NativeModule } = require('internal/bootstrap/loaders'); const { isError } = require('internal/util'); const errorCache = new Map(); +const CallTracker = require('internal/assert/calltracker'); let isDeepEqual; let isDeepStrictEqual; @@ -928,6 +929,8 @@ assert.doesNotMatch = function doesNotMatch(string, regexp, message) { internalMatch(string, regexp, message, doesNotMatch); }; +assert.CallTracker = CallTracker; + // Expose a strict only variant of assert function strict(...args) { innerOk(strict, args.length, ...args); diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index 691f057ad281e3..3c2150c69e4e09 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -312,6 +312,7 @@ class AssertionError extends Error { message, operator, stackStartFn, + details, // Compatibility with older versions. stackStartFunction } = options; @@ -426,9 +427,22 @@ class AssertionError extends Error { configurable: true }); this.code = 'ERR_ASSERTION'; - this.actual = actual; - this.expected = expected; - this.operator = operator; + if (details) { + this.actual = undefined; + this.expected = undefined; + this.operator = undefined; + for (let i = 0; i < details.length; i++) { + this['message ' + i] = details[i].message; + this['actual ' + i] = details[i].actual; + this['expected ' + i] = details[i].expected; + this['operator ' + i] = details[i].operator; + this['stack trace ' + i] = details[i].stack; + } + } else { + this.actual = actual; + this.expected = expected; + this.operator = operator; + } // eslint-disable-next-line no-restricted-syntax Error.captureStackTrace(this, stackStartFn || stackStartFunction); // Create error message including the error code in the name. diff --git a/lib/internal/assert/calltracker.js b/lib/internal/assert/calltracker.js new file mode 100644 index 00000000000000..74f517f3f9e99b --- /dev/null +++ b/lib/internal/assert/calltracker.js @@ -0,0 +1,93 @@ +'use strict'; + +const { + Error, + SafeSet, +} = primordials; + +const { + codes: { + ERR_UNAVAILABLE_DURING_EXIT, + }, +} = require('internal/errors'); +const AssertionError = require('internal/assert/assertion_error'); +const { + validateUint32, +} = require('internal/validators'); + +const noop = () => {}; + +class CallTracker { + + #callChecks = new SafeSet() + + calls(fn, exact = 1) { + if (process._exiting) + throw new ERR_UNAVAILABLE_DURING_EXIT(); + if (typeof fn === 'number') { + exact = fn; + fn = noop; + } else if (fn === undefined) { + fn = noop; + } + + validateUint32(exact, 'exact', true); + + const context = { + exact, + actual: 0, + // eslint-disable-next-line no-restricted-syntax + stackTrace: new Error(), + name: fn.name || 'calls' + }; + const callChecks = this.#callChecks; + callChecks.add(context); + + return function() { + context.actual++; + if (context.actual === context.exact) { + // Once function has reached its call count remove it from + // callChecks set to prevent memory leaks. + callChecks.delete(context); + } + // If function has been called more than expected times, add back into + // callchecks. + if (context.actual === context.exact + 1) { + callChecks.add(context); + } + return fn.apply(this, arguments); + }; + } + + report() { + const errors = []; + for (const context of this.#callChecks) { + // If functions have not been called exact times + if (context.actual !== context.exact) { + const message = `Expected the ${context.name} function to be ` + + `executed ${context.exact} time(s) but was ` + + `executed ${context.actual} time(s).`; + errors.push({ + message, + actual: context.actual, + expected: context.exact, + operator: context.name, + stack: context.stackTrace + }); + } + } + return errors; + } + + verify() { + const errors = this.report(); + if (errors.length > 0) { + throw new AssertionError({ + message: 'Function(s) were not called the expected number of times', + details: errors, + }); + } + } +} + +module.exports = CallTracker; diff --git a/lib/internal/cluster/child.js b/lib/internal/cluster/child.js index 250a82ecabaa34..74f30c0d2ece90 100644 --- a/lib/internal/cluster/child.js +++ b/lib/internal/cluster/child.js @@ -228,16 +228,23 @@ function _disconnect(masterInitiated) { // Extend generic Worker with methods specific to worker processes. Worker.prototype.disconnect = function() { - _disconnect.call(this); + if (![ 'disconnecting', 'destroying' ].includes(this.state)) { + this.state = 'disconnecting'; + _disconnect.call(this); + } + return this; }; Worker.prototype.destroy = function() { - this.exitedAfterDisconnect = true; + if (this.state === 'destroying') + return; + this.exitedAfterDisconnect = true; if (!this.isConnected()) { process.exit(0); } else { + this.state = 'destroying'; send({ act: 'exitedAfterDisconnect' }, () => process.disconnect()); process.once('disconnect', () => process.exit(0)); } diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index dc8dcaa1d054ed..c5195c77c6e169 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -32,6 +32,7 @@ const { ERR_INCOMPATIBLE_OPTION_PAIR, }, } = require('internal/errors'); +const { validateInteger } = require('internal/validators'); const { previewEntries } = internalBinding('util'); const { Buffer: { isBuffer } } = require('buffer'); const { @@ -52,12 +53,14 @@ const kTraceInstant = 'n'.charCodeAt(0); const kSecond = 1000; const kMinute = 60 * kSecond; const kHour = 60 * kMinute; +const kMaxGroupIndentation = 1000; // Lazy loaded for startup performance. let cliTable; // Track amount of indentation required via `console.group()`. const kGroupIndent = Symbol('kGroupIndent'); +const kGroupIndentationWidth = Symbol('kGroupIndentWidth'); const kFormatForStderr = Symbol('kFormatForStderr'); const kFormatForStdout = Symbol('kFormatForStdout'); const kGetInspectOptions = Symbol('kGetInspectOptions'); @@ -93,7 +96,8 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) { stderr = stdout, ignoreErrors = true, colorMode = 'auto', - inspectOptions + inspectOptions, + groupIndentation, } = options; if (!stdout || typeof stdout.write !== 'function') { @@ -106,6 +110,11 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) { if (typeof colorMode !== 'boolean' && colorMode !== 'auto') throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode); + if (groupIndentation !== undefined) { + validateInteger(groupIndentation, 'groupIndentation', + 0, kMaxGroupIndentation); + } + if (typeof inspectOptions === 'object' && inspectOptions !== null) { if (inspectOptions.colors !== undefined && options.colorMode !== undefined) { @@ -130,7 +139,7 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) { } this[kBindStreamsEager](stdout, stderr); - this[kBindProperties](ignoreErrors, colorMode); + this[kBindProperties](ignoreErrors, colorMode, groupIndentation); } const consolePropAttributes = { @@ -181,7 +190,8 @@ Console.prototype[kBindStreamsLazy] = function(object) { }); }; -Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) { +Console.prototype[kBindProperties] = function(ignoreErrors, colorMode, + groupIndentation = 2) { ObjectDefineProperties(this, { '_stdoutErrorHandler': { ...consolePropAttributes, @@ -200,7 +210,11 @@ Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) { [kCounts]: { ...consolePropAttributes, value: new Map() }, [kColorMode]: { ...consolePropAttributes, value: colorMode }, [kIsConsole]: { ...consolePropAttributes, value: true }, - [kGroupIndent]: { ...consolePropAttributes, value: '' } + [kGroupIndent]: { ...consolePropAttributes, value: '' }, + [kGroupIndentationWidth]: { + ...consolePropAttributes, + value: groupIndentation + }, }); }; @@ -403,12 +417,13 @@ const consoleMethods = { if (data.length > 0) { this.log(...data); } - this[kGroupIndent] += ' '; + this[kGroupIndent] += ' '.repeat(this[kGroupIndentationWidth]); }, groupEnd() { this[kGroupIndent] = - this[kGroupIndent].slice(0, this[kGroupIndent].length - 2); + this[kGroupIndent].slice(0, this[kGroupIndent].length - + this[kGroupIndentationWidth]); }, // https://console.spec.whatwg.org/#table diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index ae6b68b73b5767..8f86911757fe1f 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -14,7 +14,10 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_OPT_VALUE } = require('internal/errors').codes; -const { validateString } = require('internal/validators'); +const { + validateString, + validateInt32, +} = require('internal/validators'); const { isArrayBufferView } = require('internal/util/types'); const { KeyObject } = require('internal/crypto/keys'); const { @@ -51,6 +54,13 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { ); } + // Sizes < 0 don't make sense but they _are_ accepted (and subsequently + // rejected with ERR_OSSL_BN_BITS_TOO_SMALL) by OpenSSL. The glue code + // in node_crypto.cc accepts values that are IsInt32() for that reason + // and that's why we do that here too. + if (typeof sizeOrKey === 'number') + validateInt32(sizeOrKey, 'sizeOrKey'); + if (keyEncoding && !Buffer.isEncoding(keyEncoding) && keyEncoding !== 'buffer') { genEncoding = generator; @@ -67,7 +77,9 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { if (!generator) generator = DH_GENERATOR; - else if (typeof generator !== 'number') + else if (typeof generator === 'number') + validateInt32(generator, 'generator'); + else generator = toBuf(generator, genEncoding); this[kHandle] = new _DiffieHellman(sizeOrKey, generator); diff --git a/lib/internal/errors.js b/lib/internal/errors.js index e9e11bf0fb195b..c4e9fb3d59b4a3 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1318,8 +1318,12 @@ E('ERR_SERVER_NOT_RUNNING', 'Server is not running.', Error); E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound', Error); E('ERR_SOCKET_BAD_BUFFER_SIZE', 'Buffer size must be a positive integer', TypeError); -E('ERR_SOCKET_BAD_PORT', - '%s should be >= 0 and < 65536. Received %s.', RangeError); +E('ERR_SOCKET_BAD_PORT', (name, port, allowZero = true) => { + assert(typeof allowZero === 'boolean', + "The 'allowZero' argument must be of type boolean."); + const operator = allowZero ? '>=' : '>'; + return `${name} should be ${operator} 0 and < 65536. Received ${port}.`; +}, RangeError); E('ERR_SOCKET_BAD_TYPE', 'Bad socket type specified. Valid types are: udp4, udp6', TypeError); E('ERR_SOCKET_BUFFER_SIZE', @@ -1380,6 +1384,8 @@ E('ERR_TRANSFORM_ALREADY_TRANSFORMING', E('ERR_TRANSFORM_WITH_LENGTH_0', 'Calling transform done when writableState.length != 0', Error); E('ERR_TTY_INIT_FAILED', 'TTY initialization failed', SystemError); +E('ERR_UNAVAILABLE_DURING_EXIT', 'Cannot call function in process exit ' + + 'handler', Error); E('ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET', '`process.setupUncaughtExceptionCapture()` was called while a capture ' + 'callback was already active', diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index 2d73219a77772c..2f62c8623e27be 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -110,11 +110,39 @@ function stripBOM(content) { } const builtinLibs = [ - 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'crypto', - 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'net', - 'os', 'path', 'perf_hooks', 'punycode', 'querystring', 'readline', 'repl', - 'stream', 'string_decoder', 'tls', 'trace_events', 'tty', 'url', 'util', - 'v8', 'vm', 'worker_threads', 'zlib' + 'assert', + 'async_hooks', + 'buffer', + 'child_process', + 'cluster', + 'crypto', + 'dgram', + 'dns', + 'domain', + 'events', + 'fs', + 'http', + 'http2', + 'https', + 'net', + 'os', + 'path', + 'perf_hooks', + 'punycode', + 'querystring', + 'readline', + 'repl', + 'stream', + 'string_decoder', + 'tls', + 'trace_events', + 'tty', + 'url', + 'util', + 'v8', + 'vm', + 'worker_threads', + 'zlib', ]; if (internalBinding('config').experimentalWasi) { diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 5bb2f37e53eeb5..c66e0554ad2746 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -2,17 +2,22 @@ const { ArrayIsArray, + ArrayPrototypeJoin, + ArrayPrototypeShift, JSONParse, JSONStringify, ObjectFreeze, ObjectGetOwnPropertyNames, ObjectPrototypeHasOwnProperty, + RegExp, SafeMap, SafeSet, StringPrototypeEndsWith, StringPrototypeIncludes, StringPrototypeIndexOf, + StringPrototypeReplace, StringPrototypeSlice, + StringPrototypeSplit, StringPrototypeStartsWith, StringPrototypeSubstr, } = primordials; @@ -29,8 +34,8 @@ const { Stats, } = require('fs'); const { getOptionValue } = require('internal/options'); -const { sep } = require('path'); - +const { sep, relative } = require('path'); +const { Module: CJSModule } = require('internal/modules/cjs/loader'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const typeFlag = getOptionValue('--input-type'); @@ -439,11 +444,6 @@ function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) { throw new ERR_PACKAGE_PATH_NOT_EXPORTED(packageJSONUrl, '.'); } - if (packageConfig.main !== undefined) { - const resolved = new URL(packageConfig.main, packageJSONUrl); - const path = fileURLToPath(resolved); - if (tryStatSync(path).isFile()) return resolved; - } if (getOptionValue('--experimental-specifier-resolution') === 'node') { if (packageConfig.main !== undefined) { return finalizeResolution( @@ -453,9 +453,7 @@ function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) { new URL('index', packageJSONUrl), base); } } - if (packageConfig.type !== 'module') { - return legacyMainResolve(packageJSONUrl, packageConfig); - } + return legacyMainResolve(packageJSONUrl, packageConfig); } throw new ERR_MODULE_NOT_FOUND( @@ -618,9 +616,11 @@ function packageResolve(specifier, base, conditions) { throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); } -function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { - if (specifier === '') return false; - if (specifier[0] === '/') return true; +function isBareSpecifier(specifier) { + return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.'; +} + +function isRelativeSpecifier(specifier) { if (specifier[0] === '.') { if (specifier.length === 1 || specifier[1] === '/') return true; if (specifier[1] === '.') { @@ -630,6 +630,12 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { return false; } +function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { + if (specifier === '') return false; + if (specifier[0] === '/') return true; + return isRelativeSpecifier(specifier); +} + /** * @param {string} specifier * @param {URL} base @@ -652,6 +658,51 @@ function moduleResolve(specifier, base, conditions) { return finalizeResolution(resolved, base); } +/** + * Try to resolve an import as a CommonJS module + * @param {string} specifier + * @param {string} parentURL + * @returns {boolean|string} + */ +function resolveAsCommonJS(specifier, parentURL) { + try { + const parent = fileURLToPath(parentURL); + const tmpModule = new CJSModule(parent, null); + tmpModule.paths = CJSModule._nodeModulePaths(parent); + + let found = CJSModule._resolveFilename(specifier, tmpModule, false); + + // If it is a relative specifier return the relative path + // to the parent + if (isRelativeSpecifier(specifier)) { + found = relative(parent, found); + // Add '.separator if the path does not start with '..separator' + // This should be a safe assumption because when loading + // esm modules there should be always a file specified so + // there should not be a specifier like '..' or '.' + if (!StringPrototypeStartsWith(found, `..${sep}`)) { + found = `.${sep}${found}`; + } + } else if (isBareSpecifier(specifier)) { + // If it is a bare specifier return the relative path within the + // module + const pkg = StringPrototypeSplit(specifier, '/')[0]; + const index = StringPrototypeIndexOf(found, pkg); + if (index !== -1) { + found = StringPrototypeSlice(found, index); + } + } + // Normalize the path separator to give a valid suggestion + // on Windows + if (process.platform === 'win32') { + found = StringPrototypeReplace(found, new RegExp(`\\${sep}`, 'g'), '/'); + } + return found; + } catch { + return false; + } +} + function defaultResolve(specifier, context = {}, defaultResolveUnused) { let { parentURL, conditions } = context; let parsed; @@ -692,7 +743,27 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { } conditions = getConditionsSet(conditions); - let url = moduleResolve(specifier, parentURL, conditions); + let url; + try { + url = moduleResolve(specifier, parentURL, conditions); + } catch (error) { + // Try to give the user a hint of what would have been the + // resolved CommonJS module + if (error.code === 'ERR_MODULE_NOT_FOUND') { + const found = resolveAsCommonJS(specifier, parentURL); + if (found) { + // Modify the stack and message string to include the hint + const lines = StringPrototypeSplit(error.stack, '\n'); + const hint = `Did you mean to import ${found}?`; + error.stack = + ArrayPrototypeShift(lines) + '\n' + + hint + '\n' + + ArrayPrototypeJoin(lines, '\n'); + error.message += `\n${hint}`; + } + } + throw error; + } if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { const urlPath = fileURLToPath(url); diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 7d5689ddadb7fc..bc2d0ccfcaf142 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -147,10 +147,17 @@ function eos(stream, opts, callback) { if (opts.error !== false) stream.on('error', onerror); stream.on('close', onclose); - const closed = (wState && wState.closed) || (rState && rState.closed) || - (wState && wState.errorEmitted) || (rState && rState.errorEmitted) || - (wState && wState.finished) || (rState && rState.endEmitted) || - (rState && stream.req && stream.aborted); + const closed = ( + (wState && wState.closed) || + (rState && rState.closed) || + (wState && wState.errorEmitted) || + (rState && rState.errorEmitted) || + (rState && stream.req && stream.aborted) || + ( + (!writable || (wState && wState.finished)) && + (!readable || (rState && rState.endEmitted)) + ) + ); if (closed) { // TODO(ronag): Re-throw error if errorEmitted? @@ -158,6 +165,7 @@ function eos(stream, opts, callback) { // before being closed? i.e. if closed but not errored, ended or finished. // TODO(ronag): Throw some kind of error? Does it make sense // to call finished() on a "finished" stream? + // TODO(ronag): willEmitClose? process.nextTick(() => { callback(); }); diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index ca567914bbf0fe..6752679ae3bc2b 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -7,7 +7,8 @@ const { const { Buffer } = require('buffer'); const { - ERR_INVALID_ARG_TYPE + ERR_INVALID_ARG_TYPE, + ERR_STREAM_NULL_VALUES } = require('internal/errors').codes; function from(Readable, iterable, opts) { @@ -73,15 +74,20 @@ function from(Readable, iterable, opts) { needToClose = false; const { value, done } = await iterator.next(); needToClose = !done; - const resolved = await value; if (done) { readable.push(null); } else if (readable.destroyed) { await close(); - } else if (readable.push(resolved)) { - next(); } else { - reading = false; + const res = await value; + if (res === null) { + reading = false; + throw new ERR_STREAM_NULL_VALUES(); + } else if (readable.push(res)) { + next(); + } else { + reading = false; + } } } catch (err) { readable.destroy(err); diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index 3cc593ae27f403..9d4cdf9f183f16 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -147,7 +147,7 @@ function isIdenticalTypedArrayType(a, b) { return check(b); } } - /* c8 ignore next */ + /* c8 ignore next 4 */ assert.fail( `Unknown TypedArray type checking ${a[SymbolToStringTag]} ${a}\n` + `and ${b[SymbolToStringTag]} ${b}` diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 790c923386fa91..deab53d4b8221e 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -190,7 +190,7 @@ function validatePort(port, name = 'Port', { allowZero = true } = {}) { +port !== (+port >>> 0) || port > 0xFFFF || (port === 0 && !allowZero)) { - throw new ERR_SOCKET_BAD_PORT(name, port); + throw new ERR_SOCKET_BAD_PORT(name, port, allowZero); } return port | 0; } diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index ed0dedd1e31b4f..992753ef680dbb 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -22,6 +22,7 @@ const { } = require('internal/util'); const { ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, ERR_VM_MODULE_ALREADY_LINKED, ERR_VM_MODULE_DIFFERENT_CONTEXT, ERR_VM_MODULE_CANNOT_CREATE_CACHED_DATA, @@ -379,8 +380,17 @@ class SyntheticModule extends Module { constructor(exportNames, evaluateCallback, options = {}) { if (!ArrayIsArray(exportNames) || exportNames.some((e) => typeof e !== 'string')) { - throw new ERR_INVALID_ARG_TYPE('exportNames', 'Array of strings', + throw new ERR_INVALID_ARG_TYPE('exportNames', + 'Array of unique strings', exportNames); + } else { + exportNames.forEach((name, i) => { + if (exportNames.indexOf(name, i + 1) !== -1) { + throw new ERR_INVALID_ARG_VALUE(`exportNames.${name}`, + name, + 'is duplicated'); + } + }); } if (typeof evaluateCallback !== 'function') { throw new ERR_INVALID_ARG_TYPE('evaluateCallback', 'function', diff --git a/lib/internal/worker.js b/lib/internal/worker.js index 5f92a7898e93a9..48886aee3fef5d 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -54,6 +54,7 @@ const { kMaxYoungGenerationSizeMb, kMaxOldGenerationSizeMb, kCodeRangeSizeMb, + kStackSizeMb, kTotalResourceLimitCount } = internalBinding('worker'); @@ -379,6 +380,8 @@ function parseResourceLimits(obj) { ret[kMaxYoungGenerationSizeMb] = obj.maxYoungGenerationSizeMb; if (typeof obj.codeRangeSizeMb === 'number') ret[kCodeRangeSizeMb] = obj.codeRangeSizeMb; + if (typeof obj.stackSizeMb === 'number') + ret[kStackSizeMb] = obj.stackSizeMb; return ret; } @@ -386,7 +389,8 @@ function makeResourceLimits(float64arr) { return { maxYoungGenerationSizeMb: float64arr[kMaxYoungGenerationSizeMb], maxOldGenerationSizeMb: float64arr[kMaxOldGenerationSizeMb], - codeRangeSizeMb: float64arr[kCodeRangeSizeMb] + codeRangeSizeMb: float64arr[kCodeRangeSizeMb], + stackSizeMb: float64arr[kStackSizeMb] }; } diff --git a/lib/path.js b/lib/path.js index c5db4437a52408..7532b795bf63f7 100644 --- a/lib/path.js +++ b/lib/path.js @@ -385,14 +385,14 @@ const win32 = { return '.'; // Make sure that the joined path doesn't start with two slashes, because - // normalize() will mistake it for an UNC path then. + // normalize() will mistake it for a UNC path then. // // This step is skipped when it is very clear that the user actually - // intended to point at an UNC path. This is assumed when the first + // intended to point at a UNC path. This is assumed when the first // non-empty string arguments starts with exactly two slashes followed by // at least one more non-slash character. // - // Note that for normalize() to treat a path as an UNC path it needs to + // Note that for normalize() to treat a path as a UNC path it needs to // have at least 2 components, so we don't filter for that here. // This means that the user can use join to construct UNC paths from // a server name and a share name; for example: diff --git a/lib/v8.js b/lib/v8.js index 5841f204986fd7..11ca7fa640f27b 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -73,12 +73,12 @@ class Deserializer extends _Deserializer { } const { cachedDataVersionTag, setFlagsFromString: _setFlagsFromString, - heapStatisticsArrayBuffer, - heapSpaceStatisticsArrayBuffer, - heapCodeStatisticsArrayBuffer, - updateHeapStatisticsArrayBuffer, - updateHeapSpaceStatisticsArrayBuffer, - updateHeapCodeStatisticsArrayBuffer, + heapStatisticsBuffer, + heapSpaceStatisticsBuffer, + heapCodeStatisticsBuffer, + updateHeapStatisticsBuffer, + updateHeapSpaceStatisticsBuffer, + updateHeapCodeStatisticsBuffer, // Properties for heap statistics buffer extraction. kTotalHeapSizeIndex, @@ -95,7 +95,6 @@ const { // Properties for heap spaces statistics buffer extraction. kHeapSpaces, - kHeapSpaceStatisticsPropertiesCount, kSpaceSizeIndex, kSpaceUsedSizeIndex, kSpaceAvailableSizeIndex, @@ -109,15 +108,6 @@ const { const kNumberOfHeapSpaces = kHeapSpaces.length; -const heapStatisticsBuffer = - new Float64Array(heapStatisticsArrayBuffer); - -const heapSpaceStatisticsBuffer = - new Float64Array(heapSpaceStatisticsArrayBuffer); - -const heapCodeStatisticsBuffer = - new Float64Array(heapCodeStatisticsArrayBuffer); - function setFlagsFromString(flags) { validateString(flags, 'flags'); _setFlagsFromString(flags); @@ -126,7 +116,7 @@ function setFlagsFromString(flags) { function getHeapStatistics() { const buffer = heapStatisticsBuffer; - updateHeapStatisticsArrayBuffer(); + updateHeapStatisticsBuffer(); return { 'total_heap_size': buffer[kTotalHeapSizeIndex], @@ -146,16 +136,15 @@ function getHeapStatistics() { function getHeapSpaceStatistics() { const heapSpaceStatistics = new Array(kNumberOfHeapSpaces); const buffer = heapSpaceStatisticsBuffer; - updateHeapSpaceStatisticsArrayBuffer(); for (let i = 0; i < kNumberOfHeapSpaces; i++) { - const propertyOffset = i * kHeapSpaceStatisticsPropertiesCount; + updateHeapSpaceStatisticsBuffer(i); heapSpaceStatistics[i] = { space_name: kHeapSpaces[i], - space_size: buffer[propertyOffset + kSpaceSizeIndex], - space_used_size: buffer[propertyOffset + kSpaceUsedSizeIndex], - space_available_size: buffer[propertyOffset + kSpaceAvailableSizeIndex], - physical_space_size: buffer[propertyOffset + kPhysicalSpaceSizeIndex] + space_size: buffer[kSpaceSizeIndex], + space_used_size: buffer[kSpaceUsedSizeIndex], + space_available_size: buffer[kSpaceAvailableSizeIndex], + physical_space_size: buffer[kPhysicalSpaceSizeIndex] }; } @@ -165,7 +154,7 @@ function getHeapSpaceStatistics() { function getHeapCodeStatistics() { const buffer = heapCodeStatisticsBuffer; - updateHeapCodeStatisticsArrayBuffer(); + updateHeapCodeStatisticsBuffer(); return { 'code_and_metadata_size': buffer[kCodeAndMetadataSizeIndex], 'bytecode_and_metadata_size': buffer[kBytecodeAndMetadataSizeIndex], diff --git a/lib/vm.js b/lib/vm.js index cffca355720dae..fd81e9da8b0515 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -385,20 +385,27 @@ const measureMemoryModes = { detailed: constants.measureMemory.mode.DETAILED, }; +const measureMemoryExecutions = { + default: constants.measureMemory.execution.DEFAULT, + eager: constants.measureMemory.execution.EAGER, +}; + function measureMemory(options = {}) { emitExperimentalWarning('vm.measureMemory'); validateObject(options, 'options'); - const { mode = 'summary', context } = options; + const { mode = 'summary', execution = 'default' } = options; if (mode !== 'summary' && mode !== 'detailed') { throw new ERR_INVALID_ARG_VALUE( 'options.mode', options.mode, 'must be either \'summary\' or \'detailed\''); } - if (context !== undefined && - (typeof context !== 'object' || context === null || !_isContext(context))) { - throw new ERR_INVALID_ARG_TYPE('options.context', 'vm.Context', context); + if (execution !== 'default' && execution !== 'eager') { + throw new ERR_INVALID_ARG_VALUE( + 'options.execution', options.execution, + 'must be either \'default\' or \'eager\''); } - const result = _measureMemory(measureMemoryModes[mode], context); + const result = _measureMemory(measureMemoryModes[mode], + measureMemoryExecutions[execution]); if (result === undefined) { return PromiseReject(new ERR_CONTEXT_NOT_INITIALIZED()); } diff --git a/lib/wasi.js b/lib/wasi.js index a6d90f0f57365f..2de467ff1ac066 100644 --- a/lib/wasi.js +++ b/lib/wasi.js @@ -80,7 +80,17 @@ class WASI { validateObject(exports, 'instance.exports'); - const { memory } = exports; + const { _initialize, _start, memory } = exports; + + if (typeof _start !== 'function') { + throw new ERR_INVALID_ARG_TYPE( + 'instance.exports._start', 'function', _start); + } + + if (_initialize !== undefined) { + throw new ERR_INVALID_ARG_TYPE( + 'instance.exports._initialize', 'undefined', _initialize); + } if (!(memory instanceof WebAssembly.Memory)) { throw new ERR_INVALID_ARG_TYPE( @@ -95,10 +105,7 @@ class WASI { this[kSetMemory](memory); try { - if (exports._start) - exports._start(); - else if (exports.__wasi_unstable_reactor_start) - exports.__wasi_unstable_reactor_start(); + exports._start(); } catch (err) { if (err !== kExitCode) { throw err; diff --git a/node.gyp b/node.gyp index c3ffd2ff2147e2..3dadad15c9e193 100644 --- a/node.gyp +++ b/node.gyp @@ -96,6 +96,7 @@ 'lib/zlib.js', 'lib/internal/assert.js', 'lib/internal/assert/assertion_error.js', + 'lib/internal/assert/calltracker.js', 'lib/internal/async_hooks.js', 'lib/internal/buffer.js', 'lib/internal/cli_table.js', @@ -375,6 +376,9 @@ 'msvs_disabled_warnings!': [4244], 'conditions': [ + [ 'error_on_warn=="true"', { + 'cflags': ['-Werror'], + }], [ 'node_intermediate_lib_type=="static_library" and ' 'node_shared=="true" and OS=="aix"', { # For AIX, shared lib is linked by static lib and .exp. In the @@ -749,6 +753,9 @@ 'msvs_disabled_warnings!': [4244], 'conditions': [ + [ 'error_on_warn=="true"', { + 'cflags': ['-Werror'], + }], [ 'node_builtin_modules_path!=""', { 'defines': [ 'NODE_BUILTIN_MODULES_PATH="<(node_builtin_modules_path)"' ] }], diff --git a/src/heap_utils.cc b/src/heap_utils.cc index efdd68fde9d160..2e979e49e87922 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -237,7 +237,7 @@ class HeapSnapshotStream : public AsyncWrap, HeapSnapshotStream( Environment* env, HeapSnapshotPointer&& snapshot, - v8::Local obj) : + Local obj) : AsyncWrap(env, obj, AsyncWrap::PROVIDER_HEAPSNAPSHOT), StreamBase(env), snapshot_(std::move(snapshot)) { diff --git a/src/node_api.cc b/src/node_api.cc index cb8bd4b482365e..098c5e03219396 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -250,8 +250,8 @@ class ThreadSafeFunction : public node::AsyncResource { if (max_queue_size > 0) { cond = std::make_unique(); } - if ((max_queue_size == 0 || cond) && - uv_idle_init(loop, &idle) == 0) { + if (max_queue_size == 0 || cond) { + CHECK_EQ(0, uv_idle_init(loop, &idle)); return napi_ok; } @@ -291,7 +291,6 @@ class ThreadSafeFunction : public node::AsyncResource { void DispatchOne() { void* data = nullptr; bool popped_value = false; - bool idle_stop_failed = false; { node::Mutex::ScopedLock lock(this->mutex); @@ -317,43 +316,24 @@ class ThreadSafeFunction : public node::AsyncResource { } CloseHandlesAndMaybeDelete(); } else { - if (uv_idle_stop(&idle) != 0) { - idle_stop_failed = true; - } + CHECK_EQ(0, uv_idle_stop(&idle)); } } } } - if (popped_value || idle_stop_failed) { + if (popped_value) { v8::HandleScope scope(env->isolate); CallbackScope cb_scope(this); - - if (idle_stop_failed) { - CHECK(napi_throw_error(env, - "ERR_NAPI_TSFN_STOP_IDLE_LOOP", - "Failed to stop the idle loop") == napi_ok); - } else { - napi_value js_callback = nullptr; - if (!ref.IsEmpty()) { - v8::Local js_cb = - v8::Local::New(env->isolate, ref); - js_callback = v8impl::JsValueFromV8LocalValue(js_cb); - } - env->CallIntoModuleThrow([&](napi_env env) { - call_js_cb(env, js_callback, context, data); - }); + napi_value js_callback = nullptr; + if (!ref.IsEmpty()) { + v8::Local js_cb = + v8::Local::New(env->isolate, ref); + js_callback = v8impl::JsValueFromV8LocalValue(js_cb); } - } - } - - void MaybeStartIdle() { - if (uv_idle_start(&idle, IdleCb) != 0) { - v8::HandleScope scope(env->isolate); - CallbackScope cb_scope(this); - CHECK(napi_throw_error(env, - "ERR_NAPI_TSFN_START_IDLE_LOOP", - "Failed to start the idle loop") == napi_ok); + env->CallIntoModuleThrow([&](napi_env env) { + call_js_cb(env, js_callback, context, data); + }); } } @@ -435,7 +415,7 @@ class ThreadSafeFunction : public node::AsyncResource { static void AsyncCb(uv_async_t* async) { ThreadSafeFunction* ts_fn = node::ContainerOf(&ThreadSafeFunction::async, async); - ts_fn->MaybeStartIdle(); + CHECK_EQ(0, uv_idle_start(&ts_fn->idle, IdleCb)); } static void Cleanup(void* data) { diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 7926965302161c..99adccbcef9d64 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -53,6 +53,7 @@ using v8::Isolate; using v8::Local; using v8::Maybe; using v8::MaybeLocal; +using v8::MeasureMemoryExecution; using v8::MeasureMemoryMode; using v8::Name; using v8::NamedPropertyHandlerConfiguration; @@ -764,8 +765,8 @@ void ContextifyScript::New(const FunctionCallbackInfo& args) { env->cached_data_rejected_string(), Boolean::New(isolate, source.GetCachedData()->rejected)).Check(); } else if (produce_cached_data) { - const ScriptCompiler::CachedData* cached_data = - ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked()); + std::unique_ptr cached_data { + ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked()) }; bool cached_data_produced = cached_data != nullptr; if (cached_data_produced) { MaybeLocal buf = Buffer::Copy( @@ -1211,29 +1212,22 @@ static void WatchdogHasPendingSigint(const FunctionCallbackInfo& args) { static void MeasureMemory(const FunctionCallbackInfo& args) { CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsInt32()); int32_t mode = args[0].As()->Value(); + int32_t execution = args[1].As()->Value(); Isolate* isolate = args.GetIsolate(); - Environment* env = Environment::GetCurrent(args); - Local context; - if (args[1]->IsUndefined()) { - context = isolate->GetCurrentContext(); - } else { - CHECK(args[1]->IsObject()); - ContextifyContext* sandbox = - ContextifyContext::ContextFromContextifiedSandbox(env, - args[1].As()); - CHECK_NOT_NULL(sandbox); - context = sandbox->context(); - if (context.IsEmpty()) { // Not yet fully initialized - return; - } - } + + Local current_context = isolate->GetCurrentContext(); Local resolver; - if (!Promise::Resolver::New(context).ToLocal(&resolver)) return; - std::unique_ptr i = + if (!Promise::Resolver::New(current_context).ToLocal(&resolver)) return; + std::unique_ptr delegate = v8::MeasureMemoryDelegate::Default( - isolate, context, resolver, static_cast(mode)); - CHECK_NOT_NULL(i); + isolate, + current_context, + resolver, + static_cast(mode)); + isolate->MeasureMemory(std::move(delegate), + static_cast(execution)); v8::Local promise = resolver->GetPromise(); args.GetReturnValue().Set(promise); @@ -1265,13 +1259,27 @@ void Initialize(Local target, Local constants = Object::New(env->isolate()); Local measure_memory = Object::New(env->isolate()); - Local memory_mode = Object::New(env->isolate()); - MeasureMemoryMode SUMMARY = MeasureMemoryMode::kSummary; - MeasureMemoryMode DETAILED = MeasureMemoryMode::kDetailed; - NODE_DEFINE_CONSTANT(memory_mode, SUMMARY); - NODE_DEFINE_CONSTANT(memory_mode, DETAILED); - READONLY_PROPERTY(measure_memory, "mode", memory_mode); + Local memory_execution = Object::New(env->isolate()); + + { + Local memory_mode = Object::New(env->isolate()); + MeasureMemoryMode SUMMARY = MeasureMemoryMode::kSummary; + MeasureMemoryMode DETAILED = MeasureMemoryMode::kDetailed; + NODE_DEFINE_CONSTANT(memory_mode, SUMMARY); + NODE_DEFINE_CONSTANT(memory_mode, DETAILED); + READONLY_PROPERTY(measure_memory, "mode", memory_mode); + } + + { + MeasureMemoryExecution DEFAULT = MeasureMemoryExecution::kDefault; + MeasureMemoryExecution EAGER = MeasureMemoryExecution::kEager; + NODE_DEFINE_CONSTANT(memory_execution, DEFAULT); + NODE_DEFINE_CONSTANT(memory_execution, EAGER); + READONLY_PROPERTY(measure_memory, "execution", memory_execution); + } + READONLY_PROPERTY(constants, "measureMemory", measure_memory); + target->Set(context, env->constants_string(), constants).Check(); env->SetMethod(target, "measureMemory", MeasureMemory); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 348d407f0eb13a..afdb2e3c270348 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2486,7 +2486,7 @@ void SSLWrap::CertCbDone(const FunctionCallbackInfo& args) { // Store the SNI context for later use. w->sni_context_ = BaseObjectPtr(sc); - if (UseSNIContext(w->ssl_, sc) && !w->SetCACerts(sc)) { + if (UseSNIContext(w->ssl_, w->sni_context_) && !w->SetCACerts(sc)) { // Not clear why sometimes we throw error, and sometimes we call // onerror(). Both cause .destroy(), but onerror does a bit more. unsigned long err = ERR_get_error(); // NOLINT(runtime/int) @@ -5136,6 +5136,14 @@ bool DiffieHellman::Init(int primeLength, int g) { bool DiffieHellman::Init(const char* p, int p_len, int g) { dh_.reset(DH_new()); + if (p_len <= 0) { + BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + return false; + } + if (g <= 1) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + return false; + } BIGNUM* bn_p = BN_bin2bn(reinterpret_cast(p), p_len, nullptr); BIGNUM* bn_g = BN_new(); @@ -5151,10 +5159,23 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) { bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) { dh_.reset(DH_new()); - BIGNUM* bn_p = - BN_bin2bn(reinterpret_cast(p), p_len, nullptr); + if (p_len <= 0) { + BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + return false; + } + if (g_len <= 0) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + return false; + } BIGNUM* bn_g = BN_bin2bn(reinterpret_cast(g), g_len, nullptr); + if (BN_is_zero(bn_g) || BN_is_one(bn_g)) { + BN_free(bn_g); + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + return false; + } + BIGNUM* bn_p = + BN_bin2bn(reinterpret_cast(p), p_len, nullptr); if (!DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) { BN_free(bn_p); BN_free(bn_g); diff --git a/src/node_crypto_common.cc b/src/node_crypto_common.cc index 197bc5cd5913a4..3b35ee1ff7ba8a 100644 --- a/src/node_crypto_common.cc +++ b/src/node_crypto_common.cc @@ -1,3 +1,4 @@ +#include "base_object-inl.h" #include "env-inl.h" #include "node_buffer.h" #include "node_crypto.h" @@ -33,6 +34,7 @@ using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; +using v8::Undefined; using v8::Value; namespace crypto { @@ -223,7 +225,7 @@ long VerifyPeerCertificate( // NOLINT(runtime/int) return err; } -int UseSNIContext(const SSLPointer& ssl, SecureContext* context) { +int UseSNIContext(const SSLPointer& ssl, BaseObjectPtr context) { SSL_CTX* ctx = context->ctx_.get(); X509* x509 = SSL_CTX_get0_certificate(ctx); EVP_PKEY* pkey = SSL_CTX_get0_privatekey(ctx); @@ -329,11 +331,15 @@ const char* X509ErrorCode(long err) { // NOLINT(runtime/int) } MaybeLocal GetValidationErrorReason(Environment* env, int err) { + if (err == 0) + return Undefined(env->isolate()); const char* reason = X509_verify_cert_error_string(err); return OneByteString(env->isolate(), reason); } MaybeLocal GetValidationErrorCode(Environment* env, int err) { + if (err == 0) + return Undefined(env->isolate()); return OneByteString(env->isolate(), X509ErrorCode(err)); } diff --git a/src/node_crypto_common.h b/src/node_crypto_common.h index 8d40052bcca2f9..c373a97e4763a4 100644 --- a/src/node_crypto_common.h +++ b/src/node_crypto_common.h @@ -71,7 +71,7 @@ long VerifyPeerCertificate( // NOLINT(runtime/int) const SSLPointer& ssl, long def = X509_V_ERR_UNSPECIFIED); // NOLINT(runtime/int) -int UseSNIContext(const SSLPointer& ssl, SecureContext* context); +int UseSNIContext(const SSLPointer& ssl, BaseObjectPtr context); const char* GetClientHelloALPN(const SSLPointer& ssl); diff --git a/src/node_http2.cc b/src/node_http2.cc index 189f1d50a29a0d..6637166e954267 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -2309,7 +2309,7 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, return NGHTTP2_ERR_DEFERRED; } - if (stream->queue_.empty() && !stream->is_writable()) { + if (stream->available_outbound_length_ == 0 && !stream->is_writable()) { Debug(session, "no more data for stream %d", id); *flags |= NGHTTP2_DATA_FLAG_EOF; if (stream->has_trailers()) { diff --git a/src/node_mem.h b/src/node_mem.h index 0d3388ad4766bb..f8cdc20848f82e 100644 --- a/src/node_mem.h +++ b/src/node_mem.h @@ -13,8 +13,12 @@ namespace mem { // use different struct names. To allow for code re-use, // the NgLibMemoryManager template class can be used for both. +struct NgLibMemoryManagerBase { + virtual void StopTrackingMemory(void* ptr) = 0; +}; + template -class NgLibMemoryManager { +class NgLibMemoryManager : public NgLibMemoryManagerBase { public: // Class needs to provide these methods: // void CheckAllocatedSize(size_t previous_size) const; @@ -24,7 +28,7 @@ class NgLibMemoryManager { AllocatorStructName MakeAllocator(); - void StopTrackingMemory(void* ptr); + void StopTrackingMemory(void* ptr) override; private: static void* ReallocImpl(void* ptr, size_t size, void* user_data); diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc index b295dffd9d7bba..3c7d9bae0884c5 100644 --- a/src/node_task_queue.cc +++ b/src/node_task_queue.cc @@ -20,7 +20,6 @@ using v8::kPromiseRejectAfterResolved; using v8::kPromiseRejectWithNoHandler; using v8::kPromiseResolveAfterResolved; using v8::Local; -using v8::Message; using v8::MicrotasksScope; using v8::Number; using v8::Object; diff --git a/src/node_v8.cc b/src/node_v8.cc index a0f477430419f9..7174d9ae7f830b 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -29,8 +29,6 @@ namespace node { using v8::Array; -using v8::ArrayBuffer; -using v8::BackingStore; using v8::Context; using v8::FunctionCallbackInfo; using v8::HeapCodeStatistics; @@ -78,13 +76,29 @@ static constexpr size_t kHeapSpaceStatisticsPropertiesCount = HEAP_SPACE_STATISTICS_PROPERTIES(V); #undef V +#define HEAP_CODE_STATISTICS_PROPERTIES(V) \ + V(0, code_and_metadata_size, kCodeAndMetadataSizeIndex) \ + V(1, bytecode_and_metadata_size, kBytecodeAndMetadataSizeIndex) \ + V(2, external_script_source_size, kExternalScriptSourceSizeIndex) + +#define V(a, b, c) +1 +static const size_t kHeapCodeStatisticsPropertiesCount = + HEAP_CODE_STATISTICS_PROPERTIES(V); +#undef V + class BindingData : public BaseObject { public: - BindingData(Environment* env, Local obj) : BaseObject(env, obj) {} - - std::shared_ptr heap_statistics_buffer; - std::shared_ptr heap_space_statistics_buffer; - std::shared_ptr heap_code_statistics_buffer; + BindingData(Environment* env, Local obj) + : BaseObject(env, obj), + heap_statistics_buffer(env->isolate(), kHeapStatisticsPropertiesCount), + heap_space_statistics_buffer(env->isolate(), + kHeapSpaceStatisticsPropertiesCount), + heap_code_statistics_buffer(env->isolate(), + kHeapCodeStatisticsPropertiesCount) {} + + AliasedFloat64Array heap_statistics_buffer; + AliasedFloat64Array heap_space_statistics_buffer; + AliasedFloat64Array heap_code_statistics_buffer; void MemoryInfo(MemoryTracker* tracker) const override { tracker->TrackField("heap_statistics_buffer", heap_statistics_buffer); @@ -97,15 +111,6 @@ class BindingData : public BaseObject { SET_MEMORY_INFO_NAME(BindingData) }; -#define HEAP_CODE_STATISTICS_PROPERTIES(V) \ - V(0, code_and_metadata_size, kCodeAndMetadataSizeIndex) \ - V(1, bytecode_and_metadata_size, kBytecodeAndMetadataSizeIndex) \ - V(2, external_script_source_size, kExternalScriptSourceSizeIndex) - -#define V(a, b, c) +1 -static const size_t kHeapCodeStatisticsPropertiesCount = - HEAP_CODE_STATISTICS_PROPERTIES(V); -#undef V void CachedDataVersionTag(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -115,13 +120,11 @@ void CachedDataVersionTag(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(result); } - -void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { +void UpdateHeapStatisticsBuffer(const FunctionCallbackInfo& args) { BindingData* data = Unwrap(args.Data()); HeapStatistics s; args.GetIsolate()->GetHeapStatistics(&s); - double* const buffer = - static_cast(data->heap_statistics_buffer->Data()); + AliasedFloat64Array& buffer = data->heap_statistics_buffer; #define V(index, name, _) buffer[index] = static_cast(s.name()); HEAP_STATISTICS_PROPERTIES(V) #undef V @@ -132,29 +135,23 @@ void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo& args) { BindingData* data = Unwrap(args.Data()); HeapSpaceStatistics s; Isolate* const isolate = args.GetIsolate(); - size_t number_of_heap_spaces = isolate->NumberOfHeapSpaces(); + CHECK(args[0]->IsUint32()); + size_t space_index = static_cast(args[0].As()->Value()); + isolate->GetHeapSpaceStatistics(&s, space_index); - double* const buffer = - static_cast(data->heap_space_statistics_buffer->Data()); + AliasedFloat64Array& buffer = data->heap_space_statistics_buffer; - for (size_t i = 0; i < number_of_heap_spaces; i++) { - isolate->GetHeapSpaceStatistics(&s, i); - size_t const property_offset = i * kHeapSpaceStatisticsPropertiesCount; -#define V(index, name, _) \ - buffer[property_offset + index] = static_cast(s.name()); - HEAP_SPACE_STATISTICS_PROPERTIES(V) +#define V(index, name, _) buffer[index] = static_cast(s.name()); + HEAP_SPACE_STATISTICS_PROPERTIES(V) #undef V - } } - -void UpdateHeapCodeStatisticsArrayBuffer( - const FunctionCallbackInfo& args) { +void UpdateHeapCodeStatisticsBuffer(const FunctionCallbackInfo& args) { BindingData* data = Unwrap(args.Data()); HeapCodeStatistics s; args.GetIsolate()->GetHeapCodeAndMetadataStatistics(&s); - double* const buffer = - static_cast(data->heap_code_statistics_buffer->Data()); + AliasedFloat64Array& buffer = data->heap_code_statistics_buffer; + #define V(index, name, _) buffer[index] = static_cast(s.name()); HEAP_CODE_STATISTICS_PROPERTIES(V) #undef V @@ -181,20 +178,14 @@ void Initialize(Local target, CachedDataVersionTag); // Export symbols used by v8.getHeapStatistics() - env->SetMethod(target, - "updateHeapStatisticsArrayBuffer", - UpdateHeapStatisticsArrayBuffer); + env->SetMethod( + target, "updateHeapStatisticsBuffer", UpdateHeapStatisticsBuffer); - const size_t heap_statistics_buffer_byte_length = - sizeof(double) * kHeapStatisticsPropertiesCount; - - Local heap_statistics_ab = - ArrayBuffer::New(env->isolate(), heap_statistics_buffer_byte_length); - binding_data->heap_statistics_buffer = heap_statistics_ab->GetBackingStore(); - target->Set(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), - "heapStatisticsArrayBuffer"), - heap_statistics_ab).Check(); + target + ->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "heapStatisticsBuffer"), + binding_data->heap_statistics_buffer.GetJSArray()) + .Check(); #define V(i, _, name) \ target->Set(env->context(), \ @@ -205,22 +196,14 @@ void Initialize(Local target, #undef V // Export symbols used by v8.getHeapCodeStatistics() - env->SetMethod(target, - "updateHeapCodeStatisticsArrayBuffer", - UpdateHeapCodeStatisticsArrayBuffer); - - const size_t heap_code_statistics_buffer_byte_length = - sizeof(double) * kHeapCodeStatisticsPropertiesCount; + env->SetMethod( + target, "updateHeapCodeStatisticsBuffer", UpdateHeapCodeStatisticsBuffer); - Local heap_code_statistics_ab = - ArrayBuffer::New(env->isolate(), - heap_code_statistics_buffer_byte_length); - binding_data->heap_code_statistics_buffer = - heap_code_statistics_ab->GetBackingStore(); - target->Set(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), - "heapCodeStatisticsArrayBuffer"), - heap_code_statistics_ab).Check(); + target + ->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "heapCodeStatisticsBuffer"), + binding_data->heap_code_statistics_buffer.GetJSArray()) + .Check(); #define V(i, _, name) \ target->Set(env->context(), \ @@ -230,14 +213,6 @@ void Initialize(Local target, HEAP_CODE_STATISTICS_PROPERTIES(V) #undef V - // Export symbols used by v8.getHeapSpaceStatistics() - target->Set(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), - "kHeapSpaceStatisticsPropertiesCount"), - Uint32::NewFromUnsigned(env->isolate(), - kHeapSpaceStatisticsPropertiesCount)) - .Check(); - size_t number_of_heap_spaces = env->isolate()->NumberOfHeapSpaces(); // Heap space names are extracted once and exposed to JavaScript to @@ -258,24 +233,15 @@ void Initialize(Local target, number_of_heap_spaces)).Check(); env->SetMethod(target, - "updateHeapSpaceStatisticsArrayBuffer", + "updateHeapSpaceStatisticsBuffer", UpdateHeapSpaceStatisticsBuffer); - const size_t heap_space_statistics_buffer_byte_length = - sizeof(double) * - kHeapSpaceStatisticsPropertiesCount * - number_of_heap_spaces; - - Local heap_space_statistics_ab = - ArrayBuffer::New(env->isolate(), - heap_space_statistics_buffer_byte_length); - binding_data->heap_space_statistics_buffer = - heap_space_statistics_ab->GetBackingStore(); - - target->Set(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), - "heapSpaceStatisticsArrayBuffer"), - heap_space_statistics_ab).Check(); + target + ->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), + "heapSpaceStatisticsBuffer"), + binding_data->heap_space_statistics_buffer.GetJSArray()) + .Check(); #define V(i, _, name) \ target->Set(env->context(), \ diff --git a/src/node_version.h b/src/node_version.h index 78d1640de6834a..8c4a897ea2dcda 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 14 -#define NODE_MINOR_VERSION 1 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 2 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/node_wasi.cc b/src/node_wasi.cc index f4670ea36f6525..0330656b29e926 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -236,7 +236,7 @@ void WASI::New(const FunctionCallbackInfo& args) { free(options.preopens[i].real_path); } - delete[] options.preopens; + free(options.preopens); } } diff --git a/src/node_worker.cc b/src/node_worker.cc index 913b5e3a8bd306..1e1d9434cddb4c 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -39,6 +39,8 @@ using v8::Value; namespace node { namespace worker { +constexpr double kMB = 1024 * 1024; + Worker::Worker(Environment* env, Local wrap, const std::string& url, @@ -93,8 +95,6 @@ bool Worker::is_stopped() const { void Worker::UpdateResourceConstraints(ResourceConstraints* constraints) { constraints->set_stack_limit(reinterpret_cast(stack_base_)); - constexpr double kMB = 1024 * 1024; - if (resource_limits_[kMaxYoungGenerationSizeMb] > 0) { constraints->set_max_young_generation_size_in_bytes( resource_limits_[kMaxYoungGenerationSizeMb] * kMB); @@ -131,9 +131,7 @@ class WorkerThreadData { if (ret != 0) { char err_buf[128]; uv_err_name_r(ret, err_buf, sizeof(err_buf)); - w->custom_error_ = "ERR_WORKER_INIT_FAILED"; - w->custom_error_str_ = err_buf; - w->stopped_ = true; + w->Exit(1, "ERR_WORKER_INIT_FAILED", err_buf); return; } loop_init_failed_ = false; @@ -148,9 +146,9 @@ class WorkerThreadData { Isolate* isolate = Isolate::Allocate(); if (isolate == nullptr) { - w->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - w->custom_error_str_ = "Failed to create new Isolate"; - w->stopped_ = true; + // TODO(addaleax): This should be ERR_WORKER_INIT_FAILED, + // ERR_WORKER_OUT_OF_MEMORY is for reaching the per-Worker heap limit. + w->Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "Failed to create new Isolate"); return; } @@ -233,9 +231,7 @@ class WorkerThreadData { size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit, size_t initial_heap_limit) { Worker* worker = static_cast(data); - worker->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - worker->custom_error_str_ = "JS heap out of memory"; - worker->Exit(1); + worker->Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "JS heap out of memory"); // Give the current GC some extra leeway to let it finish rather than // crash hard. We are not going to perform further allocations anyway. constexpr size_t kExtraHeapAllowance = 16 * 1024 * 1024; @@ -292,8 +288,9 @@ void Worker::Run() { TryCatch try_catch(isolate_); context = NewContext(isolate_); if (context.IsEmpty()) { - custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - custom_error_str_ = "Failed to create new Context"; + // TODO(addaleax): This should be ERR_WORKER_INIT_FAILED, + // ERR_WORKER_OUT_OF_MEMORY is for reaching the per-Worker heap limit. + Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "Failed to create new Context"); return; } } @@ -592,9 +589,20 @@ void Worker::StartThread(const FunctionCallbackInfo& args) { w->stopped_ = false; + if (w->resource_limits_[kStackSizeMb] > 0) { + if (w->resource_limits_[kStackSizeMb] * kMB < kStackBufferSize) { + w->resource_limits_[kStackSizeMb] = kStackBufferSize / kMB; + w->stack_size_ = kStackBufferSize; + } else { + w->stack_size_ = w->resource_limits_[kStackSizeMb] * kMB; + } + } else { + w->resource_limits_[kStackSizeMb] = w->stack_size_ / kMB; + } + uv_thread_options_t thread_options; thread_options.flags = UV_THREAD_HAS_STACK_SIZE; - thread_options.stack_size = kStackSize; + thread_options.stack_size = w->stack_size_; int ret = uv_thread_create_ex(&w->tid_, &thread_options, [](void* arg) { // XXX: This could become a std::unique_ptr, but that makes at least // gcc 6.3 detect undefined behaviour when there shouldn't be any. @@ -604,7 +612,7 @@ void Worker::StartThread(const FunctionCallbackInfo& args) { // Leave a few kilobytes just to make sure we're within limits and have // some space to do work in C++ land. - w->stack_base_ = stack_top - (kStackSize - kStackBufferSize); + w->stack_base_ = stack_top - (w->stack_size_ - kStackBufferSize); w->Run(); @@ -682,9 +690,16 @@ Local Worker::GetResourceLimits(Isolate* isolate) const { return Float64Array::New(ab, 0, kTotalResourceLimitCount); } -void Worker::Exit(int code) { +void Worker::Exit(int code, const char* error_code, const char* error_message) { Mutex::ScopedLock lock(mutex_); - Debug(this, "Worker %llu called Exit(%d)", thread_id_.id, code); + Debug(this, "Worker %llu called Exit(%d, %s, %s)", + thread_id_.id, code, error_code, error_message); + + if (error_code != nullptr) { + custom_error_ = error_code; + custom_error_str_ = error_message; + } + if (env_ != nullptr) { exit_code_ = code; Stop(env_); @@ -830,6 +845,7 @@ void InitWorker(Local target, NODE_DEFINE_CONSTANT(target, kMaxYoungGenerationSizeMb); NODE_DEFINE_CONSTANT(target, kMaxOldGenerationSizeMb); NODE_DEFINE_CONSTANT(target, kCodeRangeSizeMb); + NODE_DEFINE_CONSTANT(target, kStackSizeMb); NODE_DEFINE_CONSTANT(target, kTotalResourceLimitCount); } diff --git a/src/node_worker.h b/src/node_worker.h index b962e5757a6f75..1b9ba322bed04f 100644 --- a/src/node_worker.h +++ b/src/node_worker.h @@ -16,6 +16,7 @@ enum ResourceLimits { kMaxYoungGenerationSizeMb, kMaxOldGenerationSizeMb, kCodeRangeSizeMb, + kStackSizeMb, kTotalResourceLimitCount }; @@ -34,8 +35,11 @@ class Worker : public AsyncWrap { void Run(); // Forcibly exit the thread with a specified exit code. This may be called - // from any thread. - void Exit(int code); + // from any thread. `error_code` and `error_message` can be used to create + // a custom `'error'` event before emitting `'exit'`. + void Exit(int code, + const char* error_code = nullptr, + const char* error_message = nullptr); // Wait for the worker thread to stop (in a blocking manner). void JoinThread(); @@ -92,7 +96,7 @@ class Worker : public AsyncWrap { void UpdateResourceConstraints(v8::ResourceConstraints* constraints); // Full size of the thread's stack. - static constexpr size_t kStackSize = 4 * 1024 * 1024; + size_t stack_size_ = 4 * 1024 * 1024; // Stack buffer size that is not available to the JS engine. static constexpr size_t kStackBufferSize = 192 * 1024; diff --git a/test/addons/worker-buffer-callback/binding.cc b/test/addons/worker-buffer-callback/binding.cc index f600f410c1ed18..ac4c0cb498b7c7 100644 --- a/test/addons/worker-buffer-callback/binding.cc +++ b/test/addons/worker-buffer-callback/binding.cc @@ -30,7 +30,7 @@ void Initialize(Local exports, node::Buffer::New( isolate, data, - sizeof(data), + sizeof(char), [](char* data, void* hint) { delete data; free_call_count++; diff --git a/test/common/measure-memory.js b/test/common/measure-memory.js new file mode 100644 index 00000000000000..67c8fb3b9d2d67 --- /dev/null +++ b/test/common/measure-memory.js @@ -0,0 +1,57 @@ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ +'use strict'; + +const assert = require('assert'); +const common = require('./'); + +// The formats could change when V8 is updated, then the tests should be +// updated accordingly. +function assertResultShape(result) { + assert.strictEqual(typeof result.jsMemoryEstimate, 'number'); + assert.strictEqual(typeof result.jsMemoryRange[0], 'number'); + assert.strictEqual(typeof result.jsMemoryRange[1], 'number'); +} + +function assertSummaryShape(result) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assertResultShape(result.total); +} + +function assertDetailedShape(result, contexts = 0) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assert.strictEqual(typeof result.current, 'object'); + assertResultShape(result.total); + assertResultShape(result.current); + if (contexts === 0) { + assert.deepStrictEqual(result.other, []); + } else { + assert.strictEqual(result.other.length, contexts); + for (const item of result.other) { + assertResultShape(item); + } + } +} + +function assertSingleDetailedShape(result) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assert.strictEqual(typeof result.current, 'object'); + assert.deepStrictEqual(result.other, []); + assertResultShape(result.total); + assertResultShape(result.current); +} + +function expectExperimentalWarning() { + common.expectWarning('ExperimentalWarning', + 'vm.measureMemory is an experimental feature. ' + + 'This feature could change at any time'); +} + +module.exports = { + assertSummaryShape, + assertDetailedShape, + assertSingleDetailedShape, + expectExperimentalWarning +}; diff --git a/test/es-module/test-esm-type-main.mjs b/test/es-module/test-esm-type-main.mjs new file mode 100644 index 00000000000000..012cf4f35fc959 --- /dev/null +++ b/test/es-module/test-esm-type-main.mjs @@ -0,0 +1,9 @@ +import { mustNotCall } from '../common/index.mjs'; +import assert from 'assert'; +import { importFixture } from '../fixtures/pkgexports.mjs'; + +(async () => { + const m = await importFixture('type-main'); + assert.strictEqual(m.default, 'asdf'); +})() +.catch(mustNotCall); diff --git a/test/fixtures/esm_loader_not_found_cjs_hint_bare.mjs b/test/fixtures/esm_loader_not_found_cjs_hint_bare.mjs new file mode 100644 index 00000000000000..4eb5f190af43e4 --- /dev/null +++ b/test/fixtures/esm_loader_not_found_cjs_hint_bare.mjs @@ -0,0 +1,5 @@ +'use strict'; + +import obj from 'some_module/obj'; + +throw new Error('Should have errored'); diff --git a/test/fixtures/node_modules/some_module/index.js b/test/fixtures/node_modules/some_module/index.js new file mode 100644 index 00000000000000..a2d739266cdca4 --- /dev/null +++ b/test/fixtures/node_modules/some_module/index.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = { main: true } diff --git a/test/fixtures/node_modules/some_module/obj.js b/test/fixtures/node_modules/some_module/obj.js new file mode 100644 index 00000000000000..249478e5ca506f --- /dev/null +++ b/test/fixtures/node_modules/some_module/obj.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = { obj: 'module' } diff --git a/test/fixtures/node_modules/some_module/package.json b/test/fixtures/node_modules/some_module/package.json new file mode 100644 index 00000000000000..95a52cc61071a5 --- /dev/null +++ b/test/fixtures/node_modules/some_module/package.json @@ -0,0 +1,12 @@ +{ + "name": "some_module", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/test/fixtures/node_modules/type-main/index.js b/test/fixtures/node_modules/type-main/index.js new file mode 100644 index 00000000000000..a4cb53964349f5 --- /dev/null +++ b/test/fixtures/node_modules/type-main/index.js @@ -0,0 +1 @@ +export default 'asdf'; diff --git a/test/fixtures/node_modules/type-main/package.json b/test/fixtures/node_modules/type-main/package.json new file mode 100644 index 00000000000000..7665d7a8037428 --- /dev/null +++ b/test/fixtures/node_modules/type-main/package.json @@ -0,0 +1,4 @@ +{ + "main": "index", + "type": "module" +} diff --git a/test/message/esm_loader_not_found_cjs_hint_bare.js b/test/message/esm_loader_not_found_cjs_hint_bare.js new file mode 100644 index 00000000000000..b049fd203fef06 --- /dev/null +++ b/test/message/esm_loader_not_found_cjs_hint_bare.js @@ -0,0 +1,17 @@ +'use strict'; + +require('../common'); +const { spawn } = require('child_process'); +const { join } = require('path'); +const { fixturesDir } = require('../common/fixtures'); + +spawn( + process.execPath, + [ + join(fixturesDir, 'esm_loader_not_found_cjs_hint_bare.mjs') + ], + { + cwd: fixturesDir, + stdio: 'inherit' + } +); diff --git a/test/message/esm_loader_not_found_cjs_hint_bare.out b/test/message/esm_loader_not_found_cjs_hint_bare.out new file mode 100644 index 00000000000000..e56f1da0f6e76e --- /dev/null +++ b/test/message/esm_loader_not_found_cjs_hint_bare.out @@ -0,0 +1,16 @@ +internal/modules/run_main.js:* + internalBinding('errors').triggerUncaughtException( + ^ + +Error [ERR_MODULE_NOT_FOUND]: Cannot find module '*test*fixtures*node_modules*some_module*obj' imported from *test*fixtures*esm_loader_not_found_cjs_hint_bare.mjs +Did you mean to import some_module/obj.js? + at finalizeResolution (internal/modules/esm/resolve.js:*:*) + at packageResolve (internal/modules/esm/resolve.js:*:*) + at moduleResolve (internal/modules/esm/resolve.js:*:*) + at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:*:*) + at Loader.resolve (internal/modules/esm/loader.js:*:*) + at Loader.getModuleJob (internal/modules/esm/loader.js:*:*) + at ModuleWrap. (internal/modules/esm/module_job.js:*:*) + at link (internal/modules/esm/module_job.js:*:*) { + code: 'ERR_MODULE_NOT_FOUND' +} diff --git a/test/message/esm_loader_not_found_cjs_hint_relative.mjs b/test/message/esm_loader_not_found_cjs_hint_relative.mjs new file mode 100644 index 00000000000000..928186318bb09a --- /dev/null +++ b/test/message/esm_loader_not_found_cjs_hint_relative.mjs @@ -0,0 +1,3 @@ +// Flags: --experimental-loader ./test/common/fixtures +import '../common/index.mjs'; +console.log('This should not be printed'); diff --git a/test/message/esm_loader_not_found_cjs_hint_relative.out b/test/message/esm_loader_not_found_cjs_hint_relative.out new file mode 100644 index 00000000000000..76df3163bb728c --- /dev/null +++ b/test/message/esm_loader_not_found_cjs_hint_relative.out @@ -0,0 +1,20 @@ +(node:*) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time +(Use `node --trace-warnings ...` to show where the warning was created) +internal/modules/run_main.js:* + internalBinding('errors').triggerUncaughtException( + ^ + +Error [ERR_MODULE_NOT_FOUND]: Cannot find module '*test*common*fixtures' imported from * +Did you mean to import ./test/common/fixtures.js? + at finalizeResolution (internal/modules/esm/resolve.js:*:*) + at moduleResolve (internal/modules/esm/resolve.js:*:*) + at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:*:*) + at Loader.resolve (internal/modules/esm/loader.js:*:*) + at Loader.getModuleJob (internal/modules/esm/loader.js:*:*) + at Loader.import (internal/modules/esm/loader.js:*:*) + at internal/process/esm_loader.js:*:* + at Object.initializeLoader (internal/process/esm_loader.js:*:*) + at runMainESM (internal/modules/run_main.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) { + code: 'ERR_MODULE_NOT_FOUND' +} diff --git a/test/node-api/test_callback_scope/binding.cc b/test/node-api/test_callback_scope/binding.cc index 153428a65bd6e4..a8a755a016a7ee 100644 --- a/test/node-api/test_callback_scope/binding.cc +++ b/test/node-api/test_callback_scope/binding.cc @@ -47,6 +47,7 @@ napi_value RunInCallbackScope(napi_env env, napi_callback_info info) { } NAPI_CALL(env, napi_close_callback_scope(env, scope)); + NAPI_CALL(env, napi_async_destroy(env, context)); return result; } @@ -85,6 +86,7 @@ static void Callback(uv_work_t* req, int ignored) { NAPI_CALL_RETURN_VOID(env, napi_close_callback_scope(env, scope)); NAPI_CALL_RETURN_VOID(env, napi_close_handle_scope(env, handle_scope)); + NAPI_CALL_RETURN_VOID(env, napi_async_destroy(env, context)); delete req; } diff --git a/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c b/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c index 3275551aee526a..b4f2e288ece31b 100644 --- a/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c +++ b/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c @@ -35,7 +35,7 @@ NAPI_MODULE_INIT() { NAPI_CALL(env, napi_create_external_arraybuffer( env, data, - sizeof(data), + sizeof(char), finalize_cb, NULL, &buffer)); diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 8703fea2b0b3a7..193cd820ac9683 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -46,6 +46,12 @@ test-crypto-keygen: SKIP [$system==freebsd] # https://github.com/nodejs/node/issues/31727 test-fs-stat-bigint: PASS,FLAKY +# https://github.com/nodejs/node/issues/29802 +test-http2-reset-flood: PASS,FLAKY +# https://github.com/nodejs/node/issues/28803 +test-stdout-close-catch: PASS,FLAKY +# https://github.com/nodejs/node/issues/31280 +test-worker-message-port-message-before-close: PASS,FLAKY [$system==aix] diff --git a/test/parallel/test-assert-calltracker-calls.js b/test/parallel/test-assert-calltracker-calls.js new file mode 100644 index 00000000000000..4de23d4658468a --- /dev/null +++ b/test/parallel/test-assert-calltracker-calls.js @@ -0,0 +1,66 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// This test ensures that assert.CallTracker.calls() works as intended. + +const tracker = new assert.CallTracker(); + +function bar() {} + +const err = { + code: 'ERR_INVALID_ARG_TYPE', +}; + +// Ensures calls() throws on invalid input types. +assert.throws(() => { + const callsbar = tracker.calls(bar, '1'); + callsbar(); +}, err +); + +assert.throws(() => { + const callsbar = tracker.calls(bar, 0.1); + callsbar(); +}, { code: 'ERR_OUT_OF_RANGE' } +); + +assert.throws(() => { + const callsbar = tracker.calls(bar, true); + callsbar(); +}, err +); + +assert.throws(() => { + const callsbar = tracker.calls(bar, () => {}); + callsbar(); +}, err +); + +assert.throws(() => { + const callsbar = tracker.calls(bar, null); + callsbar(); +}, err +); + +// Expects an error as tracker.calls() cannot be called within a process exit +// handler. +process.on('exit', () => { + assert.throws(() => tracker.calls(bar, 1), { + code: 'ERR_UNAVAILABLE_DURING_EXIT', + }); +}); + +const msg = 'Expected to throw'; + +function func() { + throw new Error(msg); +} + +const callsfunc = tracker.calls(func, 1); + +// Expects callsfunc() to call func() which throws an error. +assert.throws( + () => callsfunc(), + { message: msg } +); diff --git a/test/parallel/test-assert-calltracker-report.js b/test/parallel/test-assert-calltracker-report.js new file mode 100644 index 00000000000000..79186c88fd058b --- /dev/null +++ b/test/parallel/test-assert-calltracker-report.js @@ -0,0 +1,32 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// This test ensures that the assert.CallTracker.report() works as intended. + +const tracker = new assert.CallTracker(); + +function foo() {} + +const callsfoo = tracker.calls(foo, 1); + +// Ensures that foo was added to the callChecks array. +if (tracker.report()[0].operator !== 'foo') { + process.exit(1); +} + +callsfoo(); + +// Ensures that foo was removed from the callChecks array after being called the +// expected number of times. +if (typeof tracker.report()[0] === undefined) { + process.exit(1); +} + +callsfoo(); + +// Ensures that foo was added back to the callChecks array after being called +// more than the expected number of times. +if (tracker.report()[0].operator !== 'foo') { + process.exit(1); +} diff --git a/test/parallel/test-assert-calltracker-verify.js b/test/parallel/test-assert-calltracker-verify.js new file mode 100644 index 00000000000000..75d20bf9c49c38 --- /dev/null +++ b/test/parallel/test-assert-calltracker-verify.js @@ -0,0 +1,32 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// This test ensures that assert.CallTracker.verify() works as intended. + +const tracker = new assert.CallTracker(); + +const msg = 'Function(s) were not called the expected number of times'; + +function foo() {} + +const callsfoo = tracker.calls(foo, 1); + +// Expects an error as callsfoo() was called less than one time. +assert.throws( + () => tracker.verify(), + { message: msg } +); + +callsfoo(); + +// Will throw an error if callsfoo() isn't called exactly once. +tracker.verify(); + +callsfoo(); + +// Expects an error as callsfoo() was called more than once. +assert.throws( + () => tracker.verify(), + { message: msg } +); diff --git a/test/parallel/test-cluster-concurrent-disconnect.js b/test/parallel/test-cluster-concurrent-disconnect.js new file mode 100644 index 00000000000000..22f72040263027 --- /dev/null +++ b/test/parallel/test-cluster-concurrent-disconnect.js @@ -0,0 +1,48 @@ +'use strict'; + +// Ref: https://github.com/nodejs/node/issues/32106 + +const common = require('../common'); + +const assert = require('assert'); +const cluster = require('cluster'); +const os = require('os'); + +if (cluster.isMaster) { + const workers = []; + const numCPUs = os.cpus().length; + let waitOnline = numCPUs; + for (let i = 0; i < numCPUs; i++) { + const worker = cluster.fork(); + workers[i] = worker; + worker.once('online', common.mustCall(() => { + if (--waitOnline === 0) + for (const worker of workers) + if (worker.isConnected()) + worker.send(i % 2 ? 'disconnect' : 'destroy'); + })); + + // These errors can occur due to the nature of the test, we might be trying + // to send messages when the worker is disconnecting. + worker.on('error', (err) => { + assert.strictEqual(err.syscall, 'write'); + assert.strictEqual(err.code, 'EPIPE'); + }); + + worker.once('disconnect', common.mustCall(() => { + for (const worker of workers) + if (worker.isConnected()) + worker.send('disconnect'); + })); + + worker.once('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + } +} else { + process.on('message', (msg) => { + if (cluster.worker.isConnected()) + cluster.worker[msg](); + }); +} diff --git a/test/parallel/test-console-group.js b/test/parallel/test-console-group.js index 99c01fc36ea469..9b7e836a436add 100644 --- a/test/parallel/test-console-group.js +++ b/test/parallel/test-console-group.js @@ -12,7 +12,7 @@ const Console = require('console').Console; let c, stdout, stderr; -function setup() { +function setup(groupIndentation) { stdout = ''; hijackStdout(function(data) { stdout += data; @@ -25,7 +25,8 @@ function setup() { c = new Console({ stdout: process.stdout, stderr: process.stderr, - colorMode: false }); + colorMode: false, + groupIndentation: groupIndentation }); } function teardown() { @@ -155,3 +156,86 @@ function teardown() { assert(!keys.includes('Symbol(groupIndent)'), 'groupIndent should not be enumerable'); } + +// Check custom groupIndentation. +{ + setup(3); + const expectedOut = 'Set the groupIndentation parameter to 3\n' + + 'This is the outer level\n' + + ' Level 2\n' + + ' Level 3\n' + + ' Back to level 2\n' + + 'Back to the outer level\n' + + 'Still at the outer level\n'; + + + const expectedErr = ' More of level 3\n'; + + c.log('Set the groupIndentation parameter to 3'); + c.log('This is the outer level'); + c.group(); + c.log('Level 2'); + c.group(); + c.log('Level 3'); + c.warn('More of level 3'); + c.groupEnd(); + c.log('Back to level 2'); + c.groupEnd(); + c.log('Back to the outer level'); + c.groupEnd(); + c.log('Still at the outer level'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Check the correctness of the groupIndentation parameter. +{ + // TypeError + [null, 'str', [], false, true, {}].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + }); + + // RangeError for integer + [NaN, 1.01].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /an integer/, + } + ); + }); + + // RangeError + [-1, 1001].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: />= 0 && <= 1000/, + } + ); + }); +} diff --git a/test/parallel/test-crypto-dh-leak.js b/test/parallel/test-crypto-dh-leak.js index 9ba8d29e155dc6..65486dbd80cb64 100644 --- a/test/parallel/test-crypto-dh-leak.js +++ b/test/parallel/test-crypto-dh-leak.js @@ -4,6 +4,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +if (process.config.variables.asan) + common.skip('ASAN messes with memory measurements'); const assert = require('assert'); const crypto = require('crypto'); diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index baa7402a88fdb6..b23a51c491a9b5 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -20,6 +20,62 @@ assert.strictEqual(secret2.toString('base64'), secret1); assert.strictEqual(dh1.verifyError, 0); assert.strictEqual(dh2.verifyError, 0); +// https://github.com/nodejs/node/issues/32738 +// XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError +// instead of ERR_INVALID_ARG_TYPE and TypeError is questionable, IMO. +assert.throws(() => crypto.createDiffieHellman(13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "sizeOrKey" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +assert.throws(() => crypto.createDiffieHellman('abcdef', 13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "generator" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +for (const bits of [-1, 0, 1]) { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_BN_BITS_TOO_SMALL', + name: 'Error', + message: /bits too small/, + }); +} + +// Through a fluke of history, g=0 defaults to DH_GENERATOR (2). +{ + const g = 0; + crypto.createDiffieHellman('abcdef', g); + crypto.createDiffieHellman('abcdef', 'hex', g); +} + +for (const g of [-1, 1]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + +crypto.createDiffieHellman('abcdef', Buffer.from([2])); // OK + +for (const g of [Buffer.from([]), + Buffer.from([0]), + Buffer.from([1])]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + { const DiffieHellman = crypto.DiffieHellman; const dh = DiffieHellman(p1, 'buffer'); diff --git a/test/parallel/test-dgram-connect.js b/test/parallel/test-dgram-connect.js index a9815f439a731a..30e817f344a42c 100644 --- a/test/parallel/test-dgram-connect.js +++ b/test/parallel/test-dgram-connect.js @@ -60,7 +60,7 @@ assert.throws(() => { client.connect(port); }, { name: 'RangeError', - message: /^Port should be >= 0 and < 65536/, + message: /^Port should be > 0 and < 65536/, code: 'ERR_SOCKET_BAD_PORT' }); }); diff --git a/test/parallel/test-http-agent-close.js b/test/parallel/test-http-agent-close.js new file mode 100644 index 00000000000000..84ed5e57c5fb86 --- /dev/null +++ b/test/parallel/test-http-agent-close.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const agent = new http.Agent(); +const _err = new Error('kaboom'); +agent.createSocket = function(req, options, cb) { + cb(_err); +}; + +const req = http + .request({ + agent + }) + .on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })) + .on('close', common.mustCall(() => { + assert.strictEqual(req.destroyed, true); + })); diff --git a/test/parallel/test-http-agent-timeout.js b/test/parallel/test-http-agent-timeout.js index d8d34414d991a1..07c189e9745330 100644 --- a/test/parallel/test-http-agent-timeout.js +++ b/test/parallel/test-http-agent-timeout.js @@ -92,3 +92,43 @@ const http = require('http'); })); })); } + +{ + // Ensure custom keepSocketAlive timeout is respected + + const CUSTOM_TIMEOUT = 60; + const AGENT_TIMEOUT = 50; + + class CustomAgent extends http.Agent { + keepSocketAlive(socket) { + if (!super.keepSocketAlive(socket)) { + return false; + } + + socket.setTimeout(CUSTOM_TIMEOUT); + return true; + } + } + + const agent = new CustomAgent({ keepAlive: true, timeout: AGENT_TIMEOUT }); + + const server = http.createServer((req, res) => { + res.end(); + }); + + server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port, agent }) + .on('response', common.mustCall((res) => { + const socket = res.socket; + assert(socket); + res.resume(); + socket.on('free', common.mustCall(() => { + socket.on('timeout', common.mustCall(() => { + assert.strictEqual(socket.timeout, CUSTOM_TIMEOUT); + agent.destroy(); + server.close(); + })); + })); + })); + })); +} diff --git a/test/parallel/test-readable-from-iterator-closing.js b/test/parallel/test-readable-from-iterator-closing.js index 0254ccfc163093..02252ffe56854c 100644 --- a/test/parallel/test-readable-from-iterator-closing.js +++ b/test/parallel/test-readable-from-iterator-closing.js @@ -168,18 +168,17 @@ async function closeAfterNullYielded() { const finallyMustCall = mustCall(); const dataMustCall = mustCall(3); - function* infiniteGenerate() { + function* generate() { try { yield 'a'; yield 'a'; yield 'a'; - while (true) yield null; } finally { finallyMustCall(); } } - const stream = Readable.from(infiniteGenerate()); + const stream = Readable.from(generate()); stream.on('data', (chunk) => { dataMustCall(); diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index d4336e84db35d6..4622d2c695e1fa 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -1,7 +1,14 @@ 'use strict'; const common = require('../common'); -const { Writable, Readable, Transform, finished, Duplex } = require('stream'); +const { + Writable, + Readable, + Transform, + finished, + Duplex, + PassThrough +} = require('stream'); const assert = require('assert'); const EE = require('events'); const fs = require('fs'); @@ -396,3 +403,80 @@ testClosed((opts) => new Writable({ write() {}, ...opts })); r.destroyed = true; r.push(null); } + +{ + // Regression https://github.com/nodejs/node/issues/33130 + const response = new PassThrough(); + + class HelloWorld extends Duplex { + constructor(response) { + super({ + autoDestroy: false + }); + + this.response = response; + this.readMore = false; + + response.once('end', () => { + this.push(null); + }); + + response.on('readable', () => { + if (this.readMore) { + this._read(); + } + }); + } + + _read() { + const { response } = this; + + this.readMore = true; + + if (response.readableLength) { + this.readMore = false; + } + + let data; + while ((data = response.read()) !== null) { + this.push(data); + } + } + } + + const instance = new HelloWorld(response); + instance.setEncoding('utf8'); + instance.end(); + + (async () => { + await EE.once(instance, 'finish'); + + setImmediate(() => { + response.write('chunk 1'); + response.write('chunk 2'); + response.write('chunk 3'); + response.end(); + }); + + let res = ''; + for await (const data of instance) { + res += data; + } + + assert.strictEqual(res, 'chunk 1chunk 2chunk 3'); + })().then(common.mustCall()); +} + +{ + const p = new PassThrough(); + p.end(); + finished(p, common.mustNotCall()); +} + +{ + const p = new PassThrough(); + p.end(); + p.on('finish', common.mustCall(() => { + finished(p, common.mustNotCall()); + })); +} diff --git a/test/parallel/test-stream-readable-next-no-null.js b/test/parallel/test-stream-readable-next-no-null.js new file mode 100644 index 00000000000000..64ca40be11ed03 --- /dev/null +++ b/test/parallel/test-stream-readable-next-no-null.js @@ -0,0 +1,19 @@ +'use strict'; +const { mustNotCall, expectsError } = require('../common'); +const { Readable } = require('stream'); + +async function* generate() { + yield null; +} + +const stream = Readable.from(generate()); + +stream.on('error', expectsError({ + code: 'ERR_STREAM_NULL_VALUES', + name: 'TypeError', + message: 'May not write null values to stream' +})); + +stream.on('data', mustNotCall((chunk) => {})); + +stream.on('end', mustNotCall()); diff --git a/test/parallel/test-stream-writable-end-cb-uncaugth.js b/test/parallel/test-stream-writable-end-cb-uncaught.js similarity index 100% rename from test/parallel/test-stream-writable-end-cb-uncaugth.js rename to test/parallel/test-stream-writable-end-cb-uncaught.js diff --git a/test/parallel/test-vm-measure-memory-lazy.js b/test/parallel/test-vm-measure-memory-lazy.js new file mode 100644 index 00000000000000..513cfbc3672451 --- /dev/null +++ b/test/parallel/test-vm-measure-memory-lazy.js @@ -0,0 +1,37 @@ +// Flags: --expose-gc + +'use strict'; +const common = require('../common'); +const { + assertSummaryShape, + expectExperimentalWarning +} = require('../common/measure-memory'); +const vm = require('vm'); + +expectExperimentalWarning(); + +// Test lazy memory measurement - we will need to global.gc() +// or otherwise these may not resolve. +{ + vm.measureMemory() + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({}) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({ mode: 'summary' }) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({ mode: 'detailed' }) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} diff --git a/test/parallel/test-vm-measure-memory-multi-context.js b/test/parallel/test-vm-measure-memory-multi-context.js new file mode 100644 index 00000000000000..3a3065a8edb631 --- /dev/null +++ b/test/parallel/test-vm-measure-memory-multi-context.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const { + assertDetailedShape, + expectExperimentalWarning +} = require('../common/measure-memory'); +const vm = require('vm'); +const assert = require('assert'); + +expectExperimentalWarning(); +{ + const arr = []; + const count = 10; + for (let i = 0; i < count; ++i) { + const context = vm.createContext({ + test: new Array(100).fill('foo') + }); + arr.push(context); + } + // Check that one more context shows up in the result + vm.measureMemory({ mode: 'detailed', execution: 'eager' }) + .then(common.mustCall((result) => { + // We must hold on to the contexts here so that they + // don't get GC'ed until the measurement is complete + assert.strictEqual(arr.length, count); + assertDetailedShape(result, count); + })); +} diff --git a/test/parallel/test-vm-measure-memory.js b/test/parallel/test-vm-measure-memory.js index 7e620304e0a276..6b18db9be7a714 100644 --- a/test/parallel/test-vm-measure-memory.js +++ b/test/parallel/test-vm-measure-memory.js @@ -1,42 +1,25 @@ 'use strict'; const common = require('../common'); +const { + assertSummaryShape, + assertSingleDetailedShape, + expectExperimentalWarning +} = require('../common/measure-memory'); const assert = require('assert'); const vm = require('vm'); -common.expectWarning('ExperimentalWarning', - 'vm.measureMemory is an experimental feature. ' + - 'This feature could change at any time'); +expectExperimentalWarning(); -// The formats could change when V8 is updated, then the tests should be -// updated accordingly. -function assertSummaryShape(result) { - assert.strictEqual(typeof result, 'object'); - assert.strictEqual(typeof result.total, 'object'); - assert.strictEqual(typeof result.total.jsMemoryEstimate, 'number'); - assert(Array.isArray(result.total.jsMemoryRange)); - assert.strictEqual(typeof result.total.jsMemoryRange[0], 'number'); - assert.strictEqual(typeof result.total.jsMemoryRange[1], 'number'); -} - -function assertDetailedShape(result) { - // For now, the detailed shape is the same as the summary shape. This - // should change in future versions of V8. - return assertSummaryShape(result); -} - -// Test measuring memory of the current context +// Test eager memory measurement { - vm.measureMemory() - .then(assertSummaryShape); + vm.measureMemory({ execution: 'eager' }) + .then(common.mustCall(assertSummaryShape)); - vm.measureMemory({}) - .then(assertSummaryShape); + vm.measureMemory({ mode: 'detailed', execution: 'eager' }) + .then(common.mustCall(assertSingleDetailedShape)); - vm.measureMemory({ mode: 'summary' }) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'detailed' }) - .then(assertDetailedShape); + vm.measureMemory({ mode: 'summary', execution: 'eager' }) + .then(common.mustCall(assertSummaryShape)); assert.throws(() => vm.measureMemory(null), { code: 'ERR_INVALID_ARG_TYPE' @@ -47,24 +30,7 @@ function assertDetailedShape(result) { assert.throws(() => vm.measureMemory({ mode: 'random' }), { code: 'ERR_INVALID_ARG_VALUE' }); -} - -// Test measuring memory of the sandbox -{ - const context = vm.createContext(); - vm.measureMemory({ context }) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'summary', context },) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'detailed', context }) - .then(assertDetailedShape); - - assert.throws(() => vm.measureMemory({ mode: 'summary', context: null }), { - code: 'ERR_INVALID_ARG_TYPE' - }); - assert.throws(() => vm.measureMemory({ mode: 'summary', context: {} }), { - code: 'ERR_INVALID_ARG_TYPE' + assert.throws(() => vm.measureMemory({ execution: 'random' }), { + code: 'ERR_INVALID_ARG_VALUE' }); } diff --git a/test/parallel/test-vm-module-basic.js b/test/parallel/test-vm-module-basic.js index 155524f7e7a176..26751fd0b58e31 100644 --- a/test/parallel/test-vm-module-basic.js +++ b/test/parallel/test-vm-module-basic.js @@ -125,12 +125,22 @@ const util = require('util'); // Check to throws invalid exportNames { assert.throws(() => new SyntheticModule(undefined, () => {}, {}), { - message: 'The "exportNames" argument must be an Array of strings.' + - ' Received undefined', + message: 'The "exportNames" argument must be an ' + + 'Array of unique strings.' + + ' Received undefined', name: 'TypeError' }); } +// Check to throws duplicated exportNames +// https://github.com/nodejs/node/issues/32806 +{ + assert.throws(() => new SyntheticModule(['x', 'x'], () => {}, {}), { + message: 'The argument \'exportNames.x\' is duplicated. Received \'x\'', + name: 'TypeError', + }); +} + // Check to throws invalid evaluateCallback { assert.throws(() => new SyntheticModule([], undefined, {}), { diff --git a/test/parallel/test-vm-module-errors.js b/test/parallel/test-vm-module-errors.js index 5f36f9339fe41a..d14296b1e9ebde 100644 --- a/test/parallel/test-vm-module-errors.js +++ b/test/parallel/test-vm-module-errors.js @@ -209,6 +209,22 @@ async function checkInvalidOptionForEvaluate() { }); } +function checkInvalidCachedData() { + [true, false, 'foo', {}, Array, function() {}].forEach((invalidArg) => { + const message = 'The "options.cachedData" property must be an ' + + 'instance of Buffer, TypedArray, or DataView.' + + common.invalidArgTypeHelper(invalidArg); + assert.throws( + () => new SourceTextModule('import "foo";', { cachedData: invalidArg }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message, + } + ); + }); +} + const finished = common.mustCall(); (async function main() { @@ -217,5 +233,6 @@ const finished = common.mustCall(); await checkLinking(); await checkExecution(); await checkInvalidOptionForEvaluate(); + checkInvalidCachedData(); finished(); })(); diff --git a/test/parallel/test-worker-resource-limits.js b/test/parallel/test-worker-resource-limits.js index 9332a132694e78..0c168bbea1a488 100644 --- a/test/parallel/test-worker-resource-limits.js +++ b/test/parallel/test-worker-resource-limits.js @@ -12,6 +12,7 @@ const testResourceLimits = { maxOldGenerationSizeMb: 16, maxYoungGenerationSizeMb: 4, codeRangeSizeMb: 16, + stackSizeMb: 1, }; // Do not use isMainThread so that this test itself can be run inside a Worker. diff --git a/test/parallel/test-worker-stack-overflow-stack-size.js b/test/parallel/test-worker-stack-overflow-stack-size.js index f218554297d1a3..a079624847bcb7 100644 --- a/test/parallel/test-worker-stack-overflow-stack-size.js +++ b/test/parallel/test-worker-stack-overflow-stack-size.js @@ -8,7 +8,7 @@ const { Worker } = require('worker_threads'); // Verify that Workers don't care about --stack-size, as they have their own // fixed and known stack sizes. -async function runWorker() { +async function runWorker(options = {}) { const empiricalStackDepth = new Uint32Array(new SharedArrayBuffer(4)); const worker = new Worker(` const { workerData: { empiricalStackDepth } } = require('worker_threads'); @@ -18,26 +18,45 @@ async function runWorker() { } f();`, { eval: true, - workerData: { empiricalStackDepth } + workerData: { empiricalStackDepth }, + ...options }); const [ error ] = await once(worker, 'error'); - common.expectsError({ - constructor: RangeError, - message: 'Maximum call stack size exceeded' - })(error); + if (!options.skipErrorCheck) { + common.expectsError({ + constructor: RangeError, + message: 'Maximum call stack size exceeded' + })(error); + } return empiricalStackDepth[0]; } (async function() { - v8.setFlagsFromString('--stack-size=500'); - const w1stack = await runWorker(); - v8.setFlagsFromString('--stack-size=1000'); - const w2stack = await runWorker(); - // Make sure the two stack sizes are within 10 % of each other, i.e. not - // affected by the different `--stack-size` settings. - assert(Math.max(w1stack, w2stack) / Math.min(w1stack, w2stack) < 1.1, - `w1stack = ${w1stack}, w2stack ${w2stack} are too far apart`); + { + v8.setFlagsFromString('--stack-size=500'); + const w1stack = await runWorker(); + v8.setFlagsFromString('--stack-size=1000'); + const w2stack = await runWorker(); + // Make sure the two stack sizes are within 10 % of each other, i.e. not + // affected by the different `--stack-size` settings. + assert(Math.max(w1stack, w2stack) / Math.min(w1stack, w2stack) < 1.1, + `w1stack = ${w1stack}, w2stack = ${w2stack} are too far apart`); + } + + { + const w1stack = await runWorker({ resourceLimits: { stackSizeMb: 0.5 } }); + const w2stack = await runWorker({ resourceLimits: { stackSizeMb: 1.0 } }); + // Make sure the two stack sizes are at least 40 % apart from each other, + // i.e. affected by the different `stackSizeMb` settings. + assert(w2stack > w1stack * 1.4, + `w1stack = ${w1stack}, w2stack = ${w2stack} are too close`); + } + + // Test that various low stack sizes result in an 'error' event. + for (const stackSizeMb of [ 0.001, 0.01, 0.1, 0.2, 0.3, 0.5 ]) { + await runWorker({ resourceLimits: { stackSizeMb }, skipErrorCheck: true }); + } })().then(common.mustCall()); diff --git a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js index 46c1f6d1a5885c..c905c22d8afa78 100644 --- a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js +++ b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js @@ -2,6 +2,9 @@ 'use strict'; const common = require('../common'); +if (process.config.variables.asan) + common.skip('ASAN messes with memory measurements'); + const assert = require('assert'); const net = require('net'); diff --git a/test/parallel/test-process-title.js b/test/sequential/test-process-title.js similarity index 100% rename from test/parallel/test-process-title.js rename to test/sequential/test-process-title.js diff --git a/test/wasi/test-wasi-start-validation.js b/test/wasi/test-wasi-start-validation.js index a31c5847968491..617738442ee64a 100644 --- a/test/wasi/test-wasi-start-validation.js +++ b/test/wasi/test-wasi-start-validation.js @@ -8,85 +8,111 @@ const { WASI } = require('wasi'); const fixtures = require('../common/fixtures'); const bufferSource = fixtures.readSync('simple.wasm'); -{ - const wasi = new WASI(); - assert.throws( - () => { - wasi.start(); - }, - { code: 'ERR_INVALID_ARG_TYPE', message: /\bWebAssembly\.Instance\b/ } - ); -} - (async () => { - const wasi = new WASI({}); - const wasm = await WebAssembly.compile(bufferSource); - const instance = await WebAssembly.instantiate(wasm); + { + // Verify that a WebAssembly.Instance is passed in. + const wasi = new WASI(); - assert.throws( - () => { wasi.start(instance); }, - { code: 'ERR_INVALID_ARG_TYPE', message: /\bWebAssembly\.Memory\b/ } - ); -})(); + assert.throws( + () => { wasi.start(); }, + { code: 'ERR_INVALID_ARG_TYPE', message: /\bWebAssembly\.Instance\b/ } + ); + } -(async () => { - const wasi = new WASI(); - const wasm = await WebAssembly.compile(bufferSource); - const instance = await WebAssembly.instantiate(wasm); - const values = [undefined, null, 'foo', 42, true, false, () => {}]; - let cnt = 0; + { + // Verify that the passed instance has an exports objects. + const wasi = new WASI({}); + const wasm = await WebAssembly.compile(bufferSource); + const instance = await WebAssembly.instantiate(wasm); + + Object.defineProperty(instance, 'exports', { get() { return null; } }); + assert.throws( + () => { wasi.start(instance); }, + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"instance\.exports" property must be of type object/ + } + ); + } - // Mock instance.exports to trigger start() validation. - Object.defineProperty(instance, 'exports', { - get() { return values[cnt++]; } - }); + { + // Verify that a _start() export was passed. + const wasi = new WASI({}); + const wasm = await WebAssembly.compile(bufferSource); + const instance = await WebAssembly.instantiate(wasm); - values.forEach((val) => { + Object.defineProperty(instance, 'exports', { get() { return {}; } }); assert.throws( () => { wasi.start(instance); }, - { code: 'ERR_INVALID_ARG_TYPE', message: /\binstance\.exports\b/ } + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"instance\.exports\._start" property must be of type function/ + } ); - }); -})(); + } -(async () => { - const wasi = new WASI(); - const wasm = await WebAssembly.compile(bufferSource); - const instance = await WebAssembly.instantiate(wasm); + { + // Verify that an _initialize export was not passed. + const wasi = new WASI({}); + const wasm = await WebAssembly.compile(bufferSource); + const instance = await WebAssembly.instantiate(wasm); - // Mock instance.exports.memory to bypass start() validation. - Object.defineProperty(instance, 'exports', { - get() { - return { - memory: new WebAssembly.Memory({ initial: 1 }) - }; - } - }); + Object.defineProperty(instance, 'exports', { + get() { + return { + _start() {}, + _initialize() {} + }; + } + }); + assert.throws( + () => { wasi.start(instance); }, + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"instance\.exports\._initialize" property must be undefined/ + } + ); + } - wasi.start(instance); - assert.throws( - () => { wasi.start(instance); }, - { - code: 'ERR_WASI_ALREADY_STARTED', - message: /^WASI instance has already started$/ - } - ); -})(); + { + // Verify that a memory export was passed. + const wasi = new WASI({}); + const wasm = await WebAssembly.compile(bufferSource); + const instance = await WebAssembly.instantiate(wasm); -(async () => { - const wasi = new WASI(); - const wasm = await WebAssembly.compile(bufferSource); - const instance = await WebAssembly.instantiate(wasm); + Object.defineProperty(instance, 'exports', { + get() { return { _start() {} }; } + }); + assert.throws( + () => { wasi.start(instance); }, + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"instance\.exports\.memory" property .+ WebAssembly\.Memory/ + } + ); + } - // Mock instance.exports to bypass start() validation. - Object.defineProperty(instance, 'exports', { - get() { - return { - memory: new WebAssembly.Memory({ initial: 1 }), - __wasi_unstable_reactor_start: common.mustCall() - }; - } - }); + { + // Verify that start() can only be called once. + const wasi = new WASI({}); + const wasm = await WebAssembly.compile(bufferSource); + const instance = await WebAssembly.instantiate(wasm); - wasi.start(instance); -})(); + Object.defineProperty(instance, 'exports', { + get() { + return { + _start() {}, + memory: new WebAssembly.Memory({ initial: 1 }) + }; + } + }); + wasi.start(instance); + assert.throws( + () => { wasi.start(instance); }, + { + code: 'ERR_WASI_ALREADY_STARTED', + message: /^WASI instance has already started$/ + } + ); + } +})().then(common.mustCall()); diff --git a/tools/doc/checkLinks.js b/tools/doc/checkLinks.js index 60a3f65e5ea9f1..00697cc01cf01a 100644 --- a/tools/doc/checkLinks.js +++ b/tools/doc/checkLinks.js @@ -27,6 +27,7 @@ function findMarkdownFilesRecursively(dirPath) { if ( entry.isDirectory() && entry.name !== 'api' && + entry.name !== 'tmp' && entry.name !== 'fixtures' && entry.name !== 'changelogs' && entry.name !== 'deps' && diff --git a/tools/doc/type-parser.js b/tools/doc/type-parser.js index b244564d8f8ebf..6f98197a741653 100644 --- a/tools/doc/type-parser.js +++ b/tools/doc/type-parser.js @@ -15,10 +15,10 @@ const jsPrimitives = { const jsGlobalObjectsUrl = `${jsDocPrefix}Reference/Global_Objects/`; const jsGlobalTypes = [ - 'Array', 'ArrayBuffer', 'ArrayBufferView', 'DataView', 'Date', 'Error', + 'Array', 'ArrayBuffer', 'DataView', 'Date', 'Error', 'EvalError', 'Function', 'Map', 'Object', 'Promise', 'RangeError', 'ReferenceError', 'RegExp', 'Set', 'SharedArrayBuffer', 'SyntaxError', - 'TypeError', 'TypedArray', 'URIError', 'Uint8Array', 'WebAssembly.Instance', + 'TypeError', 'TypedArray', 'URIError', 'Uint8Array', ]; const customTypesMap = { @@ -26,11 +26,16 @@ const customTypesMap = { 'this': `${jsDocPrefix}Reference/Operators/this`, + 'ArrayBufferView': + 'https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView', + 'AsyncIterator': 'https://tc39.github.io/ecma262/#sec-asynciterator-interface', 'AsyncIterable': 'https://tc39.github.io/ecma262/#sec-asynciterable-interface', 'bigint': `${jsDocPrefix}Reference/Global_Objects/BigInt`, + 'WebAssembly.Instance': + `${jsDocPrefix}Reference/Global_Objects/WebAssembly/Instance`, 'Iterable': `${jsDocPrefix}Reference/Iteration_protocols#The_iterable_protocol`, diff --git a/tools/inspector_protocol/lib/Values_cpp.template b/tools/inspector_protocol/lib/Values_cpp.template index 764b4d37d9a7d5..be3149d50356f2 100644 --- a/tools/inspector_protocol/lib/Values_cpp.template +++ b/tools/inspector_protocol/lib/Values_cpp.template @@ -606,7 +606,7 @@ std::unique_ptr DictionaryValue::clone() const DCHECK(value != m_data.cend() && value->second); result->setValue(key, value->second->clone()); } - return std::move(result); + return result; } DictionaryValue::DictionaryValue() @@ -647,7 +647,7 @@ std::unique_ptr ListValue::clone() const std::unique_ptr result = ListValue::create(); for (const std::unique_ptr& value : m_data) result->pushValue(value->clone()); - return std::move(result); + return result; } ListValue::ListValue() diff --git a/tools/lint-md.js b/tools/lint-md.js index 35df2b11fcb936..a926298f025334 100644 --- a/tools/lint-md.js +++ b/tools/lint-md.js @@ -195,6 +195,8 @@ function trough() { } } +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + function commonjsRequire () { throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); } @@ -5894,7 +5896,7 @@ var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { var minimist = function (args, opts) { if (!opts) opts = {}; - + var flags = { bools : {}, strings : {}, unknownFn: null }; if (typeof opts['unknown'] === 'function') { @@ -5908,7 +5910,7 @@ var minimist = function (args, opts) { flags.bools[key] = true; }); } - + var aliases = {}; Object.keys(opts.alias || {}).forEach(function (key) { aliases[key] = [].concat(opts.alias[key]); @@ -5927,12 +5929,12 @@ var minimist = function (args, opts) { }); var defaults = opts['default'] || {}; - + var argv = { _ : [] }; Object.keys(flags.bools).forEach(function (key) { setArg(key, defaults[key] === undefined ? false : defaults[key]); }); - + var notFlags = []; if (args.indexOf('--') !== -1) { @@ -5954,7 +5956,7 @@ var minimist = function (args, opts) { ? Number(val) : val ; setKey(argv, key.split('.'), value); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), value); }); @@ -5987,7 +5989,7 @@ var minimist = function (args, opts) { o[key] = [ o[key], value ]; } } - + function aliasIsBoolean(key) { return aliases[key].some(function (x) { return flags.bools[x]; @@ -5996,7 +5998,7 @@ var minimist = function (args, opts) { for (var i = 0; i < args.length; i++) { var arg = args[i]; - + if (/^--.+=/.test(arg)) { // Using [\s\S] instead of . because js doesn't support the // 'dotall' regex modifier. See: @@ -6033,29 +6035,29 @@ var minimist = function (args, opts) { } else if (/^-[^-]+/.test(arg)) { var letters = arg.slice(1,-1).split(''); - + var broken = false; for (var j = 0; j < letters.length; j++) { var next = arg.slice(j+2); - + if (next === '-') { setArg(letters[j], next, arg); continue; } - + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { setArg(letters[j], next.split('=')[1], arg); broken = true; break; } - + if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { setArg(letters[j], next, arg); broken = true; break; } - + if (letters[j+1] && letters[j+1].match(/\W/)) { setArg(letters[j], arg.slice(j+2), arg); broken = true; @@ -6065,7 +6067,7 @@ var minimist = function (args, opts) { setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); } } - + var key = arg.slice(-1)[0]; if (!broken && key !== '-') { if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) @@ -6095,17 +6097,17 @@ var minimist = function (args, opts) { } } } - + Object.keys(defaults).forEach(function (key) { if (!hasKey(argv, key.split('.'))) { setKey(argv, key.split('.'), defaults[key]); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), defaults[key]); }); } }); - + if (opts['--']) { argv['--'] = new Array(); notFlags.forEach(function(key) { @@ -14436,155 +14438,155 @@ var escapeStringRegexp = function (str) { return str.replace(matchOperatorsRe, '\\$&'); }; -var colorName = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] +var colorName = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] }; var conversions = createCommonjsModule(function (module) { @@ -22580,7 +22582,7 @@ var textTable = function (rows_, opts) { var stringLength = opts.stringLength || function (s) { return String(s).length; } ; - + var dotsizes = reduce(rows_, function (acc, row) { forEach(row, function (c, ix) { var n = dotindex(c); @@ -22588,7 +22590,7 @@ var textTable = function (rows_, opts) { }); return acc; }, []); - + var rows = map$1(rows_, function (row) { return map$1(row, function (c_, ix) { var c = String(c_); @@ -22602,7 +22604,7 @@ var textTable = function (rows_, opts) { else return c; }); }); - + var sizes = reduce(rows, function (acc, row) { forEach(row, function (c, ix) { var n = stringLength(c); @@ -22610,7 +22612,7 @@ var textTable = function (rows_, opts) { }); return acc; }, []); - + return map$1(rows, function (row) { return map$1(row, function (c, ix) { var n = (sizes[ix] - stringLength(c)) || 0; @@ -22623,7 +22625,7 @@ var textTable = function (rows_, opts) { + c + Array(Math.floor(n / 2 + 1)).join(' ') ; } - + return c + s; }).join(hsep).replace(/\s+$/, ''); }).join('\n'); @@ -40953,7 +40955,7 @@ const dependencies$1 = { "markdown-extensions": "^1.1.1", remark: "^11.0.2", "remark-lint": "^6.0.5", - "remark-preset-lint-node": "^1.13.0", + "remark-preset-lint-node": "^1.15.0", "unified-args": "^7.1.0" }; const main = "dist/index.js"; @@ -40983,43 +40985,291 @@ var _package$3 = /*#__PURE__*/Object.freeze({ 'default': _package$2 }); -/* Map of allowed verbs. */ -var ALLOWED_VERBS = { - enable: true, - disable: true, - ignore: true -}; +var vfileLocation$1 = factory$7; + +function factory$7(file) { + var contents = indices$1(String(file)); + + return { + toPosition: offsetToPositionFactory$1(contents), + toOffset: positionToOffsetFactory$1(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$1(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$1(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$1(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$1 = convert$2; + +function convert$2(test) { + if (typeof test === 'string') { + return typeFactory$1(test) + } + + if (test === null || test === undefined) { + return ok$2 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$1 : matchesFactory$1)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$1(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$2(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$1(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$1(tests) { + var checks = convertAll$1(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$1(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$2() { + return true +} + +var unistUtilVisitParents$1 = visitParents$1; + + + +var CONTINUE$2 = true; +var SKIP$2 = 'skip'; +var EXIT$2 = false; + +visitParents$1.CONTINUE = CONTINUE$2; +visitParents$1.SKIP = SKIP$2; +visitParents$1.EXIT = EXIT$2; + +function visitParents$1(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$1(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$1(visitor(node, parents)); + + if (result[0] === EXIT$2) { + return result + } + } + + if (node.children && result[0] !== SKIP$2) { + subresult = toResult$1(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$2 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$2) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$1(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$2, value] + } + + return [value] +} + +var unistUtilVisit$1 = visit$1; + + + +var CONTINUE$3 = unistUtilVisitParents$1.CONTINUE; +var SKIP$3 = unistUtilVisitParents$1.SKIP; +var EXIT$3 = unistUtilVisitParents$1.EXIT; + +visit$1.CONTINUE = CONTINUE$3; +visit$1.SKIP = SKIP$3; +visit$1.EXIT = EXIT$3; + +function visit$1(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$1(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} var unifiedMessageControl = messageControl; function messageControl(options) { - var name = options && options.name; - var marker = options && options.marker; - var test = options && options.test; - var sources; - var known; - var reset; - var enable; - var disable; + var settings = options || {}; + var name = settings.name; + var marker = settings.marker; + var test = settings.test; + var sources = settings.source; + var known = settings.known; + var reset = settings.reset; + var enable = settings.enable || []; + var disable = settings.disable || []; if (!name) { throw new Error('Expected `name` in `options`, got `' + name + '`') } if (!marker) { - throw new Error('Expected `name` in `options`, got `' + name + '`') + throw new Error('Expected `marker` in `options`, got `' + marker + '`') } - if (!test) { - throw new Error('Expected `test` in `options`, got `' + test + '`') - } - - known = options.known; - reset = options.reset; - enable = options.enable || []; - disable = options.disable || []; - sources = options.source; - if (!sources) { sources = [name]; } else if (typeof sources === 'string') { @@ -41029,13 +41279,13 @@ function messageControl(options) { return transformer function transformer(tree, file) { - var toOffset = vfileLocation(file).toOffset; + var toOffset = vfileLocation$1(file).toOffset; var initial = !reset; var gaps = detectGaps(tree, file); var scope = {}; var globals = []; - unistUtilVisit(tree, test, visitor); + unistUtilVisit$1(tree, test, visitor); file.messages = file.messages.filter(filter); @@ -41050,7 +41300,7 @@ function messageControl(options) { var pos; var tail; - if (!mark || mark.name !== options.name) { + if (!mark || mark.name !== name) { return } @@ -41060,7 +41310,7 @@ function messageControl(options) { pos = mark.node.position && mark.node.position.start; tail = next && next.position && next.position.end; - if (!verb || !ALLOWED_VERBS[verb] === true) { + if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { file.fail( 'Unknown keyword `' + verb + @@ -41073,20 +41323,8 @@ function messageControl(options) { length = ruleIds.length; index = -1; - while (++index < length) { - ruleId = ruleIds[index]; - - if (isKnown(ruleId, verb, mark.node)) { - toggle(pos, verb === 'enable', ruleId); - - if (verb === 'ignore') { - toggle(tail, true, ruleId); - } - } - } - - /* Apply to all rules. */ - if (!length) { + // Apply to all rules. + if (length === 0) { if (verb === 'ignore') { toggle(pos, false); toggle(tail, true); @@ -41094,6 +41332,18 @@ function messageControl(options) { toggle(pos, verb === 'enable'); reset = verb !== 'enable'; } + } else { + while (++index < length) { + ruleId = ruleIds[index]; + + if (isKnown(ruleId, verb, mark.node)) { + toggle(pos, verb === 'enable', ruleId); + + if (verb === 'ignore') { + toggle(tail, true, ruleId); + } + } + } } } @@ -41103,13 +41353,13 @@ function messageControl(options) { var ranges = scope[ruleId]; var pos; - /* Keep messages from a different source. */ + // Keep messages from a different source. if (!message.source || sources.indexOf(message.source) === -1) { return true } - /* We only ignore messages if they‘re disabled, - * *not* when they’re not in the document. */ + // We only ignore messages if they‘re disabled, *not* when they’re not in + // the document. if (!message.line) { message.line = 1; } @@ -41118,7 +41368,7 @@ function messageControl(options) { message.column = 1; } - /* Check whether the warning is inside a gap. */ + // Check whether the warning is inside a gap. pos = toOffset(message); while (gapIndex--) { @@ -41127,22 +41377,26 @@ function messageControl(options) { } } - /* Check whether allowed by specific and global states. */ + // Check whether allowed by specific and global states. return check(message, ranges, ruleId) && check(message, globals) } - /* Helper to check (and possibly warn) if a ruleId is unknown. */ + // Helper to check (and possibly warn) if a `ruleId` is unknown. function isKnown(ruleId, verb, pos) { var result = known ? known.indexOf(ruleId) !== -1 : true; if (!result) { - file.warn('Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", pos); + file.message( + 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", + pos + ); } return result } - /* Get the latest state of a rule. When without `ruleId`, gets global state. */ + // Get the latest state of a rule. + // When without `ruleId`, gets global state. function getState(ruleId) { var ranges = ruleId ? scope[ruleId] : globals; @@ -41161,10 +41415,9 @@ function messageControl(options) { return disable.indexOf(ruleId) === -1 } - /* Handle a rule. */ + // Handle a rule. function toggle(pos, state, ruleId) { var markers = ruleId ? scope[ruleId] : globals; - var currentState; var previousState; if (!markers) { @@ -41173,13 +41426,12 @@ function messageControl(options) { } previousState = getState(ruleId); - currentState = state; - if (currentState !== previousState) { - markers.push({state: currentState, position: pos}); + if (state !== previousState) { + markers.push({state: state, position: pos}); } - /* Toggle all known rules. */ + // Toggle all known rules. if (!ruleId) { for (ruleId in scope) { toggle(pos, state, ruleId); @@ -41187,9 +41439,9 @@ function messageControl(options) { } } - /* Check all `ranges` for `message`. */ + // Check all `ranges` for `message`. function check(message, ranges, id) { - /* Check the state at the message's position. */ + // Check the state at the message’s position. var index = ranges && ranges.length; var length = -1; var range; @@ -41197,7 +41449,7 @@ function messageControl(options) { while (--index > length) { range = ranges[index]; - /* istanbul ignore if - generated marker. */ + /* istanbul ignore if - Generated marker. */ if (!range.position || !range.position.line || !range.position.column) { continue } @@ -41205,14 +41457,14 @@ function messageControl(options) { if ( range.position.line < message.line || (range.position.line === message.line && - range.position.column < message.column) + range.position.column <= message.column) ) { return range.state === true } } - /* The first marker ocurred after the first - * message, so we check the initial state. */ + // The first marker ocurred after the first message, so we check the + // initial state. if (!id) { return initial || reset } @@ -41222,26 +41474,26 @@ function messageControl(options) { } } -/* Detect gaps in `ast`. */ +// Detect gaps in `tree`. function detectGaps(tree, file) { var lastNode = tree.children[tree.children.length - 1]; var offset = 0; var isGap = false; var gaps = []; - /* Find all gaps. */ - unistUtilVisit(tree, one); + // Find all gaps. + unistUtilVisit$1(tree, one); - /* Get the end of the document. - * This detects if the last node was the last node. - * If not, there’s an extra gap between the last node - * and the end of the document. */ + // Get the end of the document. + // This detects if the last node was the last node. + // If not, there’s an extra gap between the last node and the end of the + // document. if ( lastNode && lastNode.position && lastNode.position.end && offset === lastNode.position.end.offset && - trim_1(file.toString().slice(offset)) !== '' + trim(file.toString().slice(offset)) !== '' ) { update(); @@ -41262,7 +41514,7 @@ function detectGaps(tree, file) { } } - /* Detect a new position. */ + // Detect a new position. function update(latest) { if (latest === null || latest === undefined) { isGap = true; @@ -41282,6 +41534,10 @@ function detectGaps(tree, file) { } } +function trim(value) { + return value.replace(/^\s*|\s*$/g, '') +} + var mdastCommentMarker = marker$1; var whiteSpaceExpression = /\s+/g; @@ -41367,7 +41623,7 @@ var test = [ ]; function messageControl$1(options) { - return unifiedMessageControl(immutable({marker: mdastCommentMarker, test: test}, options)) + return unifiedMessageControl(Object.assign({marker: mdastCommentMarker, test: test}, options)) } var remarkLint = lint; @@ -41383,6 +41639,583 @@ function lintMessageControl() { return remarkMessageControl({name: 'lint', source: 'remark-lint'}) } +var vfileLocation$2 = factory$8; + +function factory$8(file) { + var contents = indices$2(String(file)); + + return { + toPosition: offsetToPositionFactory$2(contents), + toOffset: positionToOffsetFactory$2(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$2(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$2(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$2(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$2 = convert$3; + +function convert$3(test) { + if (typeof test === 'string') { + return typeFactory$2(test) + } + + if (test === null || test === undefined) { + return ok$3 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$2 : matchesFactory$2)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$2(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$3(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$2(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$2(tests) { + var checks = convertAll$2(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$2(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$3() { + return true +} + +var unistUtilVisitParents$2 = visitParents$2; + + + +var CONTINUE$4 = true; +var SKIP$4 = 'skip'; +var EXIT$4 = false; + +visitParents$2.CONTINUE = CONTINUE$4; +visitParents$2.SKIP = SKIP$4; +visitParents$2.EXIT = EXIT$4; + +function visitParents$2(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$2(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$2(visitor(node, parents)); + + if (result[0] === EXIT$4) { + return result + } + } + + if (node.children && result[0] !== SKIP$4) { + subresult = toResult$2(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$4 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$4) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$2(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$4, value] + } + + return [value] +} + +var unistUtilVisit$2 = visit$2; + + + +var CONTINUE$5 = unistUtilVisitParents$2.CONTINUE; +var SKIP$5 = unistUtilVisitParents$2.SKIP; +var EXIT$5 = unistUtilVisitParents$2.EXIT; + +visit$2.CONTINUE = CONTINUE$5; +visit$2.SKIP = SKIP$5; +visit$2.EXIT = EXIT$5; + +function visit$2(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$2(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var unifiedMessageControl$1 = messageControl$2; + +function messageControl$2(options) { + var settings = options || {}; + var name = settings.name; + var marker = settings.marker; + var test = settings.test; + var sources = settings.source; + var known = settings.known; + var reset = settings.reset; + var enable = settings.enable || []; + var disable = settings.disable || []; + + if (!name) { + throw new Error('Expected `name` in `options`, got `' + name + '`') + } + + if (!marker) { + throw new Error('Expected `marker` in `options`, got `' + marker + '`') + } + + if (!sources) { + sources = [name]; + } else if (typeof sources === 'string') { + sources = [sources]; + } + + return transformer + + function transformer(tree, file) { + var toOffset = vfileLocation$2(file).toOffset; + var initial = !reset; + var gaps = detectGaps$1(tree, file); + var scope = {}; + var globals = []; + + unistUtilVisit$2(tree, test, visitor); + + file.messages = file.messages.filter(filter); + + function visitor(node, position, parent) { + var mark = marker(node); + var ruleIds; + var ruleId; + var verb; + var index; + var length; + var next; + var pos; + var tail; + + if (!mark || mark.name !== name) { + return + } + + ruleIds = mark.attributes.split(/\s/g); + verb = ruleIds.shift(); + next = parent.children[position + 1]; + pos = mark.node.position && mark.node.position.start; + tail = next && next.position && next.position.end; + + if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { + file.fail( + 'Unknown keyword `' + + verb + + '`: expected ' + + "`'enable'`, `'disable'`, or `'ignore'`", + mark.node + ); + } + + length = ruleIds.length; + index = -1; + + // Apply to all rules. + if (length === 0) { + if (verb === 'ignore') { + toggle(pos, false); + toggle(tail, true); + } else { + toggle(pos, verb === 'enable'); + reset = verb !== 'enable'; + } + } else { + while (++index < length) { + ruleId = ruleIds[index]; + + if (isKnown(ruleId, verb, mark.node)) { + toggle(pos, verb === 'enable', ruleId); + + if (verb === 'ignore') { + toggle(tail, true, ruleId); + } + } + } + } + } + + function filter(message) { + var gapIndex = gaps.length; + var ruleId = message.ruleId; + var ranges = scope[ruleId]; + var pos; + + // Keep messages from a different source. + if (!message.source || sources.indexOf(message.source) === -1) { + return true + } + + // We only ignore messages if they‘re disabled, *not* when they’re not in + // the document. + if (!message.line) { + message.line = 1; + } + + if (!message.column) { + message.column = 1; + } + + // Check whether the warning is inside a gap. + pos = toOffset(message); + + while (gapIndex--) { + if (gaps[gapIndex].start <= pos && gaps[gapIndex].end > pos) { + return false + } + } + + // Check whether allowed by specific and global states. + return check(message, ranges, ruleId) && check(message, globals) + } + + // Helper to check (and possibly warn) if a `ruleId` is unknown. + function isKnown(ruleId, verb, pos) { + var result = known ? known.indexOf(ruleId) !== -1 : true; + + if (!result) { + file.message( + 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", + pos + ); + } + + return result + } + + // Get the latest state of a rule. + // When without `ruleId`, gets global state. + function getState(ruleId) { + var ranges = ruleId ? scope[ruleId] : globals; + + if (ranges && ranges.length !== 0) { + return ranges[ranges.length - 1].state + } + + if (!ruleId) { + return !reset + } + + if (reset) { + return enable.indexOf(ruleId) !== -1 + } + + return disable.indexOf(ruleId) === -1 + } + + // Handle a rule. + function toggle(pos, state, ruleId) { + var markers = ruleId ? scope[ruleId] : globals; + var previousState; + + if (!markers) { + markers = []; + scope[ruleId] = markers; + } + + previousState = getState(ruleId); + + if (state !== previousState) { + markers.push({state: state, position: pos}); + } + + // Toggle all known rules. + if (!ruleId) { + for (ruleId in scope) { + toggle(pos, state, ruleId); + } + } + } + + // Check all `ranges` for `message`. + function check(message, ranges, id) { + // Check the state at the message’s position. + var index = ranges && ranges.length; + var length = -1; + var range; + + while (--index > length) { + range = ranges[index]; + + /* istanbul ignore if - Generated marker. */ + if (!range.position || !range.position.line || !range.position.column) { + continue + } + + if ( + range.position.line < message.line || + (range.position.line === message.line && + range.position.column <= message.column) + ) { + return range.state === true + } + } + + // The first marker ocurred after the first message, so we check the + // initial state. + if (!id) { + return initial || reset + } + + return reset ? enable.indexOf(id) !== -1 : disable.indexOf(id) === -1 + } + } +} + +// Detect gaps in `tree`. +function detectGaps$1(tree, file) { + var lastNode = tree.children[tree.children.length - 1]; + var offset = 0; + var isGap = false; + var gaps = []; + + // Find all gaps. + unistUtilVisit$2(tree, one); + + // Get the end of the document. + // This detects if the last node was the last node. + // If not, there’s an extra gap between the last node and the end of the + // document. + if ( + lastNode && + lastNode.position && + lastNode.position.end && + offset === lastNode.position.end.offset && + trim$1(file.toString().slice(offset)) !== '' + ) { + update(); + + update( + tree && tree.position && tree.position.end && tree.position.end.offset - 1 + ); + } + + return gaps + + function one(node) { + var pos = node.position; + + update(pos && pos.start && pos.start.offset); + + if (!node.children) { + update(pos && pos.end && pos.end.offset); + } + } + + // Detect a new position. + function update(latest) { + if (latest === null || latest === undefined) { + isGap = true; + return + } + + if (offset >= latest) { + return + } + + if (isGap) { + gaps.push({start: offset, end: latest}); + isGap = false; + } + + offset = latest; + } +} + +function trim$1(value) { + return value.replace(/^\s*|\s*$/g, '') +} + +var remarkMessageControl$1 = messageControl$3; + +var test$1 = [ + 'html', // Comments are `html` nodes in mdast. + 'comment' // In MDX, comments have their own node. +]; + +function messageControl$3(options) { + return unifiedMessageControl$1(Object.assign({marker: mdastCommentMarker, test: test$1}, options)) +} + +var remarkLint$1 = lint$1; + +// `remark-lint`. +// This adds support for ignoring stuff from messages (``). +// All rules are in their own packages and presets. +function lint$1() { + this.use(lintMessageControl$1); +} + +function lintMessageControl$1() { + return remarkMessageControl$1({name: 'lint', source: 'remark-lint'}) +} + /** * An Array.prototype.slice.call(arguments) alternative * @@ -41822,9 +42655,9 @@ function promise(value) { return value && 'function' == typeof value.then; } -var unifiedLintRule = factory$7; +var unifiedLintRule = factory$9; -function factory$7(id, rule) { +function factory$9(id, rule) { var parts = id.split(':'); var source = parts[0]; var ruleId = parts[1]; @@ -41862,7 +42695,7 @@ function factory$7(id, rule) { if (err && messages.indexOf(err) === -1) { try { file.fail(err); - } catch (error) {} + } catch (_) {} } while (index < messages.length) { @@ -41921,7 +42754,7 @@ function coerce(name, value) { if (level < 0 || level > 2) { throw new Error( - 'Invalid severity `' + + 'Incorrect severity `' + level + '` for `' + name + @@ -41946,490 +42779,700 @@ function finalNewline(tree, file) { } } -const addendum = "addenda"; -const aircraft = "aircraft"; -const alga = "algae"; -const alumna = "alumnae"; -const alumnus = "alumni"; -const amoeba = "amoebae"; -const analysis = "analyses"; -const antenna = "antennae"; -const antithesis = "antitheses"; -const apex = "apices"; -const appendix = "appendices"; -const automaton = "automata"; -const axis = "axes"; -const bacillus = "bacilli"; -const bacterium = "bacteria"; -const barracks = "barracks"; -const basis = "bases"; -const beau = "beaux"; -const bison = "bison"; -const buffalo = "buffalo"; -const bureau = "bureaus"; -const cactus = "cacti"; -const calf = "calves"; -const carp = "carp"; -const census = "censuses"; -const chassis = "chassis"; -const cherub = "cherubim"; -const child = "children"; -const cod = "cod"; -const codex = "codices"; -const concerto = "concerti"; -const corpus = "corpora"; -const crisis = "crises"; -const criterion = "criteria"; -const curriculum = "curricula"; -const datum = "data"; -const deer = "deer"; -const diagnosis = "diagnoses"; -const die$1 = "dice"; -const dwarf = "dwarfs"; -const echo = "echoes"; -const elf = "elves"; -const elk = "elk"; -const ellipsis = "ellipses"; -const embargo = "embargoes"; -const emphasis$3 = "emphases"; -const erratum = "errata"; -const fez = "fezes"; -const firmware = "firmware"; -const fish = "fish"; -const focus = "foci"; -const foot = "feet"; -const formula = "formulae"; -const fungus = "fungi"; -const gallows = "gallows"; -const genus = "genera"; -const goose = "geese"; -const graffito = "graffiti"; -const grouse = "grouse"; -const half$1 = "halves"; -const hero = "heroes"; -const hoof = "hooves"; -const hovercraft = "hovercraft"; -const hypothesis = "hypotheses"; -const index$5 = "indices"; -const kakapo = "kakapo"; -const knife = "knives"; -const larva = "larvae"; -const leaf = "leaves"; -const libretto = "libretti"; -const life = "lives"; -const loaf = "loaves"; -const locus = "loci"; -const louse = "lice"; -const man = "men"; -const matrix = "matrices"; -const means = "means"; -const medium = "media"; -const memorandum = "memoranda"; -const millennium = "millennia"; -const minutia = "minutiae"; -const moose = "moose"; -const mouse = "mice"; -const nebula = "nebulae"; -const nemesis = "nemeses"; -const neurosis = "neuroses"; -const news = "news"; -const nucleus = "nuclei"; -const oasis = "oases"; -const offspring = "offspring"; -const opus = "opera"; -const ovum = "ova"; -const ox = "oxen"; -const paralysis = "paralyses"; -const parenthesis = "parentheses"; -const person = "people"; -const phenomenon = "phenomena"; -const phylum = "phyla"; -const pike = "pike"; -const polyhedron = "polyhedra"; -const potato = "potatoes"; -const prognosis = "prognoses"; -const quiz = "quizzes"; -const radius = "radii"; -const referendum = "referenda"; -const salmon = "salmon"; -const scarf = "scarves"; -const self = "selves"; -const series = "series"; -const sheep = "sheep"; -const shelf = "shelves"; -const shrimp = "shrimp"; -const spacecraft = "spacecraft"; -const species = "species"; -const spectrum = "spectra"; -const squid = "squid"; -const stimulus = "stimuli"; -const stratum = "strata"; -const swine = "swine"; -const syllabus = "syllabi"; -const symposium = "symposia"; -const synopsis = "synopses"; -const synthesis = "syntheses"; -const tableau = "tableaus"; -const that = "those"; -const thesis = "theses"; -const thief = "thieves"; -const tomato = "tomatoes"; -const tooth = "teeth"; -const trout = "trout"; -const tuna = "tuna"; -const vertebra = "vertebrae"; -const vertex = "vertices"; -const veto = "vetoes"; -const vita = "vitae"; -const vortex = "vortices"; -const watercraft = "watercraft"; -const wharf = "wharves"; -const wife = "wives"; -const wolf = "wolves"; -const woman = "women"; -var irregularPlurals = { - addendum: addendum, - aircraft: aircraft, - alga: alga, - alumna: alumna, - alumnus: alumnus, - amoeba: amoeba, - analysis: analysis, - antenna: antenna, - antithesis: antithesis, - apex: apex, - appendix: appendix, - automaton: automaton, - axis: axis, - bacillus: bacillus, - bacterium: bacterium, - barracks: barracks, - basis: basis, - beau: beau, - bison: bison, - buffalo: buffalo, - bureau: bureau, - cactus: cactus, - calf: calf, - carp: carp, - census: census, - chassis: chassis, - cherub: cherub, - child: child, - "château": "châteaus", - cod: cod, - codex: codex, - concerto: concerto, - corpus: corpus, - crisis: crisis, - criterion: criterion, - curriculum: curriculum, - datum: datum, - deer: deer, - diagnosis: diagnosis, - die: die$1, - dwarf: dwarf, - echo: echo, - elf: elf, - elk: elk, - ellipsis: ellipsis, - embargo: embargo, - emphasis: emphasis$3, - erratum: erratum, - "faux pas": "faux pas", - fez: fez, - firmware: firmware, - fish: fish, - focus: focus, - foot: foot, - formula: formula, - fungus: fungus, - gallows: gallows, - genus: genus, - goose: goose, - graffito: graffito, - grouse: grouse, - half: half$1, - hero: hero, - hoof: hoof, - hovercraft: hovercraft, - hypothesis: hypothesis, - index: index$5, - kakapo: kakapo, - knife: knife, - larva: larva, - leaf: leaf, - libretto: libretto, - life: life, - loaf: loaf, - locus: locus, - louse: louse, - man: man, - matrix: matrix, - means: means, - medium: medium, - memorandum: memorandum, - millennium: millennium, - minutia: minutia, - moose: moose, - mouse: mouse, - nebula: nebula, - nemesis: nemesis, - neurosis: neurosis, - news: news, - nucleus: nucleus, - oasis: oasis, - offspring: offspring, - opus: opus, - ovum: ovum, - ox: ox, - paralysis: paralysis, - parenthesis: parenthesis, - person: person, - phenomenon: phenomenon, - phylum: phylum, - pike: pike, - polyhedron: polyhedron, - potato: potato, - prognosis: prognosis, - quiz: quiz, - radius: radius, - referendum: referendum, - salmon: salmon, - scarf: scarf, - self: self, - series: series, - sheep: sheep, - shelf: shelf, - shrimp: shrimp, - spacecraft: spacecraft, - species: species, - spectrum: spectrum, - squid: squid, - stimulus: stimulus, - stratum: stratum, - swine: swine, - syllabus: syllabus, - symposium: symposium, - synopsis: synopsis, - synthesis: synthesis, - tableau: tableau, - that: that, - thesis: thesis, - thief: thief, - "this": "these", - tomato: tomato, - tooth: tooth, - trout: trout, - tuna: tuna, - vertebra: vertebra, - vertex: vertex, - veto: veto, - vita: vita, - vortex: vortex, - watercraft: watercraft, - wharf: wharf, - wife: wife, - wolf: wolf, - woman: woman -}; - -var irregularPlurals$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - addendum: addendum, - aircraft: aircraft, - alga: alga, - alumna: alumna, - alumnus: alumnus, - amoeba: amoeba, - analysis: analysis, - antenna: antenna, - antithesis: antithesis, - apex: apex, - appendix: appendix, - automaton: automaton, - axis: axis, - bacillus: bacillus, - bacterium: bacterium, - barracks: barracks, - basis: basis, - beau: beau, - bison: bison, - buffalo: buffalo, - bureau: bureau, - cactus: cactus, - calf: calf, - carp: carp, - census: census, - chassis: chassis, - cherub: cherub, - child: child, - cod: cod, - codex: codex, - concerto: concerto, - corpus: corpus, - crisis: crisis, - criterion: criterion, - curriculum: curriculum, - datum: datum, - deer: deer, - diagnosis: diagnosis, - die: die$1, - dwarf: dwarf, - echo: echo, - elf: elf, - elk: elk, - ellipsis: ellipsis, - embargo: embargo, - emphasis: emphasis$3, - erratum: erratum, - fez: fez, - firmware: firmware, - fish: fish, - focus: focus, - foot: foot, - formula: formula, - fungus: fungus, - gallows: gallows, - genus: genus, - goose: goose, - graffito: graffito, - grouse: grouse, - half: half$1, - hero: hero, - hoof: hoof, - hovercraft: hovercraft, - hypothesis: hypothesis, - index: index$5, - kakapo: kakapo, - knife: knife, - larva: larva, - leaf: leaf, - libretto: libretto, - life: life, - loaf: loaf, - locus: locus, - louse: louse, - man: man, - matrix: matrix, - means: means, - medium: medium, - memorandum: memorandum, - millennium: millennium, - minutia: minutia, - moose: moose, - mouse: mouse, - nebula: nebula, - nemesis: nemesis, - neurosis: neurosis, - news: news, - nucleus: nucleus, - oasis: oasis, - offspring: offspring, - opus: opus, - ovum: ovum, - ox: ox, - paralysis: paralysis, - parenthesis: parenthesis, - person: person, - phenomenon: phenomenon, - phylum: phylum, - pike: pike, - polyhedron: polyhedron, - potato: potato, - prognosis: prognosis, - quiz: quiz, - radius: radius, - referendum: referendum, - salmon: salmon, - scarf: scarf, - self: self, - series: series, - sheep: sheep, - shelf: shelf, - shrimp: shrimp, - spacecraft: spacecraft, - species: species, - spectrum: spectrum, - squid: squid, - stimulus: stimulus, - stratum: stratum, - swine: swine, - syllabus: syllabus, - symposium: symposium, - synopsis: synopsis, - synthesis: synthesis, - tableau: tableau, - that: that, - thesis: thesis, - thief: thief, - tomato: tomato, - tooth: tooth, - trout: trout, - tuna: tuna, - vertebra: vertebra, - vertex: vertex, - veto: veto, - vita: vita, - vortex: vortex, - watercraft: watercraft, - wharf: wharf, - wife: wife, - wolf: wolf, - woman: woman, - 'default': irregularPlurals -}); +var pluralize = createCommonjsModule(function (module, exports) { +/* global define */ -var irregularPlurals$2 = getCjsExportFromNamespace(irregularPlurals$1); +(function (root, pluralize) { + /* istanbul ignore else */ + if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { + // Node. + module.exports = pluralize(); + } else { + // Browser global. + root.pluralize = pluralize(); + } +})(commonjsGlobal, function () { + // Rule storage - pluralize and singularize need to be run sequentially, + // while other rules can be optimized using an object for instant lookups. + var pluralRules = []; + var singularRules = []; + var uncountables = {}; + var irregularPlurals = {}; + var irregularSingles = {}; -var irregularPlurals_1 = createCommonjsModule(function (module) { + /** + * Sanitize a pluralization rule to a usable regular expression. + * + * @param {(RegExp|string)} rule + * @return {RegExp} + */ + function sanitizeRule (rule) { + if (typeof rule === 'string') { + return new RegExp('^' + rule + '$', 'i'); + } + return rule; + } -const map = new Map(); -// TODO: Use Object.entries when targeting Node.js 8 -for (const key of Object.keys(irregularPlurals$2)) { - map.set(key, irregularPlurals$2[key]); -} + /** + * Pass in a word token to produce a function that can replicate the case on + * another word. + * + * @param {string} word + * @param {string} token + * @return {Function} + */ + function restoreCase (word, token) { + // Tokens are an exact match. + if (word === token) return token; -// Ensure nobody can modify each others Map -Object.defineProperty(module, 'exports', { - get() { - return map; - } -}); -}); + // Lower cased words. E.g. "hello". + if (word === word.toLowerCase()) return token.toLowerCase(); -var plur = (word, plural, count) => { - if (typeof plural === 'number') { - count = plural; - } + // Upper cased words. E.g. "WHISKY". + if (word === word.toUpperCase()) return token.toUpperCase(); - if (irregularPlurals_1.has(word.toLowerCase())) { - plural = irregularPlurals_1.get(word.toLowerCase()); + // Title cased words. E.g. "Title". + if (word[0] === word[0].toUpperCase()) { + return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); + } - const firstLetter = word.charAt(0); - const isFirstLetterUpperCase = firstLetter === firstLetter.toUpperCase(); - if (isFirstLetterUpperCase) { - plural = firstLetter.toUpperCase() + plural.slice(1); - } + // Lower cased words. E.g. "test". + return token.toLowerCase(); + } - const isWholeWordUpperCase = word === word.toUpperCase(); - if (isWholeWordUpperCase) { - plural = plural.toUpperCase(); - } - } else if (typeof plural !== 'string') { - plural = (word.replace(/(?:s|x|z|ch|sh)$/i, '$&e').replace(/([^aeiou])y$/i, '$1ie') + 's') - .replace(/i?e?s$/i, match => { - const isTailLowerCase = word.slice(-1) === word.slice(-1).toLowerCase(); - return isTailLowerCase ? match.toLowerCase() : match.toUpperCase(); - }); - } + /** + * Interpolate a regexp string. + * + * @param {string} str + * @param {Array} args + * @return {string} + */ + function interpolate (str, args) { + return str.replace(/\$(\d{1,2})/g, function (match, index) { + return args[index] || ''; + }); + } - return Math.abs(count) === 1 ? word : plural; -}; + /** + * Replace a word using a rule. + * + * @param {string} word + * @param {Array} rule + * @return {string} + */ + function replace (word, rule) { + return word.replace(rule[0], function (match, index) { + var result = interpolate(rule[1], arguments); + + if (match === '') { + return restoreCase(word[index - 1], result); + } + + return restoreCase(match, result); + }); + } + + /** + * Sanitize a word by passing in the word and sanitization rules. + * + * @param {string} token + * @param {string} word + * @param {Array} rules + * @return {string} + */ + function sanitizeWord (token, word, rules) { + // Empty string or doesn't need fixing. + if (!token.length || uncountables.hasOwnProperty(token)) { + return word; + } + + var len = rules.length; + + // Iterate over the sanitization rules and use the first one to match. + while (len--) { + var rule = rules[len]; + + if (rule[0].test(word)) return replace(word, rule); + } + + return word; + } + + /** + * Replace a word with the updated word. + * + * @param {Object} replaceMap + * @param {Object} keepMap + * @param {Array} rules + * @return {Function} + */ + function replaceWord (replaceMap, keepMap, rules) { + return function (word) { + // Get the correct token and case restoration functions. + var token = word.toLowerCase(); + + // Check against the keep object map. + if (keepMap.hasOwnProperty(token)) { + return restoreCase(word, token); + } + + // Check against the replacement map for a direct word replacement. + if (replaceMap.hasOwnProperty(token)) { + return restoreCase(word, replaceMap[token]); + } + + // Run all the rules against the word. + return sanitizeWord(token, word, rules); + }; + } + + /** + * Check if a word is part of the map. + */ + function checkWord (replaceMap, keepMap, rules, bool) { + return function (word) { + var token = word.toLowerCase(); + + if (keepMap.hasOwnProperty(token)) return true; + if (replaceMap.hasOwnProperty(token)) return false; + + return sanitizeWord(token, token, rules) === token; + }; + } + + /** + * Pluralize or singularize a word based on the passed in count. + * + * @param {string} word The word to pluralize + * @param {number} count How many of the word exist + * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) + * @return {string} + */ + function pluralize (word, count, inclusive) { + var pluralized = count === 1 + ? pluralize.singular(word) : pluralize.plural(word); + + return (inclusive ? count + ' ' : '') + pluralized; + } + + /** + * Pluralize a word. + * + * @type {Function} + */ + pluralize.plural = replaceWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Check if a word is plural. + * + * @type {Function} + */ + pluralize.isPlural = checkWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Singularize a word. + * + * @type {Function} + */ + pluralize.singular = replaceWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Check if a word is singular. + * + * @type {Function} + */ + pluralize.isSingular = checkWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Add a pluralization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addPluralRule = function (rule, replacement) { + pluralRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add a singularization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addSingularRule = function (rule, replacement) { + singularRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add an uncountable word rule. + * + * @param {(string|RegExp)} word + */ + pluralize.addUncountableRule = function (word) { + if (typeof word === 'string') { + uncountables[word.toLowerCase()] = true; + return; + } + + // Set singular and plural references for the word. + pluralize.addPluralRule(word, '$0'); + pluralize.addSingularRule(word, '$0'); + }; + + /** + * Add an irregular word definition. + * + * @param {string} single + * @param {string} plural + */ + pluralize.addIrregularRule = function (single, plural) { + plural = plural.toLowerCase(); + single = single.toLowerCase(); + + irregularSingles[single] = plural; + irregularPlurals[plural] = single; + }; + + /** + * Irregular rules. + */ + [ + // Pronouns. + ['I', 'we'], + ['me', 'us'], + ['he', 'they'], + ['she', 'they'], + ['them', 'them'], + ['myself', 'ourselves'], + ['yourself', 'yourselves'], + ['itself', 'themselves'], + ['herself', 'themselves'], + ['himself', 'themselves'], + ['themself', 'themselves'], + ['is', 'are'], + ['was', 'were'], + ['has', 'have'], + ['this', 'these'], + ['that', 'those'], + // Words ending in with a consonant and `o`. + ['echo', 'echoes'], + ['dingo', 'dingoes'], + ['volcano', 'volcanoes'], + ['tornado', 'tornadoes'], + ['torpedo', 'torpedoes'], + // Ends with `us`. + ['genus', 'genera'], + ['viscus', 'viscera'], + // Ends with `ma`. + ['stigma', 'stigmata'], + ['stoma', 'stomata'], + ['dogma', 'dogmata'], + ['lemma', 'lemmata'], + ['schema', 'schemata'], + ['anathema', 'anathemata'], + // Other irregular rules. + ['ox', 'oxen'], + ['axe', 'axes'], + ['die', 'dice'], + ['yes', 'yeses'], + ['foot', 'feet'], + ['eave', 'eaves'], + ['goose', 'geese'], + ['tooth', 'teeth'], + ['quiz', 'quizzes'], + ['human', 'humans'], + ['proof', 'proofs'], + ['carve', 'carves'], + ['valve', 'valves'], + ['looey', 'looies'], + ['thief', 'thieves'], + ['groove', 'grooves'], + ['pickaxe', 'pickaxes'], + ['passerby', 'passersby'] + ].forEach(function (rule) { + return pluralize.addIrregularRule(rule[0], rule[1]); + }); + + /** + * Pluralization rules. + */ + [ + [/s?$/i, 's'], + [/[^\u0000-\u007F]$/i, '$0'], + [/([^aeiou]ese)$/i, '$1'], + [/(ax|test)is$/i, '$1es'], + [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], + [/(e[mn]u)s?$/i, '$1s'], + [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], + [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], + [/(seraph|cherub)(?:im)?$/i, '$1im'], + [/(her|at|gr)o$/i, '$1oes'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], + [/sis$/i, 'ses'], + [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], + [/([^aeiouy]|qu)y$/i, '$1ies'], + [/([^ch][ieo][ln])ey$/i, '$1ies'], + [/(x|ch|ss|sh|zz)$/i, '$1es'], + [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], + [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], + [/(pe)(?:rson|ople)$/i, '$1ople'], + [/(child)(?:ren)?$/i, '$1ren'], + [/eaux$/i, '$0'], + [/m[ae]n$/i, 'men'], + ['thou', 'you'] + ].forEach(function (rule) { + return pluralize.addPluralRule(rule[0], rule[1]); + }); + + /** + * Singularization rules. + */ + [ + [/s$/i, ''], + [/(ss)$/i, '$1'], + [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], + [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], + [/ies$/i, 'y'], + [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], + [/\b(mon|smil)ies$/i, '$1ey'], + [/\b((?:tit)?m|l)ice$/i, '$1ouse'], + [/(seraph|cherub)im$/i, '$1'], + [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], + [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], + [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], + [/(test)(?:is|es)$/i, '$1is'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], + [/(alumn|alg|vertebr)ae$/i, '$1a'], + [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], + [/(matr|append)ices$/i, '$1ix'], + [/(pe)(rson|ople)$/i, '$1rson'], + [/(child)ren$/i, '$1'], + [/(eau)x?$/i, '$1'], + [/men$/i, 'man'] + ].forEach(function (rule) { + return pluralize.addSingularRule(rule[0], rule[1]); + }); + + /** + * Uncountable rules. + */ + [ + // Singular words with no plurals. + 'adulthood', + 'advice', + 'agenda', + 'aid', + 'aircraft', + 'alcohol', + 'ammo', + 'analytics', + 'anime', + 'athletics', + 'audio', + 'bison', + 'blood', + 'bream', + 'buffalo', + 'butter', + 'carp', + 'cash', + 'chassis', + 'chess', + 'clothing', + 'cod', + 'commerce', + 'cooperation', + 'corps', + 'debris', + 'diabetes', + 'digestion', + 'elk', + 'energy', + 'equipment', + 'excretion', + 'expertise', + 'firmware', + 'flounder', + 'fun', + 'gallows', + 'garbage', + 'graffiti', + 'hardware', + 'headquarters', + 'health', + 'herpes', + 'highjinks', + 'homework', + 'housework', + 'information', + 'jeans', + 'justice', + 'kudos', + 'labour', + 'literature', + 'machinery', + 'mackerel', + 'mail', + 'media', + 'mews', + 'moose', + 'music', + 'mud', + 'manga', + 'news', + 'only', + 'personnel', + 'pike', + 'plankton', + 'pliers', + 'police', + 'pollution', + 'premises', + 'rain', + 'research', + 'rice', + 'salmon', + 'scissors', + 'series', + 'sewage', + 'shambles', + 'shrimp', + 'software', + 'species', + 'staff', + 'swine', + 'tennis', + 'traffic', + 'transportation', + 'trout', + 'tuna', + 'wealth', + 'welfare', + 'whiting', + 'wildebeest', + 'wildlife', + 'you', + /pok[eé]mon$/i, + // Regexes. + /[^aeiou]ese$/i, // "chinese", "japanese" + /deer$/i, // "deer", "reindeer" + /fish$/i, // "fish", "blowfish", "angelfish" + /measles$/i, + /o[iu]s$/i, // "carnivorous" + /pox$/i, // "chickpox", "smallpox" + /sheep$/i + ].forEach(pluralize.addUncountableRule); + + return pluralize; +}); +}); + +var convert_1$3 = convert$4; + +function convert$4(test) { + if (typeof test === 'string') { + return typeFactory$3(test) + } + + if (test === null || test === undefined) { + return ok$4 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$3 : matchesFactory$3)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$3(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$4(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$3(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$3(tests) { + var checks = convertAll$3(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$3(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$4() { + return true +} + +var unistUtilVisitParents$3 = visitParents$3; + + + +var CONTINUE$6 = true; +var SKIP$6 = 'skip'; +var EXIT$6 = false; + +visitParents$3.CONTINUE = CONTINUE$6; +visitParents$3.SKIP = SKIP$6; +visitParents$3.EXIT = EXIT$6; + +function visitParents$3(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$3(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$3(visitor(node, parents)); + + if (result[0] === EXIT$6) { + return result + } + } + + if (node.children && result[0] !== SKIP$6) { + subresult = toResult$3(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$6 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$6) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$3(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$1 = factory$8('start'); -var end = factory$8('end'); + if (typeof value === 'number') { + return [CONTINUE$6, value] + } + + return [value] +} + +var unistUtilVisit$3 = visit$3; + + + +var CONTINUE$7 = unistUtilVisitParents$3.CONTINUE; +var SKIP$7 = unistUtilVisitParents$3.SKIP; +var EXIT$7 = unistUtilVisitParents$3.EXIT; + +visit$3.CONTINUE = CONTINUE$7; +visit$3.SKIP = SKIP$7; +visit$3.EXIT = EXIT$7; + +function visit$3(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$3(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var start$1 = factory$a('start'); +var end = factory$a('end'); var unistUtilPosition = position$1; @@ -42440,7 +43483,7 @@ function position$1(node) { return {start: start$1(node), end: end(node)} } -function factory$8(type) { +function factory$a(type) { point.displayName = type; return point @@ -42480,7 +43523,7 @@ var start$2 = unistUtilPosition.start; function listItemBulletIndent(tree, file) { var contents = String(file); - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$3(tree, 'list', visitor); function visitor(node) { node.children.forEach(visitItems); @@ -42501,7 +43544,7 @@ function listItemBulletIndent(tree, file) { 'Incorrect indentation before bullet: remove ' + indent + ' ' + - plur('space', indent); + pluralize('space', indent); file.message(reason, { line: final.line, @@ -42512,26 +43555,216 @@ function listItemBulletIndent(tree, file) { } } +var convert_1$4 = convert$5; + +function convert$5(test) { + if (typeof test === 'string') { + return typeFactory$4(test) + } + + if (test === null || test === undefined) { + return ok$5 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$4 : matchesFactory$4)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$4(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$5(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$4(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$4(tests) { + var checks = convertAll$4(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$4(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$5() { + return true +} + +var unistUtilVisitParents$4 = visitParents$4; + + + +var CONTINUE$8 = true; +var SKIP$8 = 'skip'; +var EXIT$8 = false; + +visitParents$4.CONTINUE = CONTINUE$8; +visitParents$4.SKIP = SKIP$8; +visitParents$4.EXIT = EXIT$8; + +function visitParents$4(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$4(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$4(visitor(node, parents)); + + if (result[0] === EXIT$8) { + return result + } + } + + if (node.children && result[0] !== SKIP$8) { + subresult = toResult$4(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$8 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$8) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$4(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$8, value] + } + + return [value] +} + +var unistUtilVisit$4 = visit$4; + + + +var CONTINUE$9 = unistUtilVisitParents$4.CONTINUE; +var SKIP$9 = unistUtilVisitParents$4.SKIP; +var EXIT$9 = unistUtilVisitParents$4.EXIT; + +visit$4.CONTINUE = CONTINUE$9; +visit$4.SKIP = SKIP$9; +visit$4.EXIT = EXIT$9; + +function visit$4(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$4(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + var remarkLintListItemIndent = unifiedLintRule('remark-lint:list-item-indent', listItemIndent); var start$3 = unistUtilPosition.start; var styles = {'tab-size': true, mixed: true, space: true}; -function listItemIndent(tree, file, pref) { +function listItemIndent(tree, file, option) { var contents = String(file); + var preferred = typeof option === 'string' ? option : 'tab-size'; - pref = typeof pref === 'string' ? pref : 'tab-size'; - - if (styles[pref] !== true) { + if (styles[preferred] !== true) { file.fail( - 'Invalid list-item indent style `' + - pref + + 'Incorrect list-item indent style `' + + preferred + "`: use either `'tab-size'`, `'space'`, or `'mixed'`" ); } - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$4(tree, 'list', visitor); function visitor(node) { var spread = node.spread || node.loose; @@ -42548,28 +43781,30 @@ function listItemIndent(tree, file, pref) { var style; var diff; var reason; + var abs; marker = contents .slice(start$3(item).offset, final.offset) .replace(/\[[x ]?]\s*$/i, ''); - bulletSize = marker.trimRight().length; + bulletSize = marker.replace(/\s+$/, '').length; style = - pref === 'tab-size' || (pref === 'mixed' && spread) + preferred === 'tab-size' || (preferred === 'mixed' && spread) ? Math.ceil(bulletSize / 4) * 4 : bulletSize + 1; if (marker.length !== style) { diff = style - marker.length; + abs = Math.abs(diff); reason = 'Incorrect list-item indent: ' + (diff > 0 ? 'add' : 'remove') + ' ' + - Math.abs(diff) + + abs + ' ' + - plur('space', diff); + pluralize('space', abs); file.message(reason, final); } @@ -42577,1385 +43812,7850 @@ function listItemIndent(tree, file, pref) { } } -var mdastUtilToString = toString$4; +var convert_1$5 = convert$6; -// Get the text content of a node. If the node itself does not expose -// plain-text fields, `toString` will recursivly try its children. -function toString$4(node) { - return ( - valueOf$1(node) || - (node.children && node.children.map(toString$4).join('')) || - '' - ) +function convert$6(test) { + if (typeof test === 'string') { + return typeFactory$5(test) + } + + if (test === null || test === undefined) { + return ok$6 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$5 : matchesFactory$5)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') } -// Get the value of `node`. Checks, `value`, `alt`, and `title`, in that order. -function valueOf$1(node) { - return ( - (node && node.value ? node.value : node.alt ? node.alt : node.title) || '' - ) +function convertAll$5(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$6(tests[index]); + } + + return results } -var remarkLintNoAutoLinkWithoutProtocol = unifiedLintRule( - 'remark-lint:no-auto-link-without-protocol', - noAutoLinkWithoutProtocol -); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$5(test) { + return matches -var start$4 = unistUtilPosition.start; -var end$1 = unistUtilPosition.end; + function matches(node) { + var key; -// Protocol expression. -// See: . -var protocol$2 = /^[a-z][a-z+.-]+:\/?/i; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } -var reason = 'All automatic links must start with a protocol'; + return true + } +} -function noAutoLinkWithoutProtocol(tree, file) { - unistUtilVisit(tree, 'link', visitor); +function anyFactory$5(tests) { + var checks = convertAll$5(tests); + var length = checks.length; - function visitor(node) { - var children; + return matches - if (!unistUtilGenerated(node)) { - children = node.children; + function matches() { + var index = -1; - if ( - start$4(node).column === start$4(children[0]).column - 1 && - end$1(node).column === end$1(children[children.length - 1]).column + 1 && - !protocol$2.test(mdastUtilToString(node)) - ) { - file.message(reason, node); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } } + + return false } } -var remarkLintNoBlockquoteWithoutMarker = unifiedLintRule( - 'remark-lint:no-blockquote-without-marker', - noBlockquoteWithoutMarker -); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$5(test) { + return type -var reason$1 = 'Missing marker in blockquote'; + function type(node) { + return Boolean(node && node.type === test) + } +} -function noBlockquoteWithoutMarker(tree, file) { - var contents = String(file); - var location = vfileLocation(file); - var last = contents.length; +// Utility to return true. +function ok$6() { + return true +} - unistUtilVisit(tree, 'blockquote', visitor); +var unistUtilVisitParents$5 = visitParents$5; - function visitor(node) { - var indent = node.position && node.position.indent; - var start; - var length; - var index; - var line; - var offset; - var character; - var pos; - if (unistUtilGenerated(node) || !indent || indent.length === 0) { - return - } - start = unistUtilPosition.start(node).line; - length = indent.length; - index = -1; +var CONTINUE$a = true; +var SKIP$a = 'skip'; +var EXIT$a = false; - while (++index < length) { - line = start + index + 1; - pos = {line: line, column: indent[index]}; - offset = location.toOffset(pos) - 1; +visitParents$5.CONTINUE = CONTINUE$a; +visitParents$5.SKIP = SKIP$a; +visitParents$5.EXIT = EXIT$a; - while (++offset < last) { +function visitParents$5(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$5(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$5(visitor(node, parents)); + + if (result[0] === EXIT$a) { + return result + } + } + + if (node.children && result[0] !== SKIP$a) { + subresult = toResult$5(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$a ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$a) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$5(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$a, value] + } + + return [value] +} + +var unistUtilVisit$5 = visit$5; + + + +var CONTINUE$b = unistUtilVisitParents$5.CONTINUE; +var SKIP$b = unistUtilVisitParents$5.SKIP; +var EXIT$b = unistUtilVisitParents$5.EXIT; + +visit$5.CONTINUE = CONTINUE$b; +visit$5.SKIP = SKIP$b; +visit$5.EXIT = EXIT$b; + +function visit$5(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$5(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var mdastUtilToString = toString$4; + +// Get the text content of a node. +// Prefer the node’s plain-text fields, otherwise serialize its children, +// and if the given value is an array, serialize the nodes in it. +function toString$4(node) { + return ( + (node && + (node.value || + node.alt || + node.title || + ('children' in node && all$1(node.children)) || + ('length' in node && all$1(node)))) || + '' + ) +} + +function all$1(values) { + var result = []; + var length = values.length; + var index = -1; + + while (++index < length) { + result[index] = toString$4(values[index]); + } + + return result.join('') +} + +var remarkLintNoAutoLinkWithoutProtocol = unifiedLintRule( + 'remark-lint:no-auto-link-without-protocol', + noAutoLinkWithoutProtocol +); + +var start$4 = unistUtilPosition.start; +var end$1 = unistUtilPosition.end; + +// Protocol expression. +// See: . +var protocol$2 = /^[a-z][a-z+.-]+:\/?/i; + +var reason = 'All automatic links must start with a protocol'; + +function noAutoLinkWithoutProtocol(tree, file) { + unistUtilVisit$5(tree, 'link', visitor); + + function visitor(node) { + var children; + + if (!unistUtilGenerated(node)) { + children = node.children; + + if ( + start$4(node).column === start$4(children[0]).column - 1 && + end$1(node).column === end$1(children[children.length - 1]).column + 1 && + !protocol$2.test(mdastUtilToString(node)) + ) { + file.message(reason, node); + } + } + } +} + +var vfileLocation$3 = factory$b; + +function factory$b(file) { + var contents = indices$3(String(file)); + + return { + toPosition: offsetToPositionFactory$3(contents), + toOffset: positionToOffsetFactory$3(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$3(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$3(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$3(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$6 = convert$7; + +function convert$7(test) { + if (typeof test === 'string') { + return typeFactory$6(test) + } + + if (test === null || test === undefined) { + return ok$7 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$6 : matchesFactory$6)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$6(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$7(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$6(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$6(tests) { + var checks = convertAll$6(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$6(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$7() { + return true +} + +var unistUtilVisitParents$6 = visitParents$6; + + + +var CONTINUE$c = true; +var SKIP$c = 'skip'; +var EXIT$c = false; + +visitParents$6.CONTINUE = CONTINUE$c; +visitParents$6.SKIP = SKIP$c; +visitParents$6.EXIT = EXIT$c; + +function visitParents$6(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$6(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$6(visitor(node, parents)); + + if (result[0] === EXIT$c) { + return result + } + } + + if (node.children && result[0] !== SKIP$c) { + subresult = toResult$6(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$c ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$c) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$6(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$c, value] + } + + return [value] +} + +var unistUtilVisit$6 = visit$6; + + + +var CONTINUE$d = unistUtilVisitParents$6.CONTINUE; +var SKIP$d = unistUtilVisitParents$6.SKIP; +var EXIT$d = unistUtilVisitParents$6.EXIT; + +visit$6.CONTINUE = CONTINUE$d; +visit$6.SKIP = SKIP$d; +visit$6.EXIT = EXIT$d; + +function visit$6(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$6(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoBlockquoteWithoutMarker = unifiedLintRule( + 'remark-lint:no-blockquote-without-marker', + noBlockquoteWithoutMarker +); + +var reason$1 = 'Missing marker in block quote'; + +function noBlockquoteWithoutMarker(tree, file) { + var contents = String(file); + var location = vfileLocation$3(file); + var last = contents.length; + + unistUtilVisit$6(tree, 'blockquote', visitor); + + function visitor(node) { + var indent = node.position && node.position.indent; + var start; + var length; + var index; + var line; + var offset; + var character; + var pos; + + if (unistUtilGenerated(node) || !indent || indent.length === 0) { + return + } + + start = unistUtilPosition.start(node).line; + length = indent.length; + index = -1; + + while (++index < length) { + line = start + index + 1; + pos = {line: line, column: indent[index]}; + offset = location.toOffset(pos) - 1; + + while (++offset < last) { character = contents.charAt(offset); - if (character === '>') { - break - } + if (character === '>') { + break + } + + /* istanbul ignore else - just for safety */ + if (character !== ' ' && character !== '\t') { + file.message(reason$1, pos); + break + } + } + } + } +} + +var convert_1$7 = convert$8; + +function convert$8(test) { + if (typeof test === 'string') { + return typeFactory$7(test) + } + + if (test === null || test === undefined) { + return ok$8 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$7 : matchesFactory$7)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$7(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$8(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$7(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$7(tests) { + var checks = convertAll$7(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$7(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$8() { + return true +} + +var unistUtilVisitParents$7 = visitParents$7; + + + +var CONTINUE$e = true; +var SKIP$e = 'skip'; +var EXIT$e = false; + +visitParents$7.CONTINUE = CONTINUE$e; +visitParents$7.SKIP = SKIP$e; +visitParents$7.EXIT = EXIT$e; + +function visitParents$7(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$7(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$7(visitor(node, parents)); + + if (result[0] === EXIT$e) { + return result + } + } + + if (node.children && result[0] !== SKIP$e) { + subresult = toResult$7(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$e ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$e) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$7(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$e, value] + } + + return [value] +} + +var unistUtilVisit$7 = visit$7; + + + +var CONTINUE$f = unistUtilVisitParents$7.CONTINUE; +var SKIP$f = unistUtilVisitParents$7.SKIP; +var EXIT$f = unistUtilVisitParents$7.EXIT; + +visit$7.CONTINUE = CONTINUE$f; +visit$7.SKIP = SKIP$f; +visit$7.EXIT = EXIT$f; + +function visit$7(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$7(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoLiteralUrls = unifiedLintRule('remark-lint:no-literal-urls', noLiteralURLs); + +var start$5 = unistUtilPosition.start; +var end$2 = unistUtilPosition.end; +var mailto$3 = 'mailto:'; +var reason$2 = 'Don’t use literal URLs without angle brackets'; + +function noLiteralURLs(tree, file) { + unistUtilVisit$7(tree, 'link', visitor); + + function visitor(node) { + var children = node.children; + var value = mdastUtilToString(node); + + if ( + !unistUtilGenerated(node) && + start$5(node).column === start$5(children[0]).column && + end$2(node).column === end$2(children[children.length - 1]).column && + (node.url === mailto$3 + value || node.url === value) + ) { + file.message(reason$2, node); + } + } +} + +var convert_1$8 = convert$9; + +function convert$9(test) { + if (typeof test === 'string') { + return typeFactory$8(test) + } + + if (test === null || test === undefined) { + return ok$9 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$8 : matchesFactory$8)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$8(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$9(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$8(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$8(tests) { + var checks = convertAll$8(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$8(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$9() { + return true +} + +var unistUtilVisitParents$8 = visitParents$8; + + + +var CONTINUE$g = true; +var SKIP$g = 'skip'; +var EXIT$g = false; + +visitParents$8.CONTINUE = CONTINUE$g; +visitParents$8.SKIP = SKIP$g; +visitParents$8.EXIT = EXIT$g; + +function visitParents$8(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$8(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$8(visitor(node, parents)); + + if (result[0] === EXIT$g) { + return result + } + } + + if (node.children && result[0] !== SKIP$g) { + subresult = toResult$8(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$g ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$g) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$8(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$g, value] + } + + return [value] +} + +var unistUtilVisit$8 = visit$8; + + + +var CONTINUE$h = unistUtilVisitParents$8.CONTINUE; +var SKIP$h = unistUtilVisitParents$8.SKIP; +var EXIT$h = unistUtilVisitParents$8.EXIT; + +visit$8.CONTINUE = CONTINUE$h; +visit$8.SKIP = SKIP$h; +visit$8.EXIT = EXIT$h; + +function visit$8(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$8(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintOrderedListMarkerStyle = unifiedLintRule( + 'remark-lint:ordered-list-marker-style', + orderedListMarkerStyle +); + +var start$6 = unistUtilPosition.start; + +var styles$1 = { + ')': true, + '.': true, + null: true +}; + +function orderedListMarkerStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option !== 'string' || option === 'consistent' ? null : option; + + if (styles$1[preferred] !== true) { + file.fail( + 'Incorrect ordered list item marker style `' + + preferred + + "`: use either `'.'` or `')'`" + ); + } + + unistUtilVisit$8(tree, 'list', visitor); + + function visitor(node) { + var children = node.children; + var length = node.ordered ? children.length : 0; + var index = -1; + var marker; + var child; + + while (++index < length) { + child = children[index]; + + if (!unistUtilGenerated(child)) { + marker = contents + .slice(start$6(child).offset, start$6(child.children[0]).offset) + .replace(/\s|\d/g, '') + .replace(/\[[x ]?]\s*$/i, ''); + + if (preferred) { + if (marker !== preferred) { + file.message('Marker style should be `' + preferred + '`', child); + } + } else { + preferred = marker; + } + } + } + } +} + +var convert_1$9 = convert$a; + +function convert$a(test) { + if (typeof test === 'string') { + return typeFactory$9(test) + } + + if (test === null || test === undefined) { + return ok$a + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$9 : matchesFactory$9)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$9(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$a(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$9(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$9(tests) { + var checks = convertAll$9(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$9(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$a() { + return true +} + +var unistUtilVisitParents$9 = visitParents$9; + + + +var CONTINUE$i = true; +var SKIP$i = 'skip'; +var EXIT$i = false; + +visitParents$9.CONTINUE = CONTINUE$i; +visitParents$9.SKIP = SKIP$i; +visitParents$9.EXIT = EXIT$i; + +function visitParents$9(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$9(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$9(visitor(node, parents)); + + if (result[0] === EXIT$i) { + return result + } + } + + if (node.children && result[0] !== SKIP$i) { + subresult = toResult$9(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$i ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$i) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$9(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$i, value] + } + + return [value] +} + +var unistUtilVisit$9 = visit$9; + + + +var CONTINUE$j = unistUtilVisitParents$9.CONTINUE; +var SKIP$j = unistUtilVisitParents$9.SKIP; +var EXIT$j = unistUtilVisitParents$9.EXIT; + +visit$9.CONTINUE = CONTINUE$j; +visit$9.SKIP = SKIP$j; +visit$9.EXIT = EXIT$j; + +function visit$9(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$9(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintHardBreakSpaces = unifiedLintRule('remark-lint:hard-break-spaces', hardBreakSpaces); + +var reason$3 = 'Use two spaces for hard line breaks'; + +function hardBreakSpaces(tree, file) { + var contents = String(file); + + unistUtilVisit$9(tree, 'break', visitor); + + function visitor(node) { + var value; + + if (!unistUtilGenerated(node)) { + value = contents + .slice(unistUtilPosition.start(node).offset, unistUtilPosition.end(node).offset) + .split('\n', 1)[0] + .replace(/\r$/, ''); + + if (value.length > 2) { + file.message(reason$3, node); + } + } + } +} + +var convert_1$a = convert$b; + +function convert$b(test) { + if (typeof test === 'string') { + return typeFactory$a(test) + } + + if (test === null || test === undefined) { + return ok$b + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$a : matchesFactory$a)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$a(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$b(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$a(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$a(tests) { + var checks = convertAll$a(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$a(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$b() { + return true +} + +var unistUtilVisitParents$a = visitParents$a; + + + +var CONTINUE$k = true; +var SKIP$k = 'skip'; +var EXIT$k = false; + +visitParents$a.CONTINUE = CONTINUE$k; +visitParents$a.SKIP = SKIP$k; +visitParents$a.EXIT = EXIT$k; + +function visitParents$a(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$a(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$a(visitor(node, parents)); + + if (result[0] === EXIT$k) { + return result + } + } + + if (node.children && result[0] !== SKIP$k) { + subresult = toResult$a(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$k ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$k) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$a(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$k, value] + } + + return [value] +} + +var unistUtilVisit$a = visit$a; + + + +var CONTINUE$l = unistUtilVisitParents$a.CONTINUE; +var SKIP$l = unistUtilVisitParents$a.SKIP; +var EXIT$l = unistUtilVisitParents$a.EXIT; + +visit$a.CONTINUE = CONTINUE$l; +visit$a.SKIP = SKIP$l; +visit$a.EXIT = EXIT$l; + +function visit$a(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$a(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoDuplicateDefinitions = unifiedLintRule( + 'remark-lint:no-duplicate-definitions', + noDuplicateDefinitions +); + +var reason$4 = 'Do not use definitions with the same identifier'; + +function noDuplicateDefinitions(tree, file) { + var map = {}; + + unistUtilVisit$a(tree, ['definition', 'footnoteDefinition'], check); + + function check(node) { + var identifier; + var duplicate; + + if (!unistUtilGenerated(node)) { + identifier = node.identifier; + duplicate = map[identifier]; + + if (duplicate && duplicate.type) { + file.message( + reason$4 + ' (' + unistUtilStringifyPosition(unistUtilPosition.start(duplicate)) + ')', + node + ); + } + + map[identifier] = node; + } + } +} + +var convert_1$b = convert$c; + +function convert$c(test) { + if (typeof test === 'string') { + return typeFactory$b(test) + } + + if (test === null || test === undefined) { + return ok$c + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$b : matchesFactory$b)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$b(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$c(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$b(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$b(tests) { + var checks = convertAll$b(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$b(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$c() { + return true +} + +var unistUtilVisitParents$b = visitParents$b; + + + +var CONTINUE$m = true; +var SKIP$m = 'skip'; +var EXIT$m = false; + +visitParents$b.CONTINUE = CONTINUE$m; +visitParents$b.SKIP = SKIP$m; +visitParents$b.EXIT = EXIT$m; + +function visitParents$b(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$b(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$b(visitor(node, parents)); + + if (result[0] === EXIT$m) { + return result + } + } + + if (node.children && result[0] !== SKIP$m) { + subresult = toResult$b(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$m ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$m) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$b(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$m, value] + } + + return [value] +} + +var unistUtilVisit$b = visit$b; + + + +var CONTINUE$n = unistUtilVisitParents$b.CONTINUE; +var SKIP$n = unistUtilVisitParents$b.SKIP; +var EXIT$n = unistUtilVisitParents$b.EXIT; + +visit$b.CONTINUE = CONTINUE$n; +visit$b.SKIP = SKIP$n; +visit$b.EXIT = EXIT$n; + +function visit$b(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$b(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var mdastUtilHeadingStyle = style; + +function style(node, relative) { + var last = node.children[node.children.length - 1]; + var depth = node.depth; + var pos = node && node.position && node.position.end; + var final = last && last.position && last.position.end; + + if (!pos) { + return null + } + + // This can only occur for `'atx'` and `'atx-closed'` headings. + // This might incorrectly match `'atx'` headings with lots of trailing white + // space as an `'atx-closed'` heading. + if (!last) { + if (pos.column - 1 <= depth * 2) { + return consolidate(depth, relative) + } + + return 'atx-closed' + } + + if (final.line + 1 === pos.line) { + return 'setext' + } + + if (final.column + depth < pos.column) { + return 'atx-closed' + } + + return consolidate(depth, relative) +} + +// Get the probable style of an atx-heading, depending on preferred style. +function consolidate(depth, relative) { + return depth < 3 + ? 'atx' + : relative === 'atx' || relative === 'setext' + ? relative + : null +} + +var remarkLintNoHeadingContentIndent = unifiedLintRule( + 'remark-lint:no-heading-content-indent', + noHeadingContentIndent +); + +var start$7 = unistUtilPosition.start; +var end$3 = unistUtilPosition.end; + +function noHeadingContentIndent(tree, file) { + var contents = String(file); + + unistUtilVisit$b(tree, 'heading', visitor); + + function visitor(node) { + var depth; + var children; + var type; + var head; + var initial; + var final; + var diff; + var index; + var char; + var reason; + var abs; + + if (unistUtilGenerated(node)) { + return + } + + depth = node.depth; + children = node.children; + type = mdastUtilHeadingStyle(node, 'atx'); + + if (type === 'atx' || type === 'atx-closed') { + initial = start$7(node); + index = initial.offset; + char = contents.charAt(index); + + while (char && char !== '#') { + char = contents.charAt(++index); + } + + /* istanbul ignore if - CR/LF bug: remarkjs/remark#195. */ + if (!char) { + return + } + + index = depth + (index - initial.offset); + head = start$7(children[0]).column; + + // Ignore empty headings. + if (!head) { + return + } + + diff = head - initial.column - 1 - index; + + if (diff) { + abs = Math.abs(diff); + + reason = + (diff > 0 ? 'Remove' : 'Add') + + ' ' + + abs + + ' ' + + pluralize('space', abs) + + ' before this heading’s content'; + + file.message(reason, start$7(children[0])); + } + } + + // Closed ATX headings always must have a space between their content and + // the final hashes, thus, there is no `add x spaces`. + if (type === 'atx-closed') { + final = end$3(children[children.length - 1]); + diff = end$3(node).column - final.column - 1 - depth; + + if (diff) { + reason = + 'Remove ' + + diff + + ' ' + + pluralize('space', diff) + + ' after this heading’s content'; + + file.message(reason, final); + } + } + } +} + +var convert_1$c = convert$d; + +function convert$d(test) { + if (typeof test === 'string') { + return typeFactory$c(test) + } + + if (test === null || test === undefined) { + return ok$d + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$c : matchesFactory$c)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$c(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$d(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$c(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$c(tests) { + var checks = convertAll$c(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$c(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$d() { + return true +} + +var unistUtilVisitParents$c = visitParents$c; + + + +var CONTINUE$o = true; +var SKIP$o = 'skip'; +var EXIT$o = false; + +visitParents$c.CONTINUE = CONTINUE$o; +visitParents$c.SKIP = SKIP$o; +visitParents$c.EXIT = EXIT$o; + +function visitParents$c(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$c(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$c(visitor(node, parents)); + + if (result[0] === EXIT$o) { + return result + } + } + + if (node.children && result[0] !== SKIP$o) { + subresult = toResult$c(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$o ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$o) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$c(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$o, value] + } + + return [value] +} + +var unistUtilVisit$c = visit$c; + + + +var CONTINUE$p = unistUtilVisitParents$c.CONTINUE; +var SKIP$p = unistUtilVisitParents$c.SKIP; +var EXIT$p = unistUtilVisitParents$c.EXIT; + +visit$c.CONTINUE = CONTINUE$p; +visit$c.SKIP = SKIP$p; +visit$c.EXIT = EXIT$p; + +function visit$c(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$c(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoInlinePadding = unifiedLintRule('remark-lint:no-inline-padding', noInlinePadding); + +function noInlinePadding(tree, file) { + unistUtilVisit$c(tree, ['emphasis', 'strong', 'delete', 'image', 'link'], visitor); + + function visitor(node) { + var contents; + + if (!unistUtilGenerated(node)) { + contents = mdastUtilToString(node); + + if ( + contents.charAt(0) === ' ' || + contents.charAt(contents.length - 1) === ' ' + ) { + file.message('Don’t pad `' + node.type + '` with inner spaces', node); + } + } + } +} + +var convert_1$d = convert$e; + +function convert$e(test) { + if (typeof test === 'string') { + return typeFactory$d(test) + } + + if (test === null || test === undefined) { + return ok$e + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$d : matchesFactory$d)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$d(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$e(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$d(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$d(tests) { + var checks = convertAll$d(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$d(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$e() { + return true +} + +var unistUtilVisitParents$d = visitParents$d; + + + +var CONTINUE$q = true; +var SKIP$q = 'skip'; +var EXIT$q = false; + +visitParents$d.CONTINUE = CONTINUE$q; +visitParents$d.SKIP = SKIP$q; +visitParents$d.EXIT = EXIT$q; + +function visitParents$d(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$d(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$d(visitor(node, parents)); + + if (result[0] === EXIT$q) { + return result + } + } + + if (node.children && result[0] !== SKIP$q) { + subresult = toResult$d(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$q ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$q) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$d(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$q, value] + } + + return [value] +} + +var unistUtilVisit$d = visit$d; + + + +var CONTINUE$r = unistUtilVisitParents$d.CONTINUE; +var SKIP$r = unistUtilVisitParents$d.SKIP; +var EXIT$r = unistUtilVisitParents$d.EXIT; + +visit$d.CONTINUE = CONTINUE$r; +visit$d.SKIP = SKIP$r; +visit$d.EXIT = EXIT$r; + +function visit$d(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$d(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShortcutReferenceImage = unifiedLintRule( + 'remark-lint:no-shortcut-reference-image', + noShortcutReferenceImage +); + +var reason$5 = 'Use the trailing [] on reference images'; + +function noShortcutReferenceImage(tree, file) { + unistUtilVisit$d(tree, 'imageReference', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { + file.message(reason$5, node); + } + } +} + +var convert_1$e = convert$f; + +function convert$f(test) { + if (typeof test === 'string') { + return typeFactory$e(test) + } + + if (test === null || test === undefined) { + return ok$f + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$e : matchesFactory$e)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$e(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$f(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$e(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$e(tests) { + var checks = convertAll$e(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$e(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$f() { + return true +} + +var unistUtilVisitParents$e = visitParents$e; + + + +var CONTINUE$s = true; +var SKIP$s = 'skip'; +var EXIT$s = false; + +visitParents$e.CONTINUE = CONTINUE$s; +visitParents$e.SKIP = SKIP$s; +visitParents$e.EXIT = EXIT$s; + +function visitParents$e(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$e(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$e(visitor(node, parents)); + + if (result[0] === EXIT$s) { + return result + } + } + + if (node.children && result[0] !== SKIP$s) { + subresult = toResult$e(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$s ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$s) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$e(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$s, value] + } + + return [value] +} + +var unistUtilVisit$e = visit$e; + + + +var CONTINUE$t = unistUtilVisitParents$e.CONTINUE; +var SKIP$t = unistUtilVisitParents$e.SKIP; +var EXIT$t = unistUtilVisitParents$e.EXIT; + +visit$e.CONTINUE = CONTINUE$t; +visit$e.SKIP = SKIP$t; +visit$e.EXIT = EXIT$t; + +function visit$e(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$e(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShortcutReferenceLink = unifiedLintRule( + 'remark-lint:no-shortcut-reference-link', + noShortcutReferenceLink +); + +var reason$6 = 'Use the trailing `[]` on reference links'; + +function noShortcutReferenceLink(tree, file) { + unistUtilVisit$e(tree, 'linkReference', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { + file.message(reason$6, node); + } + } +} + +var convert_1$f = convert$g; + +function convert$g(test) { + if (typeof test === 'string') { + return typeFactory$f(test) + } + + if (test === null || test === undefined) { + return ok$g + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$f : matchesFactory$f)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$f(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$g(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$f(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$f(tests) { + var checks = convertAll$f(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$f(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$g() { + return true +} + +var unistUtilVisitParents$f = visitParents$f; + + + +var CONTINUE$u = true; +var SKIP$u = 'skip'; +var EXIT$u = false; + +visitParents$f.CONTINUE = CONTINUE$u; +visitParents$f.SKIP = SKIP$u; +visitParents$f.EXIT = EXIT$u; + +function visitParents$f(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$f(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$f(visitor(node, parents)); + + if (result[0] === EXIT$u) { + return result + } + } + + if (node.children && result[0] !== SKIP$u) { + subresult = toResult$f(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$u ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$u) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$f(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$u, value] + } + + return [value] +} + +var unistUtilVisit$f = visit$f; + + + +var CONTINUE$v = unistUtilVisitParents$f.CONTINUE; +var SKIP$v = unistUtilVisitParents$f.SKIP; +var EXIT$v = unistUtilVisitParents$f.EXIT; + +visit$f.CONTINUE = CONTINUE$v; +visit$f.SKIP = SKIP$v; +visit$f.EXIT = EXIT$v; + +function visit$f(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$f(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoUndefinedReferences = unifiedLintRule( + 'remark-lint:no-undefined-references', + noUndefinedReferences +); + +var reason$7 = 'Found reference to undefined definition'; + +// The identifier is upcased to avoid naming collisions with fields inherited +// from `Object.prototype`. +// If `Object.create(null)` was used in place of `{}`, downcasing would work +// equally well. +function normalize$3(s) { + return collapseWhiteSpace(s.toUpperCase()) +} + +function noUndefinedReferences(tree, file, option) { + var allow = ((option || {}).allow || []).map(normalize$3); + var map = {}; + + unistUtilVisit$f(tree, ['definition', 'footnoteDefinition'], mark); + unistUtilVisit$f(tree, ['imageReference', 'linkReference', 'footnoteReference'], find); + + function mark(node) { + if (!unistUtilGenerated(node)) { + map[normalize$3(node.identifier)] = true; + } + } + + function find(node) { + if ( + !unistUtilGenerated(node) && + !(normalize$3(node.identifier) in map) && + allow.indexOf(normalize$3(node.identifier)) === -1 + ) { + file.message(reason$7, node); + } + } +} + +var convert_1$g = convert$h; + +function convert$h(test) { + if (typeof test === 'string') { + return typeFactory$g(test) + } + + if (test === null || test === undefined) { + return ok$h + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$g : matchesFactory$g)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$g(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$h(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$g(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$g(tests) { + var checks = convertAll$g(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$g(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$h() { + return true +} + +var unistUtilVisitParents$g = visitParents$g; + + + +var CONTINUE$w = true; +var SKIP$w = 'skip'; +var EXIT$w = false; + +visitParents$g.CONTINUE = CONTINUE$w; +visitParents$g.SKIP = SKIP$w; +visitParents$g.EXIT = EXIT$w; + +function visitParents$g(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$g(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$g(visitor(node, parents)); + + if (result[0] === EXIT$w) { + return result + } + } + + if (node.children && result[0] !== SKIP$w) { + subresult = toResult$g(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$w ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$w) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$g(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$w, value] + } + + return [value] +} + +var unistUtilVisit$g = visit$g; + + + +var CONTINUE$x = unistUtilVisitParents$g.CONTINUE; +var SKIP$x = unistUtilVisitParents$g.SKIP; +var EXIT$x = unistUtilVisitParents$g.EXIT; + +visit$g.CONTINUE = CONTINUE$x; +visit$g.SKIP = SKIP$x; +visit$g.EXIT = EXIT$x; + +function visit$g(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$g(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoUnusedDefinitions = unifiedLintRule('remark-lint:no-unused-definitions', noUnusedDefinitions); + +var reason$8 = 'Found unused definition'; + +function noUnusedDefinitions(tree, file) { + var map = {}; + var identifier; + var entry; + + unistUtilVisit$g(tree, ['definition', 'footnoteDefinition'], find); + unistUtilVisit$g(tree, ['imageReference', 'linkReference', 'footnoteReference'], mark); + + for (identifier in map) { + entry = map[identifier]; + + if (!entry.used) { + file.message(reason$8, entry.node); + } + } + + function find(node) { + if (!unistUtilGenerated(node)) { + map[node.identifier.toUpperCase()] = {node: node, used: false}; + } + } + + function mark(node) { + var info = map[node.identifier.toUpperCase()]; + + if (!unistUtilGenerated(node) && info) { + info.used = true; + } + } +} + +var plugins$1 = [ + remarkLint$1, + // Unix compatibility. + remarkLintFinalNewline, + // Rendering across vendors differs greatly if using other styles. + remarkLintListItemBulletIndent, + [remarkLintListItemIndent, 'tab-size'], + // Differs or unsupported across vendors. + remarkLintNoAutoLinkWithoutProtocol, + remarkLintNoBlockquoteWithoutMarker, + remarkLintNoLiteralUrls, + [remarkLintOrderedListMarkerStyle, '.'], + // Mistakes. + remarkLintHardBreakSpaces, + remarkLintNoDuplicateDefinitions, + remarkLintNoHeadingContentIndent, + remarkLintNoInlinePadding, + remarkLintNoShortcutReferenceImage, + remarkLintNoShortcutReferenceLink, + remarkLintNoUndefinedReferences, + remarkLintNoUnusedDefinitions +]; + +var remarkPresetLintRecommended = { + plugins: plugins$1 +}; + +var convert_1$h = convert$i; + +function convert$i(test) { + if (typeof test === 'string') { + return typeFactory$h(test) + } + + if (test === null || test === undefined) { + return ok$i + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$h : matchesFactory$h)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$h(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$i(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$h(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$h(tests) { + var checks = convertAll$h(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$h(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$i() { + return true +} + +var unistUtilVisitParents$h = visitParents$h; + + + +var CONTINUE$y = true; +var SKIP$y = 'skip'; +var EXIT$y = false; + +visitParents$h.CONTINUE = CONTINUE$y; +visitParents$h.SKIP = SKIP$y; +visitParents$h.EXIT = EXIT$y; + +function visitParents$h(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$h(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$h(visitor(node, parents)); + + if (result[0] === EXIT$y) { + return result + } + } + + if (node.children && result[0] !== SKIP$y) { + subresult = toResult$h(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$y ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$y) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$h(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$y, value] + } + + return [value] +} + +var unistUtilVisit$h = visit$h; + + + +var CONTINUE$z = unistUtilVisitParents$h.CONTINUE; +var SKIP$z = unistUtilVisitParents$h.SKIP; +var EXIT$z = unistUtilVisitParents$h.EXIT; + +visit$h.CONTINUE = CONTINUE$z; +visit$h.SKIP = SKIP$z; +visit$h.EXIT = EXIT$z; + +function visit$h(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$h(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintBlockquoteIndentation = unifiedLintRule( + 'remark-lint:blockquote-indentation', + blockquoteIndentation +); + +function blockquoteIndentation(tree, file, option) { + var preferred = typeof option === 'number' && !isNaN(option) ? option : null; + + unistUtilVisit$h(tree, 'blockquote', visitor); + + function visitor(node) { + var abs; + var diff; + var reason; + + if (unistUtilGenerated(node) || node.children.length === 0) { + return + } + + if (preferred) { + diff = preferred - check$3(node); + + if (diff !== 0) { + abs = Math.abs(diff); + reason = + (diff > 0 ? 'Add' : 'Remove') + + ' ' + + abs + + ' ' + + pluralize('space', abs) + + ' between block quote and content'; + + file.message(reason, unistUtilPosition.start(node.children[0])); + } + } else { + preferred = check$3(node); + } + } +} + +function check$3(node) { + var head = node.children[0]; + var indentation = unistUtilPosition.start(head).column - unistUtilPosition.start(node).column; + var padding = mdastUtilToString(head).match(/^ +/); + + if (padding) { + indentation += padding[0].length; + } + + return indentation +} + +var vfileLocation$4 = factory$c; + +function factory$c(file) { + var contents = indices$4(String(file)); + + return { + toPosition: offsetToPositionFactory$4(contents), + toOffset: positionToOffsetFactory$4(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$4(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$4(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$4(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$i = convert$j; + +function convert$j(test) { + if (typeof test === 'string') { + return typeFactory$i(test) + } + + if (test === null || test === undefined) { + return ok$j + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$i : matchesFactory$i)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$i(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$j(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$i(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$i(tests) { + var checks = convertAll$i(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$i(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$j() { + return true +} + +var unistUtilVisitParents$i = visitParents$i; + + + +var CONTINUE$A = true; +var SKIP$A = 'skip'; +var EXIT$A = false; + +visitParents$i.CONTINUE = CONTINUE$A; +visitParents$i.SKIP = SKIP$A; +visitParents$i.EXIT = EXIT$A; + +function visitParents$i(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$i(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$i(visitor(node, parents)); + + if (result[0] === EXIT$A) { + return result + } + } + + if (node.children && result[0] !== SKIP$A) { + subresult = toResult$i(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$A ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$A) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$i(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$A, value] + } + + return [value] +} + +var unistUtilVisit$i = visit$i; + + + +var CONTINUE$B = unistUtilVisitParents$i.CONTINUE; +var SKIP$B = unistUtilVisitParents$i.SKIP; +var EXIT$B = unistUtilVisitParents$i.EXIT; + +visit$i.CONTINUE = CONTINUE$B; +visit$i.SKIP = SKIP$B; +visit$i.EXIT = EXIT$B; + +function visit$i(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$i(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCheckboxCharacterStyle = unifiedLintRule( + 'remark-lint:checkbox-character-style', + checkboxCharacterStyle +); + +var start$8 = unistUtilPosition.start; +var end$4 = unistUtilPosition.end; + +var checked = {x: true, X: true}; +var unchecked = {' ': true, '\t': true}; +var types$1 = {true: 'checked', false: 'unchecked'}; + +function checkboxCharacterStyle(tree, file, option) { + var contents = String(file); + var location = vfileLocation$4(file); + var preferred = typeof option === 'object' ? option : {}; + + if (preferred.unchecked && unchecked[preferred.unchecked] !== true) { + file.fail( + 'Incorrect unchecked checkbox marker `' + + preferred.unchecked + + "`: use either `'\\t'`, or `' '`" + ); + } + + if (preferred.checked && checked[preferred.checked] !== true) { + file.fail( + 'Incorrect checked checkbox marker `' + + preferred.checked + + "`: use either `'x'`, or `'X'`" + ); + } + + unistUtilVisit$i(tree, 'listItem', visitor); + + function visitor(node) { + var type; + var initial; + var final; + var value; + var style; + var character; + var reason; + + // Exit early for items without checkbox. + if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { + return + } + + type = types$1[node.checked]; + initial = start$8(node).offset; + final = (node.children.length === 0 ? end$4(node) : start$8(node.children[0])) + .offset; + + // For a checkbox to be parsed, it must be followed by a whitespace. + value = contents.slice(initial, final).replace(/\s+$/, '').slice(0, -1); + + // The checkbox character is behind a square bracket. + character = value.charAt(value.length - 1); + style = preferred[type]; + + if (style) { + if (character !== style) { + reason = + type.charAt(0).toUpperCase() + + type.slice(1) + + ' checkboxes should use `' + + style + + '` as a marker'; + + file.message(reason, { + start: location.toPosition(initial + value.length - 1), + end: location.toPosition(initial + value.length) + }); + } + } else { + preferred[type] = character; + } + } +} + +var vfileLocation$5 = factory$d; + +function factory$d(file) { + var contents = indices$5(String(file)); + + return { + toPosition: offsetToPositionFactory$5(contents), + toOffset: positionToOffsetFactory$5(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$5(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$5(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$5(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$j = convert$k; + +function convert$k(test) { + if (typeof test === 'string') { + return typeFactory$j(test) + } + + if (test === null || test === undefined) { + return ok$k + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$j : matchesFactory$j)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$j(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$k(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$j(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$j(tests) { + var checks = convertAll$j(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$j(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$k() { + return true +} + +var unistUtilVisitParents$j = visitParents$j; + + + +var CONTINUE$C = true; +var SKIP$C = 'skip'; +var EXIT$C = false; + +visitParents$j.CONTINUE = CONTINUE$C; +visitParents$j.SKIP = SKIP$C; +visitParents$j.EXIT = EXIT$C; + +function visitParents$j(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$j(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$j(visitor(node, parents)); + + if (result[0] === EXIT$C) { + return result + } + } + + if (node.children && result[0] !== SKIP$C) { + subresult = toResult$j(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$C ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$C) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$j(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$C, value] + } + + return [value] +} + +var unistUtilVisit$j = visit$j; + + + +var CONTINUE$D = unistUtilVisitParents$j.CONTINUE; +var SKIP$D = unistUtilVisitParents$j.SKIP; +var EXIT$D = unistUtilVisitParents$j.EXIT; + +visit$j.CONTINUE = CONTINUE$D; +visit$j.SKIP = SKIP$D; +visit$j.EXIT = EXIT$D; + +function visit$j(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$j(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCheckboxContentIndent = unifiedLintRule( + 'remark-lint:checkbox-content-indent', + checkboxContentIndent +); + +var start$9 = unistUtilPosition.start; +var end$5 = unistUtilPosition.end; + +var reason$9 = 'Checkboxes should be followed by a single character'; + +function checkboxContentIndent(tree, file) { + var contents = String(file); + var location = vfileLocation$5(file); + + unistUtilVisit$j(tree, 'listItem', visitor); + + function visitor(node) { + var initial; + var final; + var value; + + // Exit early for items without checkbox. + if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { + return + } + + initial = start$9(node).offset; + /* istanbul ignore next - hard to test, couldn’t find a case. */ + final = (node.children.length === 0 ? end$5(node) : start$9(node.children[0])) + .offset; + + while (/[^\S\n]/.test(contents.charAt(final))) { + final++; + } + + // For a checkbox to be parsed, it must be followed by a whitespace. + value = contents.slice(initial, final); + value = value.slice(value.indexOf(']') + 1); + + if (value.length !== 1) { + file.message(reason$9, { + start: location.toPosition(final - value.length + 1), + end: location.toPosition(final) + }); + } + } +} + +var convert_1$k = convert$l; + +function convert$l(test) { + if (typeof test === 'string') { + return typeFactory$k(test) + } + + if (test === null || test === undefined) { + return ok$l + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$k : matchesFactory$k)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$k(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$l(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$k(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$k(tests) { + var checks = convertAll$k(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$k(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$l() { + return true +} + +var unistUtilVisitParents$k = visitParents$k; + + + +var CONTINUE$E = true; +var SKIP$E = 'skip'; +var EXIT$E = false; + +visitParents$k.CONTINUE = CONTINUE$E; +visitParents$k.SKIP = SKIP$E; +visitParents$k.EXIT = EXIT$E; + +function visitParents$k(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$k(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$k(visitor(node, parents)); + + if (result[0] === EXIT$E) { + return result + } + } + + if (node.children && result[0] !== SKIP$E) { + subresult = toResult$k(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$E ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$E) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$k(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$E, value] + } + + return [value] +} + +var unistUtilVisit$k = visit$k; + + + +var CONTINUE$F = unistUtilVisitParents$k.CONTINUE; +var SKIP$F = unistUtilVisitParents$k.SKIP; +var EXIT$F = unistUtilVisitParents$k.EXIT; + +visit$k.CONTINUE = CONTINUE$F; +visit$k.SKIP = SKIP$F; +visit$k.EXIT = EXIT$F; + +function visit$k(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$k(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCodeBlockStyle = unifiedLintRule('remark-lint:code-block-style', codeBlockStyle); + +var start$a = unistUtilPosition.start; +var end$6 = unistUtilPosition.end; + +var styles$2 = {null: true, fenced: true, indented: true}; + +function codeBlockStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; + + if (styles$2[preferred] !== true) { + file.fail( + 'Incorrect code block style `' + + preferred + + "`: use either `'consistent'`, `'fenced'`, or `'indented'`" + ); + } + + unistUtilVisit$k(tree, 'code', visitor); + + function visitor(node) { + var initial; + var final; + var current; + + if (unistUtilGenerated(node)) { + return null + } + + initial = start$a(node).offset; + final = end$6(node).offset; + + current = + node.lang || /^\s*([~`])\1{2,}/.test(contents.slice(initial, final)) + ? 'fenced' + : 'indented'; + + if (preferred) { + if (preferred !== current) { + file.message('Code blocks should be ' + preferred, node); + } + } else { + preferred = current; + } + } +} + +var convert_1$l = convert$m; + +function convert$m(test) { + if (typeof test === 'string') { + return typeFactory$l(test) + } + + if (test === null || test === undefined) { + return ok$m + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$l : matchesFactory$l)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$l(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$m(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$l(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$l(tests) { + var checks = convertAll$l(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$l(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$m() { + return true +} + +var unistUtilVisitParents$l = visitParents$l; + + + +var CONTINUE$G = true; +var SKIP$G = 'skip'; +var EXIT$G = false; + +visitParents$l.CONTINUE = CONTINUE$G; +visitParents$l.SKIP = SKIP$G; +visitParents$l.EXIT = EXIT$G; + +function visitParents$l(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$l(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$l(visitor(node, parents)); + + if (result[0] === EXIT$G) { + return result + } + } + + if (node.children && result[0] !== SKIP$G) { + subresult = toResult$l(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$G ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$G) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$l(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$G, value] + } + + return [value] +} + +var unistUtilVisit$l = visit$l; + + + +var CONTINUE$H = unistUtilVisitParents$l.CONTINUE; +var SKIP$H = unistUtilVisitParents$l.SKIP; +var EXIT$H = unistUtilVisitParents$l.EXIT; + +visit$l.CONTINUE = CONTINUE$H; +visit$l.SKIP = SKIP$H; +visit$l.EXIT = EXIT$H; + +function visit$l(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$l(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintDefinitionSpacing = unifiedLintRule('remark-lint:definition-spacing', definitionSpacing); + +var label$1 = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; +var reason$a = 'Do not use consecutive whitespace in definition labels'; + +function definitionSpacing(tree, file) { + var contents = String(file); + + unistUtilVisit$l(tree, ['definition', 'footnoteDefinition'], check); + + function check(node) { + var start = unistUtilPosition.start(node).offset; + var end = unistUtilPosition.end(node).offset; + + if ( + !unistUtilGenerated(node) && + /[ \t\n]{2,}/.test(contents.slice(start, end).match(label$1)[1]) + ) { + file.message(reason$a, node); + } + } +} + +var convert_1$m = convert$n; + +function convert$n(test) { + if (typeof test === 'string') { + return typeFactory$m(test) + } + + if (test === null || test === undefined) { + return ok$n + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$m : matchesFactory$m)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$m(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$n(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$m(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$m(tests) { + var checks = convertAll$m(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$m(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$n() { + return true +} + +var unistUtilVisitParents$m = visitParents$m; + + + +var CONTINUE$I = true; +var SKIP$I = 'skip'; +var EXIT$I = false; + +visitParents$m.CONTINUE = CONTINUE$I; +visitParents$m.SKIP = SKIP$I; +visitParents$m.EXIT = EXIT$I; + +function visitParents$m(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$m(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$m(visitor(node, parents)); + + if (result[0] === EXIT$I) { + return result + } + } + + if (node.children && result[0] !== SKIP$I) { + subresult = toResult$m(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$I ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$I) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$m(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$I, value] + } + + return [value] +} + +var unistUtilVisit$m = visit$m; + + + +var CONTINUE$J = unistUtilVisitParents$m.CONTINUE; +var SKIP$J = unistUtilVisitParents$m.SKIP; +var EXIT$J = unistUtilVisitParents$m.EXIT; + +visit$m.CONTINUE = CONTINUE$J; +visit$m.SKIP = SKIP$J; +visit$m.EXIT = EXIT$J; + +function visit$m(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$m(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFencedCodeFlag = unifiedLintRule('remark-lint:fenced-code-flag', fencedCodeFlag); + +var start$b = unistUtilPosition.start; +var end$7 = unistUtilPosition.end; + +var fence$2 = /^ {0,3}([~`])\1{2,}/; +var reasonIncorrect = 'Incorrect code language flag'; +var reasonMissing = 'Missing code language flag'; + +function fencedCodeFlag(tree, file, option) { + var contents = String(file); + var allowEmpty = false; + var allowed = []; + var flags = option; + + if (typeof flags === 'object' && !('length' in flags)) { + allowEmpty = Boolean(flags.allowEmpty); + flags = flags.flags; + } + + if (typeof flags === 'object' && 'length' in flags) { + allowed = String(flags).split(','); + } + + unistUtilVisit$m(tree, 'code', visitor); + + function visitor(node) { + var value; + + if (!unistUtilGenerated(node)) { + if (node.lang) { + if (allowed.length !== 0 && allowed.indexOf(node.lang) === -1) { + file.message(reasonIncorrect, node); + } + } else { + value = contents.slice(start$b(node).offset, end$7(node).offset); + + if (!allowEmpty && fence$2.test(value)) { + file.message(reasonMissing, node); + } + } + } + } +} + +var convert_1$n = convert$o; + +function convert$o(test) { + if (typeof test === 'string') { + return typeFactory$n(test) + } + + if (test === null || test === undefined) { + return ok$o + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$n : matchesFactory$n)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$n(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$o(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$n(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$n(tests) { + var checks = convertAll$n(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$n(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$o() { + return true +} + +var unistUtilVisitParents$n = visitParents$n; + + + +var CONTINUE$K = true; +var SKIP$K = 'skip'; +var EXIT$K = false; + +visitParents$n.CONTINUE = CONTINUE$K; +visitParents$n.SKIP = SKIP$K; +visitParents$n.EXIT = EXIT$K; + +function visitParents$n(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$n(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$n(visitor(node, parents)); + + if (result[0] === EXIT$K) { + return result + } + } + + if (node.children && result[0] !== SKIP$K) { + subresult = toResult$n(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$K ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$K) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$n(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$K, value] + } + + return [value] +} + +var unistUtilVisit$n = visit$n; + + + +var CONTINUE$L = unistUtilVisitParents$n.CONTINUE; +var SKIP$L = unistUtilVisitParents$n.SKIP; +var EXIT$L = unistUtilVisitParents$n.EXIT; + +visit$n.CONTINUE = CONTINUE$L; +visit$n.SKIP = SKIP$L; +visit$n.EXIT = EXIT$L; + +function visit$n(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$n(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFencedCodeMarker = unifiedLintRule('remark-lint:fenced-code-marker', fencedCodeMarker); + +var markers = { + '`': true, + '~': true, + null: true +}; + +function fencedCodeMarker(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; + + if (markers[preferred] !== true) { + file.fail( + 'Incorrect fenced code marker `' + + preferred + + "`: use either `'consistent'`, `` '`' ``, or `'~'`" + ); + } + + unistUtilVisit$n(tree, 'code', visitor); + + function visitor(node) { + var start; + var marker; + var label; + + if (!unistUtilGenerated(node)) { + start = unistUtilPosition.start(node).offset; + marker = contents + .slice(start, start + 4) + .replace(/^\s+/, '') + .charAt(0); + + // Ignore unfenced code blocks. + if (markers[marker] === true) { + if (preferred) { + if (marker !== preferred) { + label = preferred === '~' ? preferred : '` ` `'; + file.message( + 'Fenced code should use `' + label + '` as a marker', + node + ); + } + } else { + preferred = marker; + } + } + } + } +} + +var remarkLintFileExtension = unifiedLintRule('remark-lint:file-extension', fileExtension); + +function fileExtension(tree, file, option) { + var ext = file.extname; + var preferred = typeof option === 'string' ? option : 'md'; + + if (ext && ext.slice(1) !== preferred) { + file.message('Incorrect extension: use `' + preferred + '`'); + } +} + +var convert_1$o = convert$p; + +function convert$p(test) { + if (typeof test === 'string') { + return typeFactory$o(test) + } + + if (test === null || test === undefined) { + return ok$p + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$o : matchesFactory$o)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$o(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$p(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$o(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$o(tests) { + var checks = convertAll$o(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$o(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$p() { + return true +} + +var unistUtilVisitParents$o = visitParents$o; + + + +var CONTINUE$M = true; +var SKIP$M = 'skip'; +var EXIT$M = false; + +visitParents$o.CONTINUE = CONTINUE$M; +visitParents$o.SKIP = SKIP$M; +visitParents$o.EXIT = EXIT$M; + +function visitParents$o(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$o(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$o(visitor(node, parents)); + + if (result[0] === EXIT$M) { + return result + } + } + + if (node.children && result[0] !== SKIP$M) { + subresult = toResult$o(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$M ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$M) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$o(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$M, value] + } + + return [value] +} + +var unistUtilVisit$o = visit$o; + + + +var CONTINUE$N = unistUtilVisitParents$o.CONTINUE; +var SKIP$N = unistUtilVisitParents$o.SKIP; +var EXIT$N = unistUtilVisitParents$o.EXIT; + +visit$o.CONTINUE = CONTINUE$N; +visit$o.SKIP = SKIP$N; +visit$o.EXIT = EXIT$N; + +function visit$o(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$o(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFinalDefinition = unifiedLintRule('remark-lint:final-definition', finalDefinition); + +var start$c = unistUtilPosition.start; + +function finalDefinition(tree, file) { + var last = null; + + unistUtilVisit$o(tree, visitor, true); + + function visitor(node) { + var line = start$c(node).line; + + // Ignore generated nodes. + if (node.type === 'root' || unistUtilGenerated(node)) { + return + } + + if (node.type === 'definition') { + if (last !== null && last > line) { + file.message( + 'Move definitions to the end of the file (after the node at line `' + + last + + '`)', + node + ); + } + } else if (last === null) { + last = line; + } + } +} + +var convert_1$p = convert$q; + +function convert$q(test) { + if (typeof test === 'string') { + return typeFactory$p(test) + } + + if (test === null || test === undefined) { + return ok$q + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$p : matchesFactory$p)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$p(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$q(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$p(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$p(tests) { + var checks = convertAll$p(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$p(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$q() { + return true +} + +var unistUtilVisitParents$p = visitParents$p; + + + +var CONTINUE$O = true; +var SKIP$O = 'skip'; +var EXIT$O = false; + +visitParents$p.CONTINUE = CONTINUE$O; +visitParents$p.SKIP = SKIP$O; +visitParents$p.EXIT = EXIT$O; + +function visitParents$p(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$p(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$p(visitor(node, parents)); + + if (result[0] === EXIT$O) { + return result + } + } + + if (node.children && result[0] !== SKIP$O) { + subresult = toResult$p(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$O ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$O) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$p(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$O, value] + } + + return [value] +} + +var unistUtilVisit$p = visit$p; + + + +var CONTINUE$P = unistUtilVisitParents$p.CONTINUE; +var SKIP$P = unistUtilVisitParents$p.SKIP; +var EXIT$P = unistUtilVisitParents$p.EXIT; + +visit$p.CONTINUE = CONTINUE$P; +visit$p.SKIP = SKIP$P; +visit$p.EXIT = EXIT$P; + +function visit$p(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$p(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFirstHeadingLevel = unifiedLintRule('remark-lint:first-heading-level', firstHeadingLevel); + +var re$3 = / min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$Q) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$q(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$Q, value] + } + + return [value] +} + +var unistUtilVisit$q = visit$q; + + + +var CONTINUE$R = unistUtilVisitParents$q.CONTINUE; +var SKIP$R = unistUtilVisitParents$q.SKIP; +var EXIT$R = unistUtilVisitParents$q.EXIT; + +visit$q.CONTINUE = CONTINUE$R; +visit$q.SKIP = SKIP$R; +visit$q.EXIT = EXIT$R; + +function visit$q(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$q(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintHeadingStyle = unifiedLintRule('remark-lint:heading-style', headingStyle); + +var types$2 = ['atx', 'atx-closed', 'setext']; + +function headingStyle(tree, file, option) { + var preferred = types$2.indexOf(option) === -1 ? null : option; + + unistUtilVisit$q(tree, 'heading', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node)) { + if (preferred) { + if (mdastUtilHeadingStyle(node, preferred) !== preferred) { + file.message('Headings should use ' + preferred, node); + } + } else { + preferred = mdastUtilHeadingStyle(node, preferred); + } + } + } +} + +var convert_1$r = convert$s; + +function convert$s(test) { + if (typeof test === 'string') { + return typeFactory$r(test) + } + + if (test === null || test === undefined) { + return ok$s + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$r : matchesFactory$r)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$r(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$s(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$r(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$r(tests) { + var checks = convertAll$r(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$r(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$s() { + return true +} + +var unistUtilVisitParents$r = visitParents$r; + + + +var CONTINUE$S = true; +var SKIP$S = 'skip'; +var EXIT$S = false; + +visitParents$r.CONTINUE = CONTINUE$S; +visitParents$r.SKIP = SKIP$S; +visitParents$r.EXIT = EXIT$S; + +function visitParents$r(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$r(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$r(visitor(node, parents)); + + if (result[0] === EXIT$S) { + return result + } + } + + if (node.children && result[0] !== SKIP$S) { + subresult = toResult$r(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$S ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$S) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$r(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$S, value] + } + + return [value] +} + +var unistUtilVisit$r = visit$r; + + + +var CONTINUE$T = unistUtilVisitParents$r.CONTINUE; +var SKIP$T = unistUtilVisitParents$r.SKIP; +var EXIT$T = unistUtilVisitParents$r.EXIT; + +visit$r.CONTINUE = CONTINUE$T; +visit$r.SKIP = SKIP$T; +visit$r.EXIT = EXIT$T; + +function visit$r(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$r(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintMaximumLineLength = unifiedLintRule('remark-lint:maximum-line-length', maximumLineLength); + +var start$d = unistUtilPosition.start; +var end$8 = unistUtilPosition.end; + +function maximumLineLength(tree, file, option) { + var preferred = typeof option === 'number' && !isNaN(option) ? option : 80; + var content = String(file); + var lines = content.split(/\r?\n/); + var length = lines.length; + var index = -1; + var lineLength; + + // Note: JSX is from MDX: . + unistUtilVisit$r(tree, ['heading', 'table', 'code', 'definition', 'html', 'jsx'], ignore); + unistUtilVisit$r(tree, ['link', 'image', 'inlineCode'], inline); + + // Iterate over every line, and warn for violating lines. + while (++index < length) { + lineLength = lines[index].length; + + if (lineLength > preferred) { + file.message('Line must be at most ' + preferred + ' characters', { + line: index + 1, + column: lineLength + 1 + }); + } + } + + // Finally, whitelist some inline spans, but only if they occur at or after + // the wrap. + // However, when they do, and there’s whitespace after it, they are not + // whitelisted. + function inline(node, pos, parent) { + var next = parent.children[pos + 1]; + var initial; + var final; + + /* istanbul ignore if - Nothing to whitelist when generated. */ + if (unistUtilGenerated(node)) { + return + } + + initial = start$d(node); + final = end$8(node); + + // No whitelisting when starting after the border, or ending before it. + if (initial.column > preferred || final.column < preferred) { + return + } + + // No whitelisting when there’s whitespace after the link. + if ( + next && + start$d(next).line === initial.line && + (!next.value || /^(.+?[ \t].+?)/.test(next.value)) + ) { + return + } + + whitelist(initial.line - 1, final.line); + } + + function ignore(node) { + /* istanbul ignore else - Hard to test, as we only run this case on `position: true` */ + if (!unistUtilGenerated(node)) { + whitelist(start$d(node).line - 1, end$8(node).line); + } + } + + // Whitelist from `initial` to `final`, zero-based. + function whitelist(initial, final) { + while (initial < final) { + lines[initial++] = ''; + } + } +} + +var convert_1$s = convert$t; + +function convert$t(test) { + if (typeof test === 'string') { + return typeFactory$s(test) + } + + if (test === null || test === undefined) { + return ok$t + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$s : matchesFactory$s)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$s(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$t(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$s(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$s(tests) { + var checks = convertAll$s(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$s(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$t() { + return true +} + +var unistUtilVisitParents$s = visitParents$s; + + + +var CONTINUE$U = true; +var SKIP$U = 'skip'; +var EXIT$U = false; + +visitParents$s.CONTINUE = CONTINUE$U; +visitParents$s.SKIP = SKIP$U; +visitParents$s.EXIT = EXIT$U; + +function visitParents$s(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$s(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$s(visitor(node, parents)); + + if (result[0] === EXIT$U) { + return result + } + } + + if (node.children && result[0] !== SKIP$U) { + subresult = toResult$s(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$U ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$U) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$s(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$U, value] + } + + return [value] +} + +var unistUtilVisit$s = visit$s; + + + +var CONTINUE$V = unistUtilVisitParents$s.CONTINUE; +var SKIP$V = unistUtilVisitParents$s.SKIP; +var EXIT$V = unistUtilVisitParents$s.EXIT; + +visit$s.CONTINUE = CONTINUE$V; +visit$s.SKIP = SKIP$V; +visit$s.EXIT = EXIT$V; + +function visit$s(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$s(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoConsecutiveBlankLines = unifiedLintRule( + 'remark-lint:no-consecutive-blank-lines', + noConsecutiveBlankLines +); + +function noConsecutiveBlankLines(tree, file) { + unistUtilVisit$s(tree, visitor); + + function visitor(node) { + var children = node.children; + var head; + var tail; + + if (!unistUtilGenerated(node) && children) { + head = children[0]; + + if (head && !unistUtilGenerated(head)) { + // Compare parent and first child. + compare(unistUtilPosition.start(node), unistUtilPosition.start(head), 0); + + // Compare between each child. + children.forEach(visitChild); + + tail = children[children.length - 1]; + + // Compare parent and last child. + if (tail !== head && !unistUtilGenerated(tail)) { + compare(unistUtilPosition.end(node), unistUtilPosition.end(tail), 1); + } + } + } + } + + // Compare the difference between `start` and `end`, and warn when that + // difference exceeds `max`. + function compare(start, end, max) { + var diff = end.line - start.line; + var lines = Math.abs(diff) - max; + var reason; + + if (lines > 0) { + reason = + 'Remove ' + + lines + + ' ' + + pluralize('line', Math.abs(lines)) + + ' ' + + (diff > 0 ? 'before' : 'after') + + ' node'; + + file.message(reason, end); + } + } + + function visitChild(child, index, all) { + var previous = all[index - 1]; + var max = 2; + + if (previous && !unistUtilGenerated(previous) && !unistUtilGenerated(child)) { + if ( + (previous.type === 'list' && child.type === 'list') || + (child.type === 'code' && previous.type === 'list' && !child.lang) + ) { + max++; + } + + compare(unistUtilPosition.end(previous), unistUtilPosition.start(child), max); + } + } +} + +var remarkLintNoFileNameArticles = unifiedLintRule('remark-lint:no-file-name-articles', noFileNameArticles); + +function noFileNameArticles(tree, file) { + var match = file.stem && file.stem.match(/^(the|teh|an?)\b/i); + + if (match) { + file.message('Do not start file names with `' + match[0] + '`'); + } +} + +var remarkLintNoFileNameConsecutiveDashes = unifiedLintRule( + 'remark-lint:no-file-name-consecutive-dashes', + noFileNameConsecutiveDashes +); + +var reason$b = 'Do not use consecutive dashes in a file name'; + +function noFileNameConsecutiveDashes(tree, file) { + if (file.stem && /-{2,}/.test(file.stem)) { + file.message(reason$b); + } +} + +var remarkLintNoFileNameOuterDashes = unifiedLintRule( + 'remark-lint:no-file-name-outer-dashes', + noFileNameOuterDashes +); + +var reason$c = 'Do not use initial or final dashes in a file name'; + +function noFileNameOuterDashes(tree, file) { + if (file.stem && /^-|-$/.test(file.stem)) { + file.message(reason$c); + } +} + +var convert_1$t = convert$u; + +function convert$u(test) { + if (typeof test === 'string') { + return typeFactory$t(test) + } + + if (test === null || test === undefined) { + return ok$u + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$t : matchesFactory$t)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$t(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$u(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$t(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$t(tests) { + var checks = convertAll$t(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$t(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$u() { + return true +} + +var unistUtilVisitParents$t = visitParents$t; + + + +var CONTINUE$W = true; +var SKIP$W = 'skip'; +var EXIT$W = false; + +visitParents$t.CONTINUE = CONTINUE$W; +visitParents$t.SKIP = SKIP$W; +visitParents$t.EXIT = EXIT$W; + +function visitParents$t(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$t(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$t(visitor(node, parents)); + + if (result[0] === EXIT$W) { + return result + } + } + + if (node.children && result[0] !== SKIP$W) { + subresult = toResult$t(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$W ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$W) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$t(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$W, value] + } + + return [value] +} + +var unistUtilVisit$t = visit$t; + + + +var CONTINUE$X = unistUtilVisitParents$t.CONTINUE; +var SKIP$X = unistUtilVisitParents$t.SKIP; +var EXIT$X = unistUtilVisitParents$t.EXIT; + +visit$t.CONTINUE = CONTINUE$X; +visit$t.SKIP = SKIP$X; +visit$t.EXIT = EXIT$X; + +function visit$t(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$t(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoHeadingIndent = unifiedLintRule('remark-lint:no-heading-indent', noHeadingIndent); + +var start$e = unistUtilPosition.start; + +function noHeadingIndent(tree, file) { + var contents = String(file); + var length = contents.length; + + unistUtilVisit$t(tree, 'heading', visitor); + + function visitor(node) { + var initial; + var begin; + var index; + var character; + var diff; + + if (unistUtilGenerated(node)) { + return + } + + initial = start$e(node); + begin = initial.offset; + index = begin - 1; + + while (++index < length) { + character = contents.charAt(index); + + if (character !== ' ' && character !== '\t') { + break + } + } + + diff = index - begin; + + if (diff) { + file.message( + 'Remove ' + diff + ' ' + pluralize('space', diff) + ' before this heading', + { + line: initial.line, + column: initial.column + diff + } + ); + } + } +} + +var convert_1$u = convert$v; + +function convert$v(test) { + if (typeof test === 'string') { + return typeFactory$u(test) + } + + if (test === null || test === undefined) { + return ok$v + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$u : matchesFactory$u)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$u(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$v(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$u(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$u(tests) { + var checks = convertAll$u(tests); + var length = checks.length; - /* istanbul ignore else - just for safety */ - if (character !== ' ' && character !== '\t') { - file.message(reason$1, pos); - break - } + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } } + + return false } } -var remarkLintNoLiteralUrls = unifiedLintRule('remark-lint:no-literal-urls', noLiteralURLs); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$u(test) { + return type -var start$5 = unistUtilPosition.start; -var end$2 = unistUtilPosition.end; -var mailto$3 = 'mailto:'; -var reason$2 = 'Don’t use literal URLs without angle brackets'; + function type(node) { + return Boolean(node && node.type === test) + } +} -function noLiteralURLs(tree, file) { - unistUtilVisit(tree, 'link', visitor); +// Utility to return true. +function ok$v() { + return true +} - function visitor(node) { - var children = node.children; - var value = mdastUtilToString(node); +var unistUtilVisitParents$u = visitParents$u; - if ( - !unistUtilGenerated(node) && - start$5(node).column === start$5(children[0]).column && - end$2(node).column === end$2(children[children.length - 1]).column && - (node.url === mailto$3 + value || node.url === value) - ) { - file.message(reason$2, node); + + +var CONTINUE$Y = true; +var SKIP$Y = 'skip'; +var EXIT$Y = false; + +visitParents$u.CONTINUE = CONTINUE$Y; +visitParents$u.SKIP = SKIP$Y; +visitParents$u.EXIT = EXIT$Y; + +function visitParents$u(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$u(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$u(visitor(node, parents)); + + if (result[0] === EXIT$Y) { + return result + } + } + + if (node.children && result[0] !== SKIP$Y) { + subresult = toResult$u(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$Y ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$Y) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintOrderedListMarkerStyle = unifiedLintRule( - 'remark-lint:ordered-list-marker-style', - orderedListMarkerStyle -); +function toResult$u(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$6 = unistUtilPosition.start; + if (typeof value === 'number') { + return [CONTINUE$Y, value] + } -var styles$1 = { - ')': true, - '.': true, - null: true -}; + return [value] +} -function orderedListMarkerStyle(tree, file, pref) { - var contents = String(file); +var unistUtilVisit$u = visit$u; - pref = typeof pref !== 'string' || pref === 'consistent' ? null : pref; - if (styles$1[pref] !== true) { - file.fail( - 'Invalid ordered list-item marker style `' + - pref + - "`: use either `'.'` or `')'`" - ); + +var CONTINUE$Z = unistUtilVisitParents$u.CONTINUE; +var SKIP$Z = unistUtilVisitParents$u.SKIP; +var EXIT$Z = unistUtilVisitParents$u.EXIT; + +visit$u.CONTINUE = CONTINUE$Z; +visit$u.SKIP = SKIP$Z; +visit$u.EXIT = EXIT$Z; + +function visit$u(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$u(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } +} + +var start$f = unistUtilPosition.start; - unistUtilVisit(tree, 'list', visitor); + + +var remarkLintNoMultipleToplevelHeadings = unifiedLintRule( + 'remark-lint:no-multiple-toplevel-headings', + noMultipleToplevelHeadings +); + +function noMultipleToplevelHeadings(tree, file, option) { + var preferred = option || 1; + var duplicate; + + unistUtilVisit$u(tree, 'heading', visitor); function visitor(node) { - var children = node.children; - var length = node.ordered ? children.length : 0; - var index = -1; - var marker; - var child; + if (!unistUtilGenerated(node) && node.depth === preferred) { + if (duplicate) { + file.message( + 'Don’t use multiple top level headings (' + duplicate + ')', + node + ); + } else { + duplicate = unistUtilStringifyPosition(start$f(node)); + } + } + } +} - while (++index < length) { - child = children[index]; +var convert_1$v = convert$w; - if (!unistUtilGenerated(child)) { - marker = contents - .slice(start$6(child).offset, start$6(child.children[0]).offset) - .replace(/\s|\d/g, '') - .replace(/\[[x ]?]\s*$/i, ''); +function convert$w(test) { + if (typeof test === 'string') { + return typeFactory$v(test) + } - if (pref) { - if (marker !== pref) { - file.message('Marker style should be `' + pref + '`', child); - } - } else { - pref = marker; - } + if (test === null || test === undefined) { + return ok$w + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$v : matchesFactory$v)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$v(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$w(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$v(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false } } + + return true } } -var remarkLintHardBreakSpaces = unifiedLintRule('remark-lint:hard-break-spaces', hardBreakSpaces); +function anyFactory$v(tests) { + var checks = convertAll$v(tests); + var length = checks.length; -var reason$3 = 'Use two spaces for hard line breaks'; + return matches -function hardBreakSpaces(tree, file) { - var contents = String(file); + function matches() { + var index = -1; - unistUtilVisit(tree, 'break', visitor); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } - function visitor(node) { - var value; + return false + } +} - if (!unistUtilGenerated(node)) { - value = contents - .slice(unistUtilPosition.start(node).offset, unistUtilPosition.end(node).offset) - .split('\n', 1)[0] - .replace(/\r$/, ''); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$v(test) { + return type - if (value.length > 2) { - file.message(reason$3, node); + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$w() { + return true +} + +var unistUtilVisitParents$v = visitParents$v; + + + +var CONTINUE$_ = true; +var SKIP$_ = 'skip'; +var EXIT$_ = false; + +visitParents$v.CONTINUE = CONTINUE$_; +visitParents$v.SKIP = SKIP$_; +visitParents$v.EXIT = EXIT$_; + +function visitParents$v(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$v(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$v(visitor(node, parents)); + + if (result[0] === EXIT$_) { + return result + } + } + + if (node.children && result[0] !== SKIP$_) { + subresult = toResult$v(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$_ ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$_) { + return result } + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintNoDuplicateDefinitions = unifiedLintRule( - 'remark-lint:no-duplicate-definitions', - noDuplicateDefinitions -); +function toResult$v(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var reason$4 = 'Do not use definitions with the same identifier'; + if (typeof value === 'number') { + return [CONTINUE$_, value] + } -function noDuplicateDefinitions(tree, file) { - var map = {}; + return [value] +} - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], validate); +var unistUtilVisit$v = visit$v; - function validate(node) { - var identifier; - var duplicate; - if (!unistUtilGenerated(node)) { - identifier = node.identifier; - duplicate = map[identifier]; - if (duplicate && duplicate.type) { - file.message( - reason$4 + ' (' + unistUtilStringifyPosition(unistUtilPosition.start(duplicate)) + ')', - node - ); +var CONTINUE$$ = unistUtilVisitParents$v.CONTINUE; +var SKIP$$ = unistUtilVisitParents$v.SKIP; +var EXIT$$ = unistUtilVisitParents$v.EXIT; + +visit$v.CONTINUE = CONTINUE$$; +visit$v.SKIP = SKIP$$; +visit$v.EXIT = EXIT$$; + +function visit$v(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$v(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShellDollars = unifiedLintRule('remark-lint:no-shell-dollars', noShellDollars); + +var reason$d = 'Do not use dollar signs before shell commands'; + +// List of shell script file extensions (also used as code flags for syntax +// highlighting on GitHub): +// See: +var flags = [ + 'sh', + 'bash', + 'bats', + 'cgi', + 'command', + 'fcgi', + 'ksh', + 'tmux', + 'tool', + 'zsh' +]; + +function noShellDollars(tree, file) { + unistUtilVisit$v(tree, 'code', visitor); + + function visitor(node) { + var lines; + var line; + var length; + var index; + + // Check both known shell code and unknown code. + if (!unistUtilGenerated(node) && node.lang && flags.indexOf(node.lang) !== -1) { + lines = node.value.split('\n'); + length = lines.length; + index = -1; + + if (length <= 1) { + return } - map[identifier] = node; + while (++index < length) { + line = lines[index]; + + if (line.trim() && !line.match(/^\s*\$\s*/)) { + return + } + } + + file.message(reason$d, node); } } } -var mdastUtilHeadingStyle = style; +var convert_1$w = convert$x; -function style(node, relative) { - var last = node.children[node.children.length - 1]; - var depth = node.depth; - var pos = node && node.position && node.position.end; - var final = last && last.position && last.position.end; +function convert$x(test) { + if (typeof test === 'string') { + return typeFactory$w(test) + } - if (!pos) { - return null + if (test === null || test === undefined) { + return ok$x } - // This can only occur for `'atx'` and `'atx-closed'` headings. - // This might incorrectly match `'atx'` headings with lots of trailing white - // space as an `'atx-closed'` heading. - if (!last) { - if (pos.column - 1 <= depth * 2) { - return consolidate(depth, relative) + if (typeof test === 'object') { + return ('length' in test ? anyFactory$w : matchesFactory$w)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$w(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$x(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$w(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } } - return 'atx-closed' + return true } +} - if (final.line + 1 === pos.line) { - return 'setext' +function anyFactory$w(tests) { + var checks = convertAll$w(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false } +} - if (final.column + depth < pos.column) { - return 'atx-closed' +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$w(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) } +} - return consolidate(depth, relative) +// Utility to return true. +function ok$x() { + return true } -// Get the probable style of an atx-heading, depending on preferred style. -function consolidate(depth, relative) { - return depth < 3 - ? 'atx' - : relative === 'atx' || relative === 'setext' - ? relative - : null +var unistUtilVisitParents$w = visitParents$w; + + + +var CONTINUE$10 = true; +var SKIP$10 = 'skip'; +var EXIT$10 = false; + +visitParents$w.CONTINUE = CONTINUE$10; +visitParents$w.SKIP = SKIP$10; +visitParents$w.EXIT = EXIT$10; + +function visitParents$w(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$w(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$w(visitor(node, parents)); + + if (result[0] === EXIT$10) { + return result + } + } + + if (node.children && result[0] !== SKIP$10) { + subresult = toResult$w(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$10 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$10) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } } -var remarkLintNoHeadingContentIndent = unifiedLintRule( - 'remark-lint:no-heading-content-indent', - noHeadingContentIndent -); +function toResult$w(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$7 = unistUtilPosition.start; -var end$3 = unistUtilPosition.end; + if (typeof value === 'number') { + return [CONTINUE$10, value] + } -function noHeadingContentIndent(tree, file) { - var contents = String(file); + return [value] +} - unistUtilVisit(tree, 'heading', visitor); +var unistUtilVisit$w = visit$w; - function visitor(node) { - var depth; - var children; - var type; - var head; - var initial; - var final; - var diff; - var index; - var char; - var reason; - if (unistUtilGenerated(node)) { - return - } - depth = node.depth; - children = node.children; - type = mdastUtilHeadingStyle(node, 'atx'); +var CONTINUE$11 = unistUtilVisitParents$w.CONTINUE; +var SKIP$11 = unistUtilVisitParents$w.SKIP; +var EXIT$11 = unistUtilVisitParents$w.EXIT; - if (type === 'atx' || type === 'atx-closed') { - initial = start$7(node); - index = initial.offset; - char = contents.charAt(index); +visit$w.CONTINUE = CONTINUE$11; +visit$w.SKIP = SKIP$11; +visit$w.EXIT = EXIT$11; - while (char && char !== '#') { - char = contents.charAt(++index); - } +function visit$w(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - /* istanbul ignore if - CR/LF bug: remarkjs/remark#195. */ - if (!char) { - return - } + unistUtilVisitParents$w(tree, test, overload, reverse); - index = depth + (index - initial.offset); - head = start$7(children[0]).column; + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} - // Ignore empty headings. - if (!head) { - return - } +var remarkLintNoTableIndentation = unifiedLintRule('remark-lint:no-table-indentation', noTableIndentation); - diff = head - initial.column - 1 - index; +var reason$e = 'Do not indent table rows'; - if (diff) { - reason = - (diff > 0 ? 'Remove' : 'Add') + - ' ' + - Math.abs(diff) + - ' ' + - plur('space', diff) + - ' before this heading’s content'; +function noTableIndentation(tree, file) { + var contents = String(file); - file.message(reason, start$7(children[0])); - } + unistUtilVisit$w(tree, 'table', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node)) { + node.children.forEach(each); } - // Closed ATX-heading always must have a space between their content and the - // final hashes, thus, there is no `add x spaces`. - if (type === 'atx-closed') { - final = end$3(children[children.length - 1]); - diff = end$3(node).column - final.column - 1 - depth; + return unistUtilVisit$w.SKIP + } - if (diff) { - reason = - 'Remove ' + - diff + - ' ' + - plur('space', diff) + - ' after this heading’s content'; + function each(row) { + var fence = contents.slice( + unistUtilPosition.start(row).offset, + unistUtilPosition.start(row.children[0]).offset + ); - file.message(reason, final); - } + if (fence.indexOf('|') > 1) { + file.message(reason$e, row); } } } -var remarkLintNoInlinePadding = unifiedLintRule('remark-lint:no-inline-padding', noInlinePadding); - -function noInlinePadding(tree, file) { - unistUtilVisit(tree, ['emphasis', 'strong', 'delete', 'image', 'link'], visitor); - - function visitor(node) { - var contents; +var vfileLocation$6 = factory$e; - if (!unistUtilGenerated(node)) { - contents = mdastUtilToString(node); +function factory$e(file) { + var contents = indices$6(String(file)); - if ( - contents.charAt(0) === ' ' || - contents.charAt(contents.length - 1) === ' ' - ) { - file.message('Don’t pad `' + node.type + '` with inner spaces', node); - } - } + return { + toPosition: offsetToPositionFactory$6(contents), + toOffset: positionToOffsetFactory$6(contents) } } -var remarkLintNoShortcutReferenceImage = unifiedLintRule( - 'remark-lint:no-shortcut-reference-image', - noShortcutReferenceImage -); +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$6(indices) { + return offsetToPosition -var reason$5 = 'Use the trailing [] on reference images'; + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; -function noShortcutReferenceImage(tree, file) { - unistUtilVisit(tree, 'imageReference', visitor); + if (offset < 0) { + return {} + } - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$5, node); + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } } + + return {} } } -var remarkLintNoShortcutReferenceLink = unifiedLintRule( - 'remark-lint:no-shortcut-reference-link', - noShortcutReferenceLink -); - -var reason$6 = 'Use the trailing [] on reference links'; +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$6(indices) { + return positionToOffset -function noShortcutReferenceLink(tree, file) { - unistUtilVisit(tree, 'linkReference', visitor); + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$6, node); + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 } + + return -1 } } -var remarkLintNoUndefinedReferences = unifiedLintRule( - 'remark-lint:no-undefined-references', - noUndefinedReferences -); +// Get indices of line-breaks in `value`. +function indices$6(value) { + var result = []; + var index = value.indexOf('\n'); -var reason$7 = 'Found reference to undefined definition'; + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } -// The identifier is upcased to avoid naming collisions with properties -// inherited from `Object.prototype`. Were `Object.create(null)` to be -// used in place of `{}`, downcasing would work equally well. -function normalize$3(s) { - return collapseWhiteSpace(s.toUpperCase()) + result.push(value.length + 1); + + return result } -function noUndefinedReferences(tree, file, pref) { - var allow = - pref != null && Array.isArray(pref.allow) ? pref.allow.map(normalize$3) : []; +var remarkLintNoTabs = unifiedLintRule('remark-lint:no-tabs', noTabs); - var map = {}; +var reason$f = 'Use spaces instead of tabs'; - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], mark); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], find); +function noTabs(tree, file) { + var content = String(file); + var position = vfileLocation$6(file).toPosition; + var index = content.indexOf('\t'); - function mark(node) { - if (!unistUtilGenerated(node)) { - map[normalize$3(node.identifier)] = true; - } + while (index !== -1) { + file.message(reason$f, position(index)); + index = content.indexOf('\t', index + 1); } +} - function find(node) { - if ( - !( - unistUtilGenerated(node) || - allow.includes(normalize$3(node.identifier)) || - normalize$3(node.identifier) in map - ) - ) { - file.message(reason$7, node); +var remarkLintNoTrailingSpaces = unifiedLintRule('remark-lint:no-trailing-spaces', noTrailingSpaces); + +/** + * Lines that are just space characters are not present in + * the AST, which is why we loop through lines manually. + */ + +function noTrailingSpaces(ast, file) { + var lines = file.toString().split(/\r?\n/); + for (var i = 0; i < lines.length; i++) { + var currentLine = lines[i]; + var lineIndex = i + 1; + if (/\s$/.test(currentLine)) { + file.message('Remove trailing whitespace', { + position: { + start: { line: lineIndex, column: currentLine.length + 1 }, + end: { line: lineIndex } + } + }); } } } -var remarkLintNoUnusedDefinitions = unifiedLintRule('remark-lint:no-unused-definitions', noUnusedDefinitions); - -var reason$8 = 'Found unused definition'; - -function noUnusedDefinitions(tree, file) { - var map = {}; - var identifier; - var entry; +var escapeStringRegexp$1 = string => { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], find); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], mark); + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a \unnnn escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +}; - for (identifier in map) { - entry = map[identifier]; +var convert_1$x = convert$y; - if (!entry.used) { - file.message(reason$8, entry.node); - } +function convert$y(test) { + if (typeof test === 'string') { + return typeFactory$x(test) } - function find(node) { - if (!unistUtilGenerated(node)) { - map[node.identifier.toUpperCase()] = {node: node, used: false}; - } + if (test === null || test === undefined) { + return ok$y } - function mark(node) { - var info = map[node.identifier.toUpperCase()]; + if (typeof test === 'object') { + return ('length' in test ? anyFactory$x : matchesFactory$x)(test) + } - if (!unistUtilGenerated(node) && info) { - info.used = true; - } + if (typeof test === 'function') { + return test } -} -var plugins$1 = [ - remarkLint, - // Unix compatibility. - remarkLintFinalNewline, - // Rendering across vendors differs greatly if using other styles. - remarkLintListItemBulletIndent, - [remarkLintListItemIndent, 'tab-size'], - // Differs or unsupported across vendors. - remarkLintNoAutoLinkWithoutProtocol, - remarkLintNoBlockquoteWithoutMarker, - remarkLintNoLiteralUrls, - [remarkLintOrderedListMarkerStyle, '.'], - // Mistakes. - remarkLintHardBreakSpaces, - remarkLintNoDuplicateDefinitions, - remarkLintNoHeadingContentIndent, - remarkLintNoInlinePadding, - remarkLintNoShortcutReferenceImage, - remarkLintNoShortcutReferenceLink, - remarkLintNoUndefinedReferences, - remarkLintNoUnusedDefinitions -]; + throw new Error('Expected function, string, or object as test') +} -var remarkPresetLintRecommended = { - plugins: plugins$1 -}; +function convertAll$x(tests) { + var results = []; + var length = tests.length; + var index = -1; -var remarkLintBlockquoteIndentation = unifiedLintRule( - 'remark-lint:blockquote-indentation', - blockquoteIndentation -); + while (++index < length) { + results[index] = convert$y(tests[index]); + } -function blockquoteIndentation(tree, file, pref) { - pref = typeof pref === 'number' && !isNaN(pref) ? pref : null; + return results +} - unistUtilVisit(tree, 'blockquote', visitor); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$x(test) { + return matches - function visitor(node) { - var diff; - var reason; + function matches(node) { + var key; - if (unistUtilGenerated(node) || node.children.length === 0) { - return + for (key in test) { + if (node[key] !== test[key]) { + return false + } } - if (pref) { - diff = pref - check$3(node); + return true + } +} - if (diff !== 0) { - reason = - (diff > 0 ? 'Add' : 'Remove') + - ' ' + - Math.abs(diff) + - ' ' + - plur('space', diff) + - ' between blockquote and content'; +function anyFactory$x(tests) { + var checks = convertAll$x(tests); + var length = checks.length; - file.message(reason, unistUtilPosition.start(node.children[0])); + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } - } else { - pref = check$3(node); } + + return false } } -function check$3(node) { - var head = node.children[0]; - var indentation = unistUtilPosition.start(head).column - unistUtilPosition.start(node).column; - var padding = mdastUtilToString(head).match(/^ +/); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$x(test) { + return type - if (padding) { - indentation += padding[0].length; + function type(node) { + return Boolean(node && node.type === test) } +} - return indentation +// Utility to return true. +function ok$y() { + return true } -var remarkLintCheckboxCharacterStyle = unifiedLintRule( - 'remark-lint:checkbox-character-style', - checkboxCharacterStyle -); +var unistUtilVisitParents$x = visitParents$x; -var start$8 = unistUtilPosition.start; -var end$4 = unistUtilPosition.end; -var checked = {x: true, X: true}; -var unchecked = {' ': true, '\t': true}; -var types$1 = {true: 'checked', false: 'unchecked'}; -function checkboxCharacterStyle(tree, file, pref) { - var contents = String(file); - var location = vfileLocation(file); +var CONTINUE$12 = true; +var SKIP$12 = 'skip'; +var EXIT$12 = false; - pref = typeof pref === 'object' ? pref : {}; +visitParents$x.CONTINUE = CONTINUE$12; +visitParents$x.SKIP = SKIP$12; +visitParents$x.EXIT = EXIT$12; - if (pref.unchecked && unchecked[pref.unchecked] !== true) { - file.fail( - 'Invalid unchecked checkbox marker `' + - pref.unchecked + - "`: use either `'\\t'`, or `' '`" - ); - } +function visitParents$x(tree, test, visitor, reverse) { + var is; - if (pref.checked && checked[pref.checked] !== true) { - file.fail( - 'Invalid checked checkbox marker `' + - pref.checked + - "`: use either `'x'`, or `'X'`" - ); + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - unistUtilVisit(tree, 'listItem', visitor); + is = convert_1$x(test); - function visitor(node) { - var type; - var initial; - var final; - var value; - var style; - var character; - var reason; + one(tree, null, []); - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$x(visitor(node, parents)); + + if (result[0] === EXIT$12) { + return result + } } - type = types$1[node.checked]; - initial = start$8(node).offset; - final = (node.children.length === 0 ? end$4(node) : start$8(node.children[0])) - .offset; + if (node.children && result[0] !== SKIP$12) { + subresult = toResult$x(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$12 ? subresult : result + } - // For a checkbox to be parsed, it must be followed by a whitespace. - value = contents - .slice(initial, final) - .trimRight() - .slice(0, -1); + return result + } - // The checkbox character is behind a square bracket. - character = value.charAt(value.length - 1); - style = pref[type]; + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; - if (style) { - if (character !== style) { - reason = - type.charAt(0).toUpperCase() + - type.slice(1) + - ' checkboxes should use `' + - style + - '` as a marker'; + while (index > min && index < children.length) { + result = one(children[index], index, parents); - file.message(reason, { - start: location.toPosition(initial + value.length - 1), - end: location.toPosition(initial + value.length) - }); + if (result[0] === EXIT$12) { + return result } - } else { - pref[type] = character; + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintCheckboxContentIndent = unifiedLintRule( - 'remark-lint:checkbox-content-indent', - checkboxContentIndent -); +function toResult$x(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$9 = unistUtilPosition.start; -var end$5 = unistUtilPosition.end; + if (typeof value === 'number') { + return [CONTINUE$12, value] + } -var reason$9 = 'Checkboxes should be followed by a single character'; + return [value] +} -function checkboxContentIndent(tree, file) { - var contents = String(file); - var location = vfileLocation(file); +var unistUtilVisit$x = visit$x; - unistUtilVisit(tree, 'listItem', visitor); - function visitor(node) { - var initial; - var final; - var value; - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return - } +var CONTINUE$13 = unistUtilVisitParents$x.CONTINUE; +var SKIP$13 = unistUtilVisitParents$x.SKIP; +var EXIT$13 = unistUtilVisitParents$x.EXIT; - initial = start$9(node).offset; - /* istanbul ignore next - hard to test, couldn’t find a case. */ - final = (node.children.length === 0 ? end$5(node) : start$9(node.children[0])) - .offset; +visit$x.CONTINUE = CONTINUE$13; +visit$x.SKIP = SKIP$13; +visit$x.EXIT = EXIT$13; - while (/[^\S\n]/.test(contents.charAt(final))) { - final++; - } +function visit$x(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - // For a checkbox to be parsed, it must be followed by a whitespace. - value = contents.slice(initial, final); - value = value.slice(value.indexOf(']') + 1); + unistUtilVisitParents$x(tree, test, overload, reverse); - if (value.length !== 1) { - file.message(reason$9, { - start: location.toPosition(final - value.length + 1), - end: location.toPosition(final) - }); - } + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintCodeBlockStyle = unifiedLintRule('remark-lint:code-block-style', codeBlockStyle); - -var start$a = unistUtilPosition.start; -var end$6 = unistUtilPosition.end; - -var styles$2 = {null: true, fenced: true, indented: true}; - -function codeBlockStyle(tree, file, pref) { - var contents = String(file); +var vfileLocation$7 = factory$f; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; +function factory$f(file) { + var contents = indices$7(String(file)); - if (styles$2[pref] !== true) { - file.fail( - 'Invalid code block style `' + - pref + - "`: use either `'consistent'`, `'fenced'`, or `'indented'`" - ); + return { + toPosition: offsetToPositionFactory$7(contents), + toOffset: positionToOffsetFactory$7(contents) } +} - unistUtilVisit(tree, 'code', visitor); +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$7(indices) { + return offsetToPosition - function visitor(node) { - var current = check(node); + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; - if (current) { - if (!pref) { - pref = current; - } else if (pref !== current) { - file.message('Code blocks should be ' + pref, node); + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } } } + + return {} } +} - // Get the style of `node`. - function check(node) { - var initial = start$a(node).offset; - var final = end$6(node).offset; +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$7(indices) { + return positionToOffset - if (unistUtilGenerated(node)) { - return null + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 } - return node.lang || /^\s*([~`])\1{2,}/.test(contents.slice(initial, final)) - ? 'fenced' - : 'indented' + return -1 } } -var remarkLintDefinitionSpacing = unifiedLintRule('remark-lint:definition-spacing', definitionSpacing); +// Get indices of line-breaks in `value`. +function indices$7(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); -var label$1 = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; -var reason$a = 'Do not use consecutive white-space in definition labels'; + return result +} -function definitionSpacing(tree, file) { - var contents = String(file); +const start$g = unistUtilPosition.start; - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], validate); +var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); - function validate(node) { - var start = unistUtilPosition.start(node).offset; - var end = unistUtilPosition.end(node).offset; +function testProhibited (val, content) { + let regexpFlags = 'g'; - if ( - !unistUtilGenerated(node) && - /[ \t\n]{2,}/.test(contents.slice(start, end).match(label$1)[1]) - ) { - file.message(reason$a, node); - } + if (!val.no) { + val.no = escapeStringRegexp$1(val.yes); + regexpFlags += 'i'; } -} -var remarkLintFencedCodeFlag = unifiedLintRule('remark-lint:fenced-code-flag', fencedCodeFlag); + let regexpString = '(? { + const results = testProhibited(val, content); + if (results.length) { + results.forEach(({ result, index }) => { + const message = val.yes ? `Use "${val.yes}" instead of "${result}"` : `Do not use "${result}"`; + file.message(message, { + start: location.toPosition(initial + index), + end: location.toPosition(initial + index + [...result].length) + }); + }); } - } + }); } } -var remarkLintFencedCodeMarker = unifiedLintRule('remark-lint:fenced-code-marker', fencedCodeMarker); - -var markers = { - '`': true, - '~': true, - null: true -}; +var convert_1$y = convert$z; -function fencedCodeMarker(tree, file, pref) { - var contents = String(file); +function convert$z(test) { + if (typeof test === 'string') { + return typeFactory$y(test) + } - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; + if (test === null || test === undefined) { + return ok$z + } - if (markers[pref] !== true) { - file.fail( - 'Invalid fenced code marker `' + - pref + - "`: use either `'consistent'`, `` '`' ``, or `'~'`" - ); + if (typeof test === 'object') { + return ('length' in test ? anyFactory$y : matchesFactory$y)(test) } - unistUtilVisit(tree, 'code', visitor); + if (typeof test === 'function') { + return test + } - function visitor(node) { - var marker; + throw new Error('Expected function, string, or object as test') +} - if (!unistUtilGenerated(node)) { - marker = contents - .substr(unistUtilPosition.start(node).offset, 4) - .trimLeft() - .charAt(0); +function convertAll$y(tests) { + var results = []; + var length = tests.length; + var index = -1; - // Ignore unfenced code blocks. - if (markers[marker] === true) { - if (pref) { - if (marker !== pref) { - file.message( - 'Fenced code should use ' + pref + ' as a marker', - node - ); - } - } else { - pref = marker; - } - } - } + while (++index < length) { + results[index] = convert$z(tests[index]); } + + return results } -var remarkLintFileExtension = unifiedLintRule('remark-lint:file-extension', fileExtension); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$y(test) { + return matches -function fileExtension(tree, file, pref) { - var ext = file.extname; + function matches(node) { + var key; - pref = typeof pref === 'string' ? pref : 'md'; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } - if (ext && ext.slice(1) !== pref) { - file.message('Invalid extension: use `' + pref + '`'); + return true } } -var remarkLintFinalDefinition = unifiedLintRule('remark-lint:final-definition', finalDefinition); +function anyFactory$y(tests) { + var checks = convertAll$y(tests); + var length = checks.length; -var start$c = unistUtilPosition.start; + return matches -function finalDefinition(tree, file) { - var last = null; + function matches() { + var index = -1; - unistUtilVisit(tree, visitor, true); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } - function visitor(node) { - var line = start$c(node).line; + return false + } +} - // Ignore generated nodes. - if (node.type === 'root' || unistUtilGenerated(node)) { - return - } +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$y(test) { + return type - if (node.type === 'definition') { - if (last !== null && last > line) { - file.message( - 'Move definitions to the end of the file (after the node at line `' + - last + - '`)', - node - ); - } - } else if (last === null) { - last = line; - } + function type(node) { + return Boolean(node && node.type === test) } } -var remarkLintFirstHeadingLevel = unifiedLintRule('remark-lint:first-heading-level', firstHeadingLevel); +// Utility to return true. +function ok$z() { + return true +} -var re$3 = /. - unistUtilVisit(tree, ['heading', 'table', 'code', 'definition', 'html', 'jsx'], ignore); - unistUtilVisit(tree, ['link', 'image', 'inlineCode'], inline); + while (index > min && index < children.length) { + result = one(children[index], index, parents); - // Iterate over every line, and warn for violating lines. - while (++index < length) { - lineLength = lines[index].length; + if (result[0] === EXIT$14) { + return result + } - if (lineLength > style) { - file.message('Line must be at most ' + style + ' characters', { - line: index + 1, - column: lineLength + 1 - }); + index = typeof result[1] === 'number' ? result[1] : index + step; } } +} - // Finally, whitelist some inline spans, but only if they occur at or after - // the wrap. - // However, when they do, and there’s whitespace after it, they are not - // whitelisted. - function inline(node, pos, parent) { - var next = parent.children[pos + 1]; - var initial; - var final; +function toResult$y(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } - /* istanbul ignore if - Nothing to whitelist when generated. */ - if (unistUtilGenerated(node)) { - return - } + if (typeof value === 'number') { + return [CONTINUE$14, value] + } - initial = start$d(node); - final = end$8(node); + return [value] +} - // No whitelisting when starting after the border, or ending before it. - if (initial.column > style || final.column < style) { - return - } +var unistUtilVisit$y = visit$y; - // No whitelisting when there’s whitespace after the link. - if ( - next && - start$d(next).line === initial.line && - (!next.value || /^(.+?[ \t].+?)/.test(next.value)) - ) { - return - } - whitelist(initial.line - 1, final.line); - } - function ignore(node) { - /* istanbul ignore else - Hard to test, as we only run this case on `position: true` */ - if (!unistUtilGenerated(node)) { - whitelist(start$d(node).line - 1, end$8(node).line); - } +var CONTINUE$15 = unistUtilVisitParents$y.CONTINUE; +var SKIP$15 = unistUtilVisitParents$y.SKIP; +var EXIT$15 = unistUtilVisitParents$y.EXIT; + +visit$y.CONTINUE = CONTINUE$15; +visit$y.SKIP = SKIP$15; +visit$y.EXIT = EXIT$15; + +function visit$y(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - // Whitelist from `initial` to `final`, zero-based. - function whitelist(initial, final) { - while (initial < final) { - lines[initial++] = ''; - } + unistUtilVisitParents$y(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintNoConsecutiveBlankLines = unifiedLintRule( - 'remark-lint:no-consecutive-blank-lines', - noConsecutiveBlankLines -); +var rule = unifiedLintRule; -function noConsecutiveBlankLines(tree, file) { - unistUtilVisit(tree, visitor); - function visitor(node) { - var children = node.children; - var head; - var tail; - if (!unistUtilGenerated(node) && children) { - head = children[0]; - if (head && !unistUtilGenerated(head)) { - // Compare parent and first child. - compare(unistUtilPosition.start(node), unistUtilPosition.start(head), 0); +var remarkLintRuleStyle = rule('remark-lint:rule-style', ruleStyle); - // Compare between each child. - children.forEach(visitChild); +var start$h = unistUtilPosition.start; +var end$9 = unistUtilPosition.end; - tail = children[children.length - 1]; +function ruleStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - // Compare parent and last child. - if (tail !== head && !unistUtilGenerated(tail)) { - compare(unistUtilPosition.end(node), unistUtilPosition.end(tail), 1); - } - } - } + if (preferred !== null && /[^-_* ]/.test(preferred)) { + file.fail( + "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" + ); } - // Compare the difference between `start` and `end`, and warn when that - // difference exceeds `max`. - function compare(start, end, max) { - var diff = end.line - start.line; - var lines = Math.abs(diff) - max; - var reason; - - if (lines > 0) { - reason = - 'Remove ' + - lines + - ' ' + - plur('line', lines) + - ' ' + - (diff > 0 ? 'before' : 'after') + - ' node'; + unistUtilVisit$y(tree, 'thematicBreak', visitor); - file.message(reason, end); - } - } + function visitor(node) { + var initial = start$h(node).offset; + var final = end$9(node).offset; + var rule; - function visitChild(child, index, all) { - var prev = all[index - 1]; - var max = 2; + if (!unistUtilGenerated(node)) { + rule = contents.slice(initial, final); - if (prev && !unistUtilGenerated(prev) && !unistUtilGenerated(child)) { - if ( - (prev.type === 'list' && child.type === 'list') || - (child.type === 'code' && prev.type === 'list' && !child.lang) - ) { - max++; + if (preferred) { + if (rule !== preferred) { + file.message('Rules should use `' + preferred + '`', node); + } + } else { + preferred = rule; } - - compare(unistUtilPosition.end(prev), unistUtilPosition.start(child), max); } } } -var remarkLintNoFileNameArticles = unifiedLintRule('remark-lint:no-file-name-articles', noFileNameArticles); - -function noFileNameArticles(tree, file) { - var match = file.stem && file.stem.match(/^(the|teh|an?)\b/i); +var convert_1$z = convert$A; - if (match) { - file.message('Do not start file names with `' + match[0] + '`'); +function convert$A(test) { + if (typeof test === 'string') { + return typeFactory$z(test) } -} -var remarkLintNoFileNameConsecutiveDashes = unifiedLintRule( - 'remark-lint:no-file-name-consecutive-dashes', - noFileNameConsecutiveDashes -); + if (test === null || test === undefined) { + return ok$A + } -var reason$b = 'Do not use consecutive dashes in a file name'; + if (typeof test === 'object') { + return ('length' in test ? anyFactory$z : matchesFactory$z)(test) + } -function noFileNameConsecutiveDashes(tree, file) { - if (file.stem && /-{2,}/.test(file.stem)) { - file.message(reason$b); + if (typeof test === 'function') { + return test } -} -var remarkLintNoFileNameOuterDashes = unifiedLintRule( - 'remark-lint:no-file-name-outer-dashes', - noFileNameOuterDashes -); + throw new Error('Expected function, string, or object as test') +} -var reason$c = 'Do not use initial or final dashes in a file name'; +function convertAll$z(tests) { + var results = []; + var length = tests.length; + var index = -1; -function noFileNameOuterDashes(tree, file) { - if (file.stem && /^-|-$/.test(file.stem)) { - file.message(reason$c); + while (++index < length) { + results[index] = convert$A(tests[index]); } + + return results } -var remarkLintNoHeadingIndent = unifiedLintRule('remark-lint:no-heading-indent', noHeadingIndent); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$z(test) { + return matches -var start$e = unistUtilPosition.start; + function matches(node) { + var key; -function noHeadingIndent(tree, file) { - var contents = String(file); - var length = contents.length; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } - unistUtilVisit(tree, 'heading', visitor); + return true + } +} - function visitor(node) { - var initial; - var begin; - var index; - var character; - var diff; +function anyFactory$z(tests) { + var checks = convertAll$z(tests); + var length = checks.length; - if (unistUtilGenerated(node)) { - return - } + return matches - initial = start$e(node); - begin = initial.offset; - index = begin - 1; + function matches() { + var index = -1; while (++index < length) { - character = contents.charAt(index); - - if (character !== ' ' && character !== '\t') { - break + if (checks[index].apply(this, arguments)) { + return true } } - diff = index - begin; + return false + } +} - if (diff) { - file.message( - 'Remove ' + diff + ' ' + plur('space', diff) + ' before this heading', - { - line: initial.line, - column: initial.column + diff - } - ); - } +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$z(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) } } -var start$f = unistUtilPosition.start; +// Utility to return true. +function ok$A() { + return true +} +var unistUtilVisitParents$z = visitParents$z; -var remarkLintNoMultipleToplevelHeadings = unifiedLintRule( - 'remark-lint:no-multiple-toplevel-headings', - noMultipleToplevelHeadings -); -function noMultipleToplevelHeadings(tree, file, pref) { - var style = pref ? pref : 1; - var duplicate; +var CONTINUE$16 = true; +var SKIP$16 = 'skip'; +var EXIT$16 = false; - unistUtilVisit(tree, 'heading', visitor); +visitParents$z.CONTINUE = CONTINUE$16; +visitParents$z.SKIP = SKIP$16; +visitParents$z.EXIT = EXIT$16; - function visitor(node) { - if (!unistUtilGenerated(node) && node.depth === style) { - if (duplicate) { - file.message( - 'Don’t use multiple top level headings (' + duplicate + ')', - node - ); - } else { - duplicate = unistUtilStringifyPosition(start$f(node)); - } - } +function visitParents$z(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } -} -var remarkLintNoShellDollars = unifiedLintRule('remark-lint:no-shell-dollars', noShellDollars); + is = convert_1$z(test); -var reason$d = 'Do not use dollar signs before shell-commands'; + one(tree, null, []); -// List of shell script file extensions (also used as code flags for syntax -// highlighting on GitHub): -// See: -var flags = [ - 'sh', - 'bash', - 'bats', - 'cgi', - 'command', - 'fcgi', - 'ksh', - 'tmux', - 'tool', - 'zsh' -]; + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; -function noShellDollars(tree, file) { - unistUtilVisit(tree, 'code', visitor); + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$z(visitor(node, parents)); - function visitor(node) { - var lines; - var line; - var length; - var index; + if (result[0] === EXIT$16) { + return result + } + } - // Check both known shell code and unknown code. - if (!unistUtilGenerated(node) && node.lang && flags.indexOf(node.lang) !== -1) { - lines = node.value.split('\n'); - length = lines.length; - index = -1; + if (node.children && result[0] !== SKIP$16) { + subresult = toResult$z(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$16 ? subresult : result + } - if (length <= 1) { - return - } + return result + } - while (++index < length) { - line = lines[index]; + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; - if (line.trim() && !line.match(/^\s*\$\s*/)) { - return - } + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$16) { + return result } - file.message(reason$d, node); + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintNoTableIndentation = unifiedLintRule('remark-lint:no-table-indentation', noTableIndentation); +function toResult$z(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var reason$e = 'Do not indent table rows'; + if (typeof value === 'number') { + return [CONTINUE$16, value] + } -function noTableIndentation(tree, file) { - var contents = String(file); + return [value] +} - unistUtilVisit(tree, 'table', visitor); +var unistUtilVisit$z = visit$z; - function visitor(node) { - if (!unistUtilGenerated(node)) { - node.children.forEach(each); - } - return unistUtilVisit.SKIP + +var CONTINUE$17 = unistUtilVisitParents$z.CONTINUE; +var SKIP$17 = unistUtilVisitParents$z.SKIP; +var EXIT$17 = unistUtilVisitParents$z.EXIT; + +visit$z.CONTINUE = CONTINUE$17; +visit$z.SKIP = SKIP$17; +visit$z.EXIT = EXIT$17; + +function visit$z(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - function each(row) { - var fence = contents.slice( - unistUtilPosition.start(row).offset, - unistUtilPosition.start(row.children[0]).offset - ); + unistUtilVisitParents$z(tree, test, overload, reverse); - if (fence.indexOf('|') > 1) { - file.message(reason$e, row); - } + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintNoTabs = unifiedLintRule('remark-lint:no-tabs', noTabs); +var remarkLintStrongMarker = unifiedLintRule('remark-lint:strong-marker', strongMarker); -var reason$f = 'Use spaces instead of hard-tabs'; +var markers$1 = {'*': true, _: true, null: true}; -function noTabs(tree, file) { - var content = String(file); - var position = vfileLocation(file).toPosition; - var index = content.indexOf('\t'); +function strongMarker(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - while (index !== -1) { - file.message(reason$f, position(index)); - index = content.indexOf('\t', index + 1); + if (markers$1[preferred] !== true) { + file.fail( + 'Incorrect strong marker `' + + preferred + + "`: use either `'consistent'`, `'*'`, or `'_'`" + ); } -} -var remarkLintNoTrailingSpaces = unifiedLintRule('remark-lint:no-trailing-spaces', noTrailingSpaces); + unistUtilVisit$z(tree, 'strong', visitor); -/** - * Lines that are just space characters are not present in - * the AST, which is why we loop through lines manually. - */ + function visitor(node) { + var marker = contents.charAt(unistUtilPosition.start(node).offset); -function noTrailingSpaces(ast, file) { - var lines = file.toString().split(/\r?\n/); - for (var i = 0; i < lines.length; i++) { - var currentLine = lines[i]; - var lineIndex = i + 1; - if (/\s$/.test(currentLine)) { - file.message('Remove trailing whitespace', { - position: { - start: { line: lineIndex, column: currentLine.length + 1 }, - end: { line: lineIndex } + if (!unistUtilGenerated(node)) { + if (preferred) { + if (marker !== preferred) { + file.message( + 'Strong should use `' + preferred + '` as a marker', + node + ); } - }); + } else { + preferred = marker; + } } } } -var convert_1$1 = convert$2; +var convert_1$A = convert$B; -function convert$2(test) { +function convert$B(test) { if (typeof test === 'string') { - return typeFactory$1(test) + return typeFactory$A(test) } if (test === null || test === undefined) { - return ok$2 + return ok$B } if (typeof test === 'object') { - return ('length' in test ? anyFactory$1 : matchesFactory$1)(test) + return ('length' in test ? anyFactory$A : matchesFactory$A)(test) } if (typeof test === 'function') { @@ -43965,13 +51665,13 @@ function convert$2(test) { throw new Error('Expected function, string, or object as test') } -function convertAll$1(tests) { +function convertAll$A(tests) { var results = []; var length = tests.length; var index = -1; while (++index < length) { - results[index] = convert$2(tests[index]); + results[index] = convert$B(tests[index]); } return results @@ -43979,7 +51679,7 @@ function convertAll$1(tests) { // Utility assert each property in `test` is represented in `node`, and each // values are strictly equal. -function matchesFactory$1(test) { +function matchesFactory$A(test) { return matches function matches(node) { @@ -43995,8 +51695,8 @@ function matchesFactory$1(test) { } } -function anyFactory$1(tests) { - var checks = convertAll$1(tests); +function anyFactory$A(tests) { + var checks = convertAll$A(tests); var length = checks.length; return matches @@ -44016,7 +51716,7 @@ function anyFactory$1(tests) { // Utility to convert a string into a function which checks a given node’s type // for said string. -function typeFactory$1(test) { +function typeFactory$A(test) { return type function type(node) { @@ -44025,23 +51725,23 @@ function typeFactory$1(test) { } // Utility to return true. -function ok$2() { +function ok$B() { return true } -var unistUtilVisitParents$1 = visitParents$1; +var unistUtilVisitParents$A = visitParents$A; -var CONTINUE$2 = true; -var SKIP$2 = 'skip'; -var EXIT$2 = false; +var CONTINUE$18 = true; +var SKIP$18 = 'skip'; +var EXIT$18 = false; -visitParents$1.CONTINUE = CONTINUE$2; -visitParents$1.SKIP = SKIP$2; -visitParents$1.EXIT = EXIT$2; +visitParents$A.CONTINUE = CONTINUE$18; +visitParents$A.SKIP = SKIP$18; +visitParents$A.EXIT = EXIT$18; -function visitParents$1(tree, test, visitor, reverse) { +function visitParents$A(tree, test, visitor, reverse) { var is; if (typeof test === 'function' && typeof visitor !== 'function') { @@ -44050,7 +51750,7 @@ function visitParents$1(tree, test, visitor, reverse) { test = null; } - is = convert_1$1(test); + is = convert_1$A(test); one(tree, null, []); @@ -44060,16 +51760,16 @@ function visitParents$1(tree, test, visitor, reverse) { var subresult; if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult$1(visitor(node, parents)); + result = toResult$A(visitor(node, parents)); - if (result[0] === EXIT$2) { + if (result[0] === EXIT$18) { return result } } - if (node.children && result[0] !== SKIP$2) { - subresult = toResult$1(all(node.children, parents.concat(node))); - return subresult[0] === EXIT$2 ? subresult : result + if (node.children && result[0] !== SKIP$18) { + subresult = toResult$A(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$18 ? subresult : result } return result @@ -44085,7 +51785,7 @@ function visitParents$1(tree, test, visitor, reverse) { while (index > min && index < children.length) { result = one(children[index], index, parents); - if (result[0] === EXIT$2) { + if (result[0] === EXIT$18) { return result } @@ -44094,38 +51794,38 @@ function visitParents$1(tree, test, visitor, reverse) { } } -function toResult$1(value) { +function toResult$A(value) { if (value !== null && typeof value === 'object' && 'length' in value) { return value } if (typeof value === 'number') { - return [CONTINUE$2, value] + return [CONTINUE$18, value] } return [value] } -var unistUtilVisit$1 = visit$1; +var unistUtilVisit$A = visit$A; -var CONTINUE$3 = unistUtilVisitParents$1.CONTINUE; -var SKIP$3 = unistUtilVisitParents$1.SKIP; -var EXIT$3 = unistUtilVisitParents$1.EXIT; +var CONTINUE$19 = unistUtilVisitParents$A.CONTINUE; +var SKIP$19 = unistUtilVisitParents$A.SKIP; +var EXIT$19 = unistUtilVisitParents$A.EXIT; -visit$1.CONTINUE = CONTINUE$3; -visit$1.SKIP = SKIP$3; -visit$1.EXIT = EXIT$3; +visit$A.CONTINUE = CONTINUE$19; +visit$A.SKIP = SKIP$19; +visit$A.EXIT = EXIT$19; -function visit$1(tree, test, visitor, reverse) { +function visit$A(tree, test, visitor, reverse) { if (typeof test === 'function' && typeof visitor !== 'function') { reverse = visitor; visitor = test; test = null; } - unistUtilVisitParents$1(tree, test, overload, reverse); + unistUtilVisitParents$A(tree, test, overload, reverse); function overload(node, parents) { var parent = parents[parents.length - 1]; @@ -44134,142 +51834,27 @@ function visit$1(tree, test, visitor, reverse) { } } -var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); - -function testProhibited(val, content) { - let regexpString = '(\\.|@[a-z0-9/-]*)?'; - - // If it starts with a letter, make sure it is a word break. - if (/^\b/.test(val.no)) { - regexpString += '\\b'; - } - regexpString += `(${val.no})`; - - // If it ends with a letter, make sure it is a word break. - if (/\b$/.test(val.no)) { - regexpString += '\\b'; - } - regexpString += '(\\.\\w)?'; - const re = new RegExp(regexpString, 'g'); - - let result = null; - while (result = re.exec(content)) { - if (!result[1] && !result[3]) { - return result[2]; - } - } - - return false; -} - -function prohibitedStrings(ast, file, strings) { - unistUtilVisit$1(ast, 'text', checkText); - - function checkText(node) { - const content = node.value; - - strings.forEach((val) => { - const result = testProhibited(val, content); - if (result) { - file.message(`Use "${val.yes}" instead of "${result}"`, node); - } - }); - } -} - -var rule = unifiedLintRule; - - - - -var remarkLintRuleStyle = rule('remark-lint:rule-style', ruleStyle); - -var start$g = unistUtilPosition.start; -var end$9 = unistUtilPosition.end; - -function ruleStyle(tree, file, pref) { - var contents = String(file); - - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (pref !== null && /[^-_* ]/.test(pref)) { - file.fail( - "Invalid preferred rule-style: provide a valid markdown rule, or `'consistent'`" - ); - } - - unistUtilVisit(tree, 'thematicBreak', visitor); - - function visitor(node) { - var initial = start$g(node).offset; - var final = end$9(node).offset; - var rule; - - if (!unistUtilGenerated(node)) { - rule = contents.slice(initial, final); - - if (pref) { - if (rule !== pref) { - file.message('Rules should use `' + pref + '`', node); - } - } else { - pref = rule; - } - } - } -} - -var remarkLintStrongMarker = unifiedLintRule('remark-lint:strong-marker', strongMarker); - -var markers$1 = {'*': true, _: true, null: true}; - -function strongMarker(tree, file, pref) { - var contents = String(file); - - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (markers$1[pref] !== true) { - file.fail( - 'Invalid strong marker `' + - pref + - "`: use either `'consistent'`, `'*'`, or `'_'`" - ); - } - - unistUtilVisit(tree, 'strong', visitor); - - function visitor(node) { - var marker = contents.charAt(unistUtilPosition.start(node).offset); - - if (!unistUtilGenerated(node)) { - if (pref) { - if (marker !== pref) { - file.message('Strong should use `' + pref + '` as a marker', node); - } - } else { - pref = marker; - } - } - } -} - var remarkLintTableCellPadding = unifiedLintRule('remark-lint:table-cell-padding', tableCellPadding); -var start$h = unistUtilPosition.start; +var start$i = unistUtilPosition.start; var end$a = unistUtilPosition.end; var styles$3 = {null: true, padded: true, compact: true}; -function tableCellPadding(tree, file, pref) { +function tableCellPadding(tree, file, option) { var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (styles$3[pref] !== true) { - file.fail('Invalid table-cell-padding style `' + pref + '`'); + if (styles$3[preferred] !== true) { + file.fail( + 'Incorrect table cell padding style `' + + preferred + + "`, expected `'padded'`, `'compact'`, or `'consistent'`" + ); } - unistUtilVisit(tree, 'table', visitor); + unistUtilVisit$A(tree, 'table', visitor); function visitor(node) { var rows = node.children; @@ -44304,8 +51889,8 @@ function tableCellPadding(tree, file, pref) { next = cells[column + 1]; fence = contents.slice( - cell ? end$a(cell).offset : start$h(row).offset, - next ? start$h(next).offset : end$a(row).offset + cell ? end$a(cell).offset : start$i(row).offset, + next ? start$i(next).offset : end$a(row).offset ); pos = fence.indexOf('|'); @@ -44327,8 +51912,8 @@ function tableCellPadding(tree, file, pref) { } } - if (pref) { - style = pref === 'padded' ? 1 : 0; + if (preferred) { + style = preferred === 'padded' ? 1 : 0; } else { style = entries[0] && (!entries[0].start || !entries[0].end) ? 0 : 1; } @@ -44342,7 +51927,7 @@ function tableCellPadding(tree, file, pref) { checkSide('end', entry, style, sizes); } - return unistUtilVisit.SKIP + return unistUtilVisit$A.SKIP } function checkSide(side, entry, style, sizes) { @@ -44382,12 +51967,203 @@ function tableCellPadding(tree, file, pref) { } function size(node) { - return end$a(node).offset - start$h(node).offset + return end$a(node).offset - start$i(node).offset +} + +var convert_1$B = convert$C; + +function convert$C(test) { + if (typeof test === 'string') { + return typeFactory$B(test) + } + + if (test === null || test === undefined) { + return ok$C + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$B : matchesFactory$B)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$B(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$C(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$B(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$B(tests) { + var checks = convertAll$B(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$B(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$C() { + return true +} + +var unistUtilVisitParents$B = visitParents$B; + + + +var CONTINUE$1a = true; +var SKIP$1a = 'skip'; +var EXIT$1a = false; + +visitParents$B.CONTINUE = CONTINUE$1a; +visitParents$B.SKIP = SKIP$1a; +visitParents$B.EXIT = EXIT$1a; + +function visitParents$B(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$B(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$B(visitor(node, parents)); + + if (result[0] === EXIT$1a) { + return result + } + } + + if (node.children && result[0] !== SKIP$1a) { + subresult = toResult$B(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$1a ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$1a) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$B(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1a, value] + } + + return [value] +} + +var unistUtilVisit$B = visit$B; + + + +var CONTINUE$1b = unistUtilVisitParents$B.CONTINUE; +var SKIP$1b = unistUtilVisitParents$B.SKIP; +var EXIT$1b = unistUtilVisitParents$B.EXIT; + +visit$B.CONTINUE = CONTINUE$1b; +visit$B.SKIP = SKIP$1b; +visit$B.EXIT = EXIT$1b; + +function visit$B(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$B(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } } var remarkLintTablePipes = unifiedLintRule('remark-lint:table-pipes', tablePipes); -var start$i = unistUtilPosition.start; +var start$j = unistUtilPosition.start; var end$b = unistUtilPosition.end; var reasonStart = 'Missing initial pipe in table fence'; @@ -44396,7 +52172,7 @@ var reasonEnd = 'Missing final pipe in table fence'; function tablePipes(tree, file) { var contents = String(file); - unistUtilVisit(tree, 'table', visitor); + unistUtilVisit$B(tree, 'table', visitor); function visitor(node) { var rows = node.children; @@ -44416,11 +52192,11 @@ function tablePipes(tree, file) { cells = row.children; head = cells[0]; tail = cells[cells.length - 1]; - initial = contents.slice(start$i(row).offset, start$i(head).offset); + initial = contents.slice(start$j(row).offset, start$j(head).offset); final = contents.slice(end$b(tail).offset, end$b(row).offset); if (initial.indexOf('|') === -1) { - file.message(reasonStart, start$i(row)); + file.message(reasonStart, start$j(row)); } if (final.indexOf('|') === -1) { @@ -44431,12 +52207,203 @@ function tablePipes(tree, file) { } } +var convert_1$C = convert$D; + +function convert$D(test) { + if (typeof test === 'string') { + return typeFactory$C(test) + } + + if (test === null || test === undefined) { + return ok$D + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$C : matchesFactory$C)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$C(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$D(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$C(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$C(tests) { + var checks = convertAll$C(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$C(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$D() { + return true +} + +var unistUtilVisitParents$C = visitParents$C; + + + +var CONTINUE$1c = true; +var SKIP$1c = 'skip'; +var EXIT$1c = false; + +visitParents$C.CONTINUE = CONTINUE$1c; +visitParents$C.SKIP = SKIP$1c; +visitParents$C.EXIT = EXIT$1c; + +function visitParents$C(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$C(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$C(visitor(node, parents)); + + if (result[0] === EXIT$1c) { + return result + } + } + + if (node.children && result[0] !== SKIP$1c) { + subresult = toResult$C(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$1c ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$1c) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$C(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1c, value] + } + + return [value] +} + +var unistUtilVisit$C = visit$C; + + + +var CONTINUE$1d = unistUtilVisitParents$C.CONTINUE; +var SKIP$1d = unistUtilVisitParents$C.SKIP; +var EXIT$1d = unistUtilVisitParents$C.EXIT; + +visit$C.CONTINUE = CONTINUE$1d; +visit$C.SKIP = SKIP$1d; +visit$C.EXIT = EXIT$1d; + +function visit$C(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$C(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + var remarkLintUnorderedListMarkerStyle = unifiedLintRule( 'remark-lint:unordered-list-marker-style', unorderedListMarkerStyle ); -var start$j = unistUtilPosition.start; +var start$k = unistUtilPosition.start; var styles$4 = { '-': true, @@ -44445,20 +52412,20 @@ var styles$4 = { null: true }; -function unorderedListMarkerStyle(tree, file, pref) { +function unorderedListMarkerStyle(tree, file, option) { var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (styles$4[pref] !== true) { + if (styles$4[preferred] !== true) { file.fail( - 'Invalid unordered list-item marker style `' + - pref + + 'Incorrect unordered list item marker style `' + + preferred + "`: use either `'-'`, `'*'`, or `'+'`" ); } - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$C(tree, 'list', visitor); function visitor(node) { var children = node.children; @@ -44472,16 +52439,16 @@ function unorderedListMarkerStyle(tree, file, pref) { if (!unistUtilGenerated(child)) { marker = contents - .slice(start$j(child).offset, start$j(child.children[0]).offset) + .slice(start$k(child).offset, start$k(child.children[0]).offset) .replace(/\[[x ]?]\s*$/i, '') .replace(/\s/g, ''); - if (pref) { - if (marker !== pref) { - file.message('Marker style should be `' + pref + '`', child); + if (preferred) { + if (marker !== preferred) { + file.message('Marker style should be `' + preferred + '`', child); } } else { - pref = marker; + preferred = marker; } } } @@ -44498,8 +52465,8 @@ var plugins$2 = [ remarkLintCheckboxCharacterStyle, { checked: "x", - unchecked: " " - } + unchecked: " ", + }, ], remarkLintCheckboxContentIndent, [remarkLintCodeBlockStyle, "fenced"], @@ -44517,7 +52484,6 @@ var plugins$2 = [ remarkLintNoFileNameConsecutiveDashes, remarkLintNoFileNameOuterDashes, remarkLintNoHeadingIndent, - [remarkLintNoLiteralUrls, false], remarkLintNoMultipleToplevelHeadings, remarkLintNoShellDollars, remarkLintNoTableIndentation, @@ -44526,29 +52492,26 @@ var plugins$2 = [ [ remarkLintProhibitedStrings, [ - { no: "End-Of-Life", yes: "End-of-Life" }, - { no: "End-of-life", yes: "End-of-Life" }, - { no: "Github", yes: "GitHub" }, + { yes: "End-of-Life" }, + { yes: "GitHub" }, { no: "hostname", yes: "host name" }, - { no: "[Jj]avascript", yes: "JavaScript" }, + { yes: "JavaScript" }, { no: "Node", yes: "Node.js" }, - { no: "Node\\.JS", yes: "Node.js" }, - { no: "node\\.js", yes: "Node.js" }, + { yes: "Node.js" }, + { no: "Node[Jj][Ss]", yes: "Node.js" }, { no: "Node\\.js's?", yes: "the Node.js" }, { no: "[Nn]ote that", yes: "" }, - { no: "Rfc", yes: "RFC" }, + { yes: "RFC" }, { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, - { no: "rfc", yes: "RFC" }, - { no: "UNIX", yes: "Unix" }, - { no: "unix", yes: "Unix" }, - { no: "v8", yes: "V8" } - ] + { yes: "Unix" }, + { yes: "V8" }, + ], ], remarkLintRuleStyle, [remarkLintStrongMarker, "*"], [remarkLintTableCellPadding, "padded"], remarkLintTablePipes, - [remarkLintUnorderedListMarkerStyle, "*"] + [remarkLintUnorderedListMarkerStyle, "*"], ]; var remarkPresetLintNode = { diff --git a/tools/node-lint-md-cli-rollup/package-lock.json b/tools/node-lint-md-cli-rollup/package-lock.json index e6597cfdd506fe..f1a8df25bef8c1 100644 --- a/tools/node-lint-md-cli-rollup/package-lock.json +++ b/tools/node-lint-md-cli-rollup/package-lock.json @@ -401,11 +401,6 @@ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, - "irregular-plurals": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", - "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==" - }, "is-alphabetical": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", @@ -595,14 +590,14 @@ } }, "mdast-util-heading-style": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.5.tgz", - "integrity": "sha512-8zQkb3IUwiwOdUw6jIhnwM6DPyib+mgzQuHAe7j2Hy1rIarU4VUxe472bp9oktqULW3xqZE+Kz6OD4Gi7IA3vw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", + "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==" }, "mdast-util-to-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz", - "integrity": "sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" }, "minimatch": { "version": "3.0.4", @@ -688,13 +683,10 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" }, - "plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", - "requires": { - "irregular-plurals": "^2.0.0" - } + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" }, "rc": { "version": "1.2.8", @@ -753,360 +745,1084 @@ } }, "remark-lint-blockquote-indentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.3.tgz", - "integrity": "sha512-qK4C1l2VmeOVWEAkDYP0CaDtSFoaEBEo5l4oyz1kTkY7YB0Jh7llW2KjuhJz5IzMLmloKJzIyGwlu/odcwaHpg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-2.0.0.tgz", + "integrity": "sha512-Ma/lk+egYzvzV9+RLxR7iaNcFqwsF02guxY2nFF7gaVFXWDhbRy+hbiRZiTQe3y8AK+smc2yE79I+JRUVL15LQ==", "requires": { "mdast-util-to-string": "^1.0.2", - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-checkbox-character-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-1.0.3.tgz", - "integrity": "sha512-bQGrGHLlguTxOzuywHtYxNcg58TYhNgeEAMCTvdAggt5bYZIwmh/otx51JsQ0a96qxd/6/G0Ri2xzgyxf9wB8w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-2.0.0.tgz", + "integrity": "sha512-V+eTXFHrHCpFFG2RWaQM6lSetLLvpYC8WEZ9dMYSAUbeS/h0PhA7cB7j5kGH86RUwGCihawfzNAKbRmgGxL+DQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-checkbox-content-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-1.0.3.tgz", - "integrity": "sha512-YaM1yy8RdnM0DUaP0r2X8kF+inUTmjkCpj5Xjn7QTOV1T5jqJMJnRRilirAWgOGa1QBZBUew7uj0L1Je9SJIZw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-2.0.0.tgz", + "integrity": "sha512-02Xytexe8nso1ofPC6wN3FE48302nmteSIwydeIDFhJq7mG14SxF4xgay+Kjbhs/O5NoRIF2ju9qcPNJ5gFsXA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-code-block-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.3.tgz", - "integrity": "sha512-DL+rudnd9ILP5YXm74tLpMzfWZLqziX7NwIwUhqRefaOyWwxgPPy7hbT59FJqcFc6E/zvDz+Oq4nR1BSV5kEdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-2.0.0.tgz", + "integrity": "sha512-bXT1b9MvYDxKdLfzWTW3eSXWy7v57LXtU5ySLzlD1g3DWoSA6rSWjJT5l/2mA+iOuswg18ssY3SSjwExmTyWUA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-definition-spacing": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.4.tgz", - "integrity": "sha512-UderghITmru72OXB5ErCFhVsY7up2wK/m1bUD3E2dm/TFn73/7WpykENt5UirCDT/aeyoHYl8QXUVL20rAc3XQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-2.0.0.tgz", + "integrity": "sha512-kE+ffEGsyxgUDlcKSVrnhqyHjQfH0RtUVN/OdA/iSzKfTy/Yc9VMMaNu6xT14xhwjTnSVPrd38rUOnDt1LZhAw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-fenced-code-flag": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.3.tgz", - "integrity": "sha512-X8Oi6dhfqV9NI3cVg29myvT/NATDHVgRGCpnNz76w7VXwzhBvQtJr1MxZzuPxfWLox+ARCXF2rY9n9hbYFHYTg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-2.0.0.tgz", + "integrity": "sha512-SyQ31cdQlbsS+eBw2DUxkuzNwGIGlWnnCLyHLz3D1nxtZBVUaUOnIAturSA3PsguIrnxH4qD2JYCTp5aPbZhzQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-fenced-code-marker": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.3.tgz", - "integrity": "sha512-JKnojSQ8JkwpIpbNm6wtKEfx8iiv8QIwNHFM06iTCHExMhXa4pJ3wb5M5f0wsWNHtoND3lrw6AcVPoZxEPnflg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-2.0.0.tgz", + "integrity": "sha512-ZkJ4/o0A34nQefhsu6AU2cftQjCwzXClbZ5TrwgtkQQHG9BSu9/vo3PSLxGGw7XBX63oKcrx5HWGrWXaeLTN2g==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-file-extension": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.3.tgz", - "integrity": "sha512-P5gzsxKmuAVPN7Kq1W0f8Ss0cFKfu+OlezYJWXf+5qOa+9Y5GqHEUOobPnsmNFZrVMiM7JoqJN2C9ZjrUx3N6Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.4.tgz", + "integrity": "sha512-Zfp1mXNwpg7STjTWynZjL+/JtvIOCrmOAZzL3uK+tYpT0ZDPdQ1EQEl5D92+Eiu5OcYlenzG42jiLcyJjv+Q2g==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-final-definition": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-1.0.3.tgz", - "integrity": "sha512-QhbBYy99enfQDeUTElioCHrhgg+SgjMNRlru7/JlOguOufP6wn7AXgn2EVTrLZRoByY0VsNS2jCayXxUTzQ8KA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-2.0.0.tgz", + "integrity": "sha512-oGObGXt/CdQfvnoQHWrFPtpTQK7oHiw5kBGzG5GbPSj3rrv30ohD5K+11ljEle9e3wO048EiWDROO5eKzIeeGw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-final-newline": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.3.tgz", - "integrity": "sha512-ETAadktv75EwUS3XDhyZUVstXKxfPAEn7SmfN9kZ4+Jb4qo4hHE9gtTOzhE6HxLUxxl9BBhpC5mMO3JcL8UZ5A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.4.tgz", + "integrity": "sha512-pUwqX8TVTTfqX5arMnu9Dr2ufg6wZ6Pk1VeqlnWfK92PBXLG8Zc3yrLpYXOJy1fHdWpqUECRRowG0H/OkZIEbw==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-first-heading-level": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-1.1.4.tgz", - "integrity": "sha512-iU5G4ZmGx8/2p/U2rPc6qhjyQ/BCcOuj07KzI7XxapYfJqZF6Xxz2rC2b/5xsDJAz2vXG74U4iG3c9vmbyH9WQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-hard-break-spaces": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.4.tgz", - "integrity": "sha512-YM82UpgliZCZhGNmFxEe7ArfhqR5CplFf2bc0k0+8w3rKWKx7EJcGMar2NK410tIi40gGeWtH/pIEypPJFCCiA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-2.0.0.tgz", + "integrity": "sha512-LFjKO6nQAPo0oarhLZqHaGUqCpLvjeVuJTr58yo3jpC4v0Gmb1iG8X53hrLtxPz+MP4J5WVz/83eAXCH+Vh3vA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } + } + }, + "remark-lint-hard-break-spaces": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.0.tgz", + "integrity": "sha512-dmB8GucOSDtEctwa+Y8JlSAWF4q8HcquvLr+OpFOSE1QCrpFoZdb2mcSY+rZuTtfeg4S60orhhzArd2aiHvUPQ==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } + } }, "remark-lint-heading-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-1.0.3.tgz", - "integrity": "sha512-ZUhMav0HHUxo5gzLqxQsOf2ZpP/I3m6EEK8q25/kqpCYnwm1uRJ5CQ40PDQx46pmKtVibIMzDmraYovxNG3ovw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-2.0.0.tgz", + "integrity": "sha512-LZvnAq5zWh9i/oRAEocth8yajEEH4kRgCrL4dE547Nkv6zaR2SKcym+uXMZ+GF6WEWcjXMiwSxIL7MHaT6XexA==", "requires": { "mdast-util-heading-style": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-list-item-bullet-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.3.tgz", - "integrity": "sha512-iVxQbrgzLpMHG3C6o6wRta/+Bc96etOiBYJnh2zm/aWz6DJ7cGLDykngblP/C4he7LYSeWOD/8Y57HbXZwM2Og==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-2.0.0.tgz", + "integrity": "sha512-8iK+ht771UBf/Iuj4YBgdLnFFOyEgfXY62jBoywtMuiOLVWXDfPe+jUY7pCrnFjsnxXGEnMaxHJqENgrHd0J/w==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-list-item-indent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.4.tgz", - "integrity": "sha512-Sv0gVH6qP1/nFpbJuyyguB9sAD2o42StD2WbEZeUcEexXwRO4u/YaX0Pm5pMtCiEHyN+qyL6ShKBQMtgol9BeA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.0.tgz", + "integrity": "sha512-qnKsq2UQpCC8gnI1O23dgoKsd+5RAJrAJuvHXrlkRgzsab7BOMluptxRlyLVXn0P71l4Wo/bfo84Ual7qpOyWw==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-maximum-line-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-1.2.1.tgz", - "integrity": "sha512-CSxX1qc+rAqixk8eBrI+yBsUmD8YGfOezFeJWjJRuUaoOvs67oqCIU+I2HbwcUYY8/KnDxF1MCp+uCM0RkjKKw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-2.0.0.tgz", + "integrity": "sha512-Qhe1QwDGisMP/UraUexWIPNBXJO8VQ7LIelz4NdftBQl/FxDVoXn3477Fm+8bGtcTXkMPF+QfllE4L1U7kJQgQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-auto-link-without-protocol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.3.tgz", - "integrity": "sha512-k+hg2mXnO4Q9WV+UShPLen5oThvFxcRVWkx2hviVd/nu3eiszBKH3o38csBwjeJoMG3l2ZhdUW8dlOBhq8670Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.0.tgz", + "integrity": "sha512-pIntUa+zNiyRxIt2Wvp1soktDbVnk1SEiJXsjcLYYn9GapgXqOQG5ZfFwR6zxTkGV5mZKo9927EvHQkvIV6cLQ==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-blockquote-without-marker": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.3.tgz", - "integrity": "sha512-faDzKrA6aKidsRXG6gcIlCO8TexLxIxe+n9B3mdnl8mhZGgE0FfWTkIWVMj0IYps/xVsVMf45KxhXgc1wU9kwg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-3.0.0.tgz", + "integrity": "sha512-auyAxMVDuhvGw29VilqUfUIUnBT7qmByG/kBPqV/GwM1a5rn4fIUJ7p9Je9BlWMRCBMTNQUMsm3ce0dawouVew==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-no-consecutive-blank-lines": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.3.tgz", - "integrity": "sha512-2Ef7fPxrfLditA7sTo2Qfqd+xwh/luWl8GzILE5vcWIxLDqKk3dTLJkB5nP+7Cr4kqWJAwXnRkEDd77ehrRV3A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-2.0.0.tgz", + "integrity": "sha512-qIXHW0atHaOmHlu7V+4Krs5IAdIZhcXoeRdOMgqkGNW8CtfL12pP8KnzigAB9D5/X/qxPxZ95Js/KaESFS+3hA==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-duplicate-definitions": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.5.tgz", - "integrity": "sha512-zKXmfNUODXhJsGQdqfguMG9Nl9v1sLaDsQgMjUtmOSoQRnNud9ThQAZl62eX5jBn5HKcpOifG80tgkyBvU5eEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.0.tgz", + "integrity": "sha512-Z5DkYKbmS+r4D0ZhaXgK6L72EWzhiklpXNF/TS+KCsffAFgfy5aJfSA3A8GpVNj1wYMP35STXBGBCLW5TckvGw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-file-name-articles": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.3.tgz", - "integrity": "sha512-YZDJDKUWZEmhrO6tHB0u0K0K2qJKxyg/kryr14OaRMvWLS62RgMn97sXPZ38XOSN7mOcCnl0k7/bClghJXx0sg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.4.tgz", + "integrity": "sha512-Ieqg/2WjYs5M+IoZsFrQUG0niN8zRC6IAYWOVaHi3UK/1P0IdmXKZE6pCFSJrhletawAaPw9Xtl42/45tcccCA==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-file-name-consecutive-dashes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.3.tgz", - "integrity": "sha512-7f4vyXn/ca5lAguWWC3eu5hi8oZ7etX7aQlnTSgQZeslnJCbVJm6V6prFJKAzrqbBzMicUXr5pZLBDoXyTvHHw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.4.tgz", + "integrity": "sha512-Fyc8mL+Fyt2b/BVkCc2Y+GjJ4SwafDKQEUaizeuZQDBTiqRK3S4L9YpvLHTAPgTNntZkXLUsHzFDlGyKzW2gBQ==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-file-name-outer-dashes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.4.tgz", - "integrity": "sha512-+bZvvme2Bm3Vp5L2iKuvGHYVmHKrTkkRt8JqJPGepuhvBvT4Q7+CgfKyMtC/hIjyl+IcuJQ2H0qPRzdicjy1wQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.5.tgz", + "integrity": "sha512-5CMrCqyJj4ydM2QMhMAc60o08fJDxBgmO62r+RqVs+aIdIK6TtsF+T8oX+aTEtc3y/euKJ681tqEsSeJZh/h0A==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-heading-content-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.3.tgz", - "integrity": "sha512-7xM6X5E/dt8OXOHdejH+sfYb139a3kMr8ZSSkcp90Ab1y+ZQBNaWsR3mYh8FRKkYPTN5eyd+KjhNpLWyqqCbgg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-2.0.0.tgz", + "integrity": "sha512-Zqg0WXG60Nan8j7HZtnBXidMxXhlhc7Q5JrB54I3n7H3vSPCyaqhZJ2/obYVLalEVGND8NOJGvfA1rtchaZyYg==", "requires": { "mdast-util-heading-style": "^1.0.2", - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-heading-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-1.0.3.tgz", - "integrity": "sha512-RTvsFfiXjHZOxU+t7DtNPk9M9EqGe82MZbo+VOJEUBkQKf17qp4EZkJEvl4h9pn+hJmoKHLb7Vfge8Bxe42gcQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-2.0.0.tgz", + "integrity": "sha512-dBjSP2QdQVypFpwQdjZ6h/VsyY3CBY+IXY2edSWiITOofZrt7knmwrLFUoxPtvc9k4PIBA7XXpiwPPYBQzuLFg==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-inline-padding": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.4.tgz", - "integrity": "sha512-u5rgbDkcfVv645YxxOwoGBBJbsHEwWm/XqnO8EhfKTxkfKOF4ZItG7Ajhj89EDaeXMkvCcB/avBl4bj50eJH3g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-2.0.0.tgz", + "integrity": "sha512-0YueQ3SBA8zFQYCN0/afRc6ZuSbM4Azx4sPVeVpAfMT0MrYgmi6msswyhUDXaeN2RwVO6bx/ZW6di8dVqRr7UA==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-literal-urls": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.3.tgz", - "integrity": "sha512-H5quyMzl2kaewK+jYD1FI0G1SIinIsIp4DEyOUwIR+vYUoKwo0B4vvW0cmPpD1dgqqxHYx0B2B0JQQKFVWzGiw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.0.tgz", + "integrity": "sha512-bZAxr65ftz9joszDkSs2LBeJB2cRE8GydUtxYdA1WRHYmVW1AfM5ilcqLnWhiOmu+XMPH7J0eRvUzbtvu+xerw==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-multiple-toplevel-headings": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.4.tgz", - "integrity": "sha512-0wDddx6htN5sL9/rofesiQF0oEgwN5224UmueiDx0ZUlYrn6VS0/SS0X3WWxtXmyeqlExfWF3D/g89tNs7dcjw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-2.0.0.tgz", + "integrity": "sha512-vpbdnrqUykyqpjaREg4W07J3gHgR0eTapDkz9RjVwyGNmBry7xUnyvaiPavAKqsA+qO/nnpIH8Qyw/2u5hDsJQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shell-dollars": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.3.tgz", - "integrity": "sha512-fT3lQMTjEkPryL+63qDP1NfrohP3tG5i3SkNWSSR4VLU6OSsSSXlHGQGjo0ag//+EPKHB5/9frB/YQ0gDEPRGQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-2.0.0.tgz", + "integrity": "sha512-1uEM0kSGlV6UY7w3PdIeIf/USFFvVuU1352myQdaiw/Wof7+uVXznFFCPnhJDTVlPN4vrgwFnLb32UwXrjkrQw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shortcut-reference-image": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.3.tgz", - "integrity": "sha512-CGm27X54kXp/5ehXejDTsZjqzK4uIhLGcrFzN3k/KjdwunQouEY92AARGrLSEuJ1hQx0bJsmnvr/hvQyWAfNJg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.0.tgz", + "integrity": "sha512-kgGCQBHibJ0IFVhWjnfjbqkKC0VeL5+cvyjjwfMJlgZrHEXNOYb2FJE2nvF/l6PSXQ17goRZpznTBfP4mQieUA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shortcut-reference-link": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.4.tgz", - "integrity": "sha512-FXdMJYqspZBhPlxYqfVgVluVXjxStg0RHJzqrk8G9wS8fCS62AE3reoaoiCahwoH1tfKcA+poktbKqDAmZo7Jg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.0.tgz", + "integrity": "sha512-rSdGLWpEsHa4b2doUch+B7QtUHH9XuC8Hndb4rAYf8U0d48KfGAIoiicxUho8qZJ4VA3RIaDo4kA/iQ15Al+Vg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-table-indentation": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.4.tgz", - "integrity": "sha512-H4VGHcg1k8sTIbwazFYLNbDqpPR+M0aHHKDf+93b/xyd27Dp0ODQrMnQbls1Cls5qOAQnwAQbx+75wcpFxP3OQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-2.0.0.tgz", + "integrity": "sha512-5akpqHl+5r3Xe2WFiZB1I9eAwn6zTYqXNd0CVsiTF3DJo0KyvvgyrFRV1sCf/l/kzyNaFvpWpFDTMoWc8EI0RQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-tabs": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-1.0.3.tgz", - "integrity": "sha512-GxmG1LLxYoVjKnQ39On4mFEiVwpLfR3BPTXyaC9UCBUj9fnDQ7ANXceeCsPAyxamr0UM4r2tk/hB9mNT4rLskQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-2.0.0.tgz", + "integrity": "sha512-aXbqkgjI0611IN651eXK8NxLQLEjReviU6AjtluMVnvGx1B8Y8mEn5pxznrorXaAjOP4mvX0JYeu8kdhcAaHsw==", "requires": { "unified-lint-rule": "^1.0.0", - "vfile-location": "^2.0.1" + "vfile-location": "^3.0.0" + }, + "dependencies": { + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-no-trailing-spaces": { @@ -1118,46 +1834,132 @@ } }, "remark-lint-no-undefined-references": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.1.1.tgz", - "integrity": "sha512-b1eIjWFaCu6m16Ax2uG33o1v+eRYqDTQRUqU6UeQ76JXmDmVtVO75ZuyRpqqE7VTZRW8YLVurXfJPDXfIa5Wng==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-2.0.0.tgz", + "integrity": "sha512-K4k05pmlMRqEMUDYewitRUx8zM+ntJWbG61dILmL7to7uy0JoSbzuDtz1cxC+kKBKzkulPnyE3WOgRZG8RX2Jg==", "requires": { "collapse-white-space": "^1.0.4", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-unused-definitions": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.5.tgz", - "integrity": "sha512-Bo22e0RNzc1QMW317KTuStGFDG7uTDUQhm/TrW6Qzud0WXnNnqUyvts+e7wTYoj8VnwhhjyjyoA9lKA3uXMdAQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.0.tgz", + "integrity": "sha512-Y8zrulwaf7z6WR1ICfEGjW92iq2SPEN7Zhrs0nloNITHOg22tIPf28TurUz9HSQ3sEd52d9bZCfW9RkdfMq1xw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-ordered-list-marker-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.3.tgz", - "integrity": "sha512-24TmW1eUa/2JlwprZg9jJ8LKLxNGKnlKiI5YOhN4taUp2yv8daqlV9vR54yfn/ZZQh6EQvbIX0jeVY9NYgQUtw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.0.tgz", + "integrity": "sha512-zYMZA8tQD/slJYKqsstZv0/Q34Hkdlf4DjC8SOr92PSA60R/xr7JdVd/AHHisbMsFvdnHZrxaB8oIOtbAUJCSw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-prohibited-strings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.2.1.tgz", - "integrity": "sha512-i3LatoJn/eHkgawdi3eoynikQa5zIEDX+GYcvu4ns5LsOvIrT8WcuvgYQ2kbEFbV0KTy7yBAGLJ9040xs1ssXA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.5.1.tgz", + "integrity": "sha512-YZoRWbzIGRIQkngAowwAKG39kUAGSalYvrxqTzUU4LYj1dS37q7i5WDr4m/mnCcc5KwRin08D62Dphs6g9Btnw==", "requires": { + "escape-string-regexp": "^4.0.0", "unified-lint-rule": "^1.0.2", - "unist-util-visit": "^2.0.0" + "unist-util-position": "^3.1.0", + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.1" }, "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, "unist-util-is": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", @@ -1181,62 +1983,197 @@ "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" } } }, "remark-lint-rule-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-1.0.3.tgz", - "integrity": "sha512-SJe7IFORYRdo8JUhMSdcTktVAUVNVp36YYl1ZD9CfHqQHWlFD+3vWYzJXOZfog/i+CyWf7Yi0WVYmQes+167dA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-2.0.0.tgz", + "integrity": "sha512-fdRfLUE5AJiFEn9rWTQrHwOUG3UcYtIxbWnR7YFvuPlFmzcMRwRHP5ZOcrj4KIpwCdVtlPI3h08m0kfO7a1KlQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-strong-marker": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.3.tgz", - "integrity": "sha512-PFkH282dCwfRsVEw9IxbYbaZBY4UcTuT2SN+lA3R0cBeocWnOySVw8YEm4sv9JfV8BLcQA5gc4tj66/U3KCScw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-2.0.0.tgz", + "integrity": "sha512-1gl6vZF5BvV4kvS4xxhl8cw90La5Cio9ZFDQuspZMRA2KjzpwoU5RlTUbeHv8OqlKJJ2p7s0MDs8bLZNTzzjHA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-table-cell-padding": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.4.tgz", - "integrity": "sha512-AQWWtV1yca1PN27QaFRJbBK6Ro/bopv1XnVKxj/iMebhOU2D2FBJ8rXmMZXVMC3G9OB2WSzGgqH3nP6QY12LoA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-2.0.0.tgz", + "integrity": "sha512-UstIXIaRVRJPKZPv1AXX/p3qCt//RYNsRHIq8KvL5YQPKaKWRkj2cNermCgm0XoUXy0EmRPNiBtUcuAQaP+jXg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-table-pipes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.3.tgz", - "integrity": "sha512-K9NnGZp6i0m/CaOH7ZT4Ymt2seyiRPcBIlNMMGXBm6gpy34KJDDxYqsNUrh+j7dR+Zg4rYAQLnr3BiSHvj+rbQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-2.0.0.tgz", + "integrity": "sha512-qGIttPFNT+19BEDz2JJWQtJIClFNIpg+XVw6ruX9LSR7xdo5QG9uARG4XS2EGUQQ7fiLIxQYb8g2dHwuXGbfmA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-unordered-list-marker-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.3.tgz", - "integrity": "sha512-0nn/Yscy5ImO4fqByrk/Ua02UwGx8LRu+0kdCbkVz4IxPO5qxTEfyccUQZR71zTdMJp1d2OeqyD9XtMaO4X7Ww==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-2.0.0.tgz", + "integrity": "sha512-s+ZiBgBDbIiScPPxWG/r2E/4YY+xP6EFLsLXPV/uPx7JqegIP/4+MAPi7Nz2zLmnQ2eekssZrEXma3uDb/dE1Q==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-message-control": { @@ -1272,65 +2209,178 @@ } }, "remark-preset-lint-node": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-1.13.0.tgz", - "integrity": "sha512-UNAoY4wl672d0qE+LM5rA0ILOTJN+siNGj3/qa5Zvl7nMIUwqMcz0G266Ck6OL6GOrpys/e4EOrkXiitEdEqNA==", - "requires": { - "remark-lint": "^6.0.5", - "remark-lint-blockquote-indentation": "^1.0.3", - "remark-lint-checkbox-character-style": "^1.0.3", - "remark-lint-checkbox-content-indent": "^1.0.3", - "remark-lint-code-block-style": "^1.0.3", - "remark-lint-definition-spacing": "^1.0.4", - "remark-lint-fenced-code-flag": "^1.0.3", - "remark-lint-fenced-code-marker": "^1.0.3", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-1.15.0.tgz", + "integrity": "sha512-1G7S2F/u7bk3kc4tZPrUphceP0RfT9AF6e+gzWbNi8URutECe3kl+Ur6ooMI5f1VqJUzcLF/U1YuhnFhkPnKkA==", + "requires": { + "remark-lint": "^7.0.0", + "remark-lint-blockquote-indentation": "^2.0.0", + "remark-lint-checkbox-character-style": "^2.0.0", + "remark-lint-checkbox-content-indent": "^2.0.0", + "remark-lint-code-block-style": "^2.0.0", + "remark-lint-definition-spacing": "^2.0.0", + "remark-lint-fenced-code-flag": "^2.0.0", + "remark-lint-fenced-code-marker": "^2.0.0", "remark-lint-file-extension": "^1.0.3", - "remark-lint-final-definition": "^1.0.3", - "remark-lint-first-heading-level": "^1.1.4", - "remark-lint-heading-style": "^1.0.3", - "remark-lint-list-item-indent": "^1.0.4", - "remark-lint-maximum-line-length": "^1.2.1", - "remark-lint-no-consecutive-blank-lines": "^1.0.3", - "remark-lint-no-file-name-articles": "^1.0.3", - "remark-lint-no-file-name-consecutive-dashes": "^1.0.3", - "remark-lint-no-file-name-outer-dashes": "^1.0.4", - "remark-lint-no-heading-indent": "^1.0.3", - "remark-lint-no-literal-urls": "^1.0.3", - "remark-lint-no-multiple-toplevel-headings": "^1.0.4", - "remark-lint-no-shell-dollars": "^1.0.3", - "remark-lint-no-table-indentation": "^1.0.4", - "remark-lint-no-tabs": "^1.0.3", + "remark-lint-final-definition": "^2.0.0", + "remark-lint-first-heading-level": "^2.0.0", + "remark-lint-heading-style": "^2.0.0", + "remark-lint-list-item-indent": "^2.0.0", + "remark-lint-maximum-line-length": "^2.0.0", + "remark-lint-no-consecutive-blank-lines": "^2.0.0", + "remark-lint-no-file-name-articles": "^1.0.4", + "remark-lint-no-file-name-consecutive-dashes": "^1.0.4", + "remark-lint-no-file-name-outer-dashes": "^1.0.5", + "remark-lint-no-heading-indent": "^2.0.0", + "remark-lint-no-multiple-toplevel-headings": "^2.0.0", + "remark-lint-no-shell-dollars": "^2.0.0", + "remark-lint-no-table-indentation": "^2.0.0", + "remark-lint-no-tabs": "^2.0.0", "remark-lint-no-trailing-spaces": "^2.0.1", - "remark-lint-prohibited-strings": "^1.2.1", - "remark-lint-rule-style": "^1.0.3", - "remark-lint-strong-marker": "^1.0.3", - "remark-lint-table-cell-padding": "^1.0.4", - "remark-lint-table-pipes": "^1.0.3", - "remark-lint-unordered-list-marker-style": "^1.0.3", - "remark-preset-lint-recommended": "^3.0.3" + "remark-lint-prohibited-strings": "^1.5.1", + "remark-lint-rule-style": "^2.0.0", + "remark-lint-strong-marker": "^2.0.0", + "remark-lint-table-cell-padding": "^2.0.0", + "remark-lint-table-pipes": "^2.0.0", + "remark-lint-unordered-list-marker-style": "^2.0.0", + "remark-preset-lint-recommended": "^4.0.0" + }, + "dependencies": { + "remark-lint": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.0.tgz", + "integrity": "sha512-OLrWPYy0MUcGLa/2rjuy1kQILTRRK+JiRtyUzqe4XRoHboGuvFDcy/W2e7sq5hu/0xmD+Eh7cEa1Coiqp7LeaA==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "requires": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + } + }, + "unified-message-control": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.1.tgz", + "integrity": "sha512-K2Kvvp1DBzeuxYLLsumZh/gDWUTl4e2z/P3VReFirC78cfHKtQifbhnfRrSBtKtd1Uc6cvYTW0/SZIUaMAEcTg==", + "requires": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-preset-lint-recommended": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.3.tgz", - "integrity": "sha512-5sQ34j1Irlsj6Tt4WWRylZ7UU+1jD5es/LfDZBZp/LXDwC4ldGqKpMmCCR6Z00x1jYM1phmS4M+eGqTdah0qkQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-4.0.0.tgz", + "integrity": "sha512-Nroe+4Itvk+AHxkMCMu6iRUptE/5pXWgLoEOGdVO/2JIiMk/+15HEogMZ05vMhPct9+Wp4uVt2zqfuvzNzdcww==", "requires": { - "remark-lint": "^6.0.0", + "remark-lint": "^7.0.0", "remark-lint-final-newline": "^1.0.0", - "remark-lint-hard-break-spaces": "^1.0.0", - "remark-lint-list-item-bullet-indent": "^1.0.0", - "remark-lint-list-item-indent": "^1.0.0", - "remark-lint-no-auto-link-without-protocol": "^1.0.0", - "remark-lint-no-blockquote-without-marker": "^2.0.0", - "remark-lint-no-duplicate-definitions": "^1.0.0", - "remark-lint-no-heading-content-indent": "^1.0.0", - "remark-lint-no-inline-padding": "^1.0.0", - "remark-lint-no-literal-urls": "^1.0.0", - "remark-lint-no-shortcut-reference-image": "^1.0.0", - "remark-lint-no-shortcut-reference-link": "^1.0.0", - "remark-lint-no-undefined-references": "^1.0.0", - "remark-lint-no-unused-definitions": "^1.0.0", - "remark-lint-ordered-list-marker-style": "^1.0.0" + "remark-lint-hard-break-spaces": "^2.0.0", + "remark-lint-list-item-bullet-indent": "^2.0.0", + "remark-lint-list-item-indent": "^2.0.0", + "remark-lint-no-auto-link-without-protocol": "^2.0.0", + "remark-lint-no-blockquote-without-marker": "^3.0.0", + "remark-lint-no-duplicate-definitions": "^2.0.0", + "remark-lint-no-heading-content-indent": "^2.0.0", + "remark-lint-no-inline-padding": "^2.0.0", + "remark-lint-no-literal-urls": "^2.0.0", + "remark-lint-no-shortcut-reference-image": "^2.0.0", + "remark-lint-no-shortcut-reference-link": "^2.0.0", + "remark-lint-no-undefined-references": "^2.0.0", + "remark-lint-no-unused-definitions": "^2.0.0", + "remark-lint-ordered-list-marker-style": "^2.0.0" + }, + "dependencies": { + "remark-lint": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.0.tgz", + "integrity": "sha512-OLrWPYy0MUcGLa/2rjuy1kQILTRRK+JiRtyUzqe4XRoHboGuvFDcy/W2e7sq5hu/0xmD+Eh7cEa1Coiqp7LeaA==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "requires": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + } + }, + "unified-message-control": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.1.tgz", + "integrity": "sha512-K2Kvvp1DBzeuxYLLsumZh/gDWUTl4e2z/P3VReFirC78cfHKtQifbhnfRrSBtKtd1Uc6cvYTW0/SZIUaMAEcTg==", + "requires": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-stringify": { @@ -1608,9 +2658,9 @@ } }, "unified-lint-rule": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.4.tgz", - "integrity": "sha512-q9wY6S+d38xRAuWQVOMjBQYi7zGyKkY23ciNafB8JFVmDroyKjtytXHCg94JnhBCXrNqpfojo3+8D+gmF4zxJQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.5.tgz", + "integrity": "sha512-jOPr/fx8lTzqszEfh46p99jUMqgPlIZ8rNKllEepumISvgfj9lUq1c7BSpVihr0L1df3lkjVHAThRPS7dIyjYg==", "requires": { "wrapped": "^1.0.1" } diff --git a/tools/node-lint-md-cli-rollup/package.json b/tools/node-lint-md-cli-rollup/package.json index be155b49e95fce..58ea5ee80a3dad 100644 --- a/tools/node-lint-md-cli-rollup/package.json +++ b/tools/node-lint-md-cli-rollup/package.json @@ -13,7 +13,7 @@ "markdown-extensions": "^1.1.1", "remark": "^11.0.2", "remark-lint": "^6.0.5", - "remark-preset-lint-node": "^1.13.0", + "remark-preset-lint-node": "^1.15.0", "unified-args": "^7.1.0" }, "main": "dist/index.js",