diff --git a/services/web/.eslintignore b/services/web/.eslintignore
index 4f0838e9a8..c4910a4e86 100644
--- a/services/web/.eslintignore
+++ b/services/web/.eslintignore
@@ -1,12 +1,7 @@
-app/js
-modules/**/app/js
modules/**/scripts
-modules/*/index.js
public/js
public/minjs
modules/**/public/js
-test/**/js
-modules/**/test/**/js
-app.js
+test/unit_frontend/js
webpack.config.*
-karma.conf.js
\ No newline at end of file
+karma.conf.js
diff --git a/services/web/.gitignore b/services/web/.gitignore
index f0c799e2dc..c5fc0338cc 100644
--- a/services/web/.gitignore
+++ b/services/web/.gitignore
@@ -36,13 +36,6 @@ Thumbs.db
node_modules/*
data/*
-app.js
-app.js.map
-app/js/*
-test/unit/js/*
-test/unit_frontend/js/*
-test/smoke/js/*
-test/acceptance/js/*
cookies.txt
requestQueueWorker.js
TpdsWorker.js
@@ -71,10 +64,11 @@ public/stylesheets/ieee-style*.css
public/stylesheets/*.map
public/minjs/
-Gemfile.lock
-
public/js/libs/require*.js
+test/unit_frontend/js/
+
+Gemfile.lock
*.swp
.DS_Store
@@ -84,8 +78,3 @@ docker-shared.yml
config/*.coffee
modules/**/Makefile
-
-modules/*/index.js
-modules/**/app/js/*
-modules/**/test/unit/js/*
-modules/**/test/acceptance/js/*
diff --git a/services/web/.prettierignore b/services/web/.prettierignore
index 4f0838e9a8..c4910a4e86 100644
--- a/services/web/.prettierignore
+++ b/services/web/.prettierignore
@@ -1,12 +1,7 @@
-app/js
-modules/**/app/js
modules/**/scripts
-modules/*/index.js
public/js
public/minjs
modules/**/public/js
-test/**/js
-modules/**/test/**/js
-app.js
+test/unit_frontend/js
webpack.config.*
-karma.conf.js
\ No newline at end of file
+karma.conf.js
diff --git a/services/web/.vscode/settings.json b/services/web/.vscode/settings.json
index 36a2567460..8cbded1a1b 100644
--- a/services/web/.vscode/settings.json
+++ b/services/web/.vscode/settings.json
@@ -2,7 +2,7 @@
"files.exclude": {
"app/js": true,
"public/js": true,
- "test/**/js": true,
+ "test/unit_frontend/js": true,
"node_modules": true,
"data": true
}
diff --git a/services/web/Gruntfile.coffee b/services/web/Gruntfile.coffee
deleted file mode 100644
index 279875c648..0000000000
--- a/services/web/Gruntfile.coffee
+++ /dev/null
@@ -1,58 +0,0 @@
-fs = require "fs"
-PackageVersions = require "./app/coffee/infrastructure/PackageVersions"
-Settings = require "settings-sharelatex"
-require('es6-promise').polyfill()
-
-module.exports = (grunt) ->
- grunt.loadNpmTasks 'grunt-contrib-requirejs'
- grunt.loadNpmTasks 'grunt-file-append'
-
- config =
-
- requirejs:
- compile:
- options:
- optimize:"uglify2"
- uglify2:
- mangle: false
- appDir: "public/js"
- baseUrl: "./"
- dir: "public/minjs"
- inlineText: false
- generateSourceMaps: true
- preserveLicenseComments: false
- paths:
- "moment": "libs/#{PackageVersions.lib('moment')}"
- "mathjax": "/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML"
- "pdfjs-dist/build/pdf": "libs/#{PackageVersions.lib('pdfjs')}/pdf"
- "ace": "#{PackageVersions.lib('ace')}"
- "fineuploader": "libs/#{PackageVersions.lib('fineuploader')}"
-
- skipDirOptimize: true
- modules: [
- {
- name: "main",
- exclude: ["libraries"]
- }, {
- name: "ide",
- exclude: ["pdfjs-dist/build/pdf", "libraries"]
- },{
- name: "libraries"
- },{
- name: "ace/mode-latex"
- },{
- name: "ace/worker-latex"
- }
-
- ]
-
- file_append:
- default_options: files: [ {
- append: '\n//ide.js is complete - used for automated testing'
- input: 'public/minjs/ide.js'
- output: 'public/minjs/ide.js'
- }]
-
- grunt.initConfig config
- grunt.registerTask 'compile:minify', 'Concat and minify the client side js', ['requirejs', "file_append"]
-
diff --git a/services/web/Gruntfile.js b/services/web/Gruntfile.js
new file mode 100644
index 0000000000..0104d5b536
--- /dev/null
+++ b/services/web/Gruntfile.js
@@ -0,0 +1,86 @@
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const fs = require('fs')
+const PackageVersions = require('./app/src/infrastructure/PackageVersions')
+const Settings = require('settings-sharelatex')
+require('es6-promise').polyfill()
+
+module.exports = function(grunt) {
+ grunt.loadNpmTasks('grunt-contrib-requirejs')
+ grunt.loadNpmTasks('grunt-file-append')
+
+ const config = {
+ requirejs: {
+ compile: {
+ options: {
+ optimize: 'uglify2',
+ uglify2: {
+ mangle: false
+ },
+ appDir: 'public/js',
+ baseUrl: './',
+ dir: 'public/minjs',
+ inlineText: false,
+ generateSourceMaps: true,
+ preserveLicenseComments: false,
+ paths: {
+ moment: `libs/${PackageVersions.lib('moment')}`,
+ mathjax: '/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML',
+ 'pdfjs-dist/build/pdf': `libs/${PackageVersions.lib('pdfjs')}/pdf`,
+ ace: `${PackageVersions.lib('ace')}`,
+ fineuploader: `libs/${PackageVersions.lib('fineuploader')}`
+ },
+
+ skipDirOptimize: true,
+ modules: [
+ {
+ name: 'main',
+ exclude: ['libraries']
+ },
+ {
+ name: 'ide',
+ exclude: ['pdfjs-dist/build/pdf', 'libraries']
+ },
+ {
+ name: 'libraries'
+ },
+ {
+ name: 'ace/mode-latex'
+ },
+ {
+ name: 'ace/worker-latex'
+ }
+ ]
+ }
+ }
+ },
+
+ file_append: {
+ default_options: {
+ files: [
+ {
+ append: '\n//ide.js is complete - used for automated testing',
+ input: 'public/minjs/ide.js',
+ output: 'public/minjs/ide.js'
+ }
+ ]
+ }
+ }
+ }
+
+ grunt.initConfig(config)
+ return grunt.registerTask(
+ 'compile:minify',
+ 'Concat and minify the client side js',
+ ['requirejs', 'file_append']
+ )
+}
diff --git a/services/web/Makefile b/services/web/Makefile
index b33a2c64c2..ccf5894cb1 100644
--- a/services/web/Makefile
+++ b/services/web/Makefile
@@ -16,23 +16,16 @@ MODULE_DIRS := $(shell find modules -mindepth 1 -maxdepth 1 -type d -not -name '
MODULE_MAKEFILES := $(MODULE_DIRS:=/Makefile)
MODULE_NAME=$(shell basename $(MODULE))
-COFFEE := node_modules/.bin/coffee -m $(COFFEE_OPTIONS)
-COFFEE := node_modules/.bin/coffee $(COFFEE_OPTIONS)
BABEL := node_modules/.bin/babel
GRUNT := node_modules/.bin/grunt
LESSC := node_modules/.bin/lessc
CLEANCSS := node_modules/.bin/cleancss
-APP_COFFEE_FILES := $(shell find app/coffee -name '*.coffee')
-FRONT_END_SRC_FILES := $(shell find public/src -name '*.js')
-TEST_COFFEE_FILES := $(shell find test/*/coffee -name '*.coffee')
-TEST_SRC_FILES := $(shell find test/*/src -name '*.js')
-MODULE_MAIN_SRC_FILES := $(shell find modules -type f -wholename '*main/index.js')
-MODULE_IDE_SRC_FILES := $(shell find modules -type f -wholename '*ide/index.js')
-COFFEE_FILES := app.coffee $(APP_COFFEE_FILES) $(FRONT_END_COFFEE_FILES) $(TEST_COFFEE_FILES)
-SRC_FILES := $(FRONT_END_SRC_FILES) $(TEST_SRC_FILES)
-JS_FILES := $(subst coffee,js,$(COFFEE_FILES))
-OUTPUT_SRC_FILES := $(subst src,js,$(SRC_FILES))
+SRC_FILES := $(shell find public/src -name '*.js')
+DIST_FILES := $(subst src,js,$(SRC_FILES))
+MAIN_SRC_FILES := $(shell find modules -type f -wholename '*main/index.js')
+IDE_SRC_FILES := $(shell find modules -type f -wholename '*ide/index.js')
+
LESS_FILES := $(shell find public/stylesheets -name '*.less')
LESSC_COMMON_FLAGS := --source-map --autoprefix="last 2 versions, ie >= 10"
CLEANCSS_FLAGS := --s0 --source-map
@@ -49,35 +42,15 @@ CSS_OL_IEEE_FILE := public/stylesheets/ieee-style.css
CSS_FILES := $(CSS_SL_FILE) $(CSS_OL_FILE) $(CSS_OL_LIGHT_FILE) $(CSS_OL_IEEE_FILE)
# The automatic variable $(@D) is the target directory name
-app.js: app.coffee
- $(COFFEE) --compile -o $(@D) $<
-
-app/js/%.js: app/coffee/%.coffee
- @mkdir -p $(@D)
- $(COFFEE) --compile -o $(@D) $<
-
public/js/%.js: public/src/%.js
@mkdir -p $(@D)
$(BABEL) $< --out-file $@
-test/unit/js/%.js: test/unit/coffee/%.coffee
- @mkdir -p $(@D)
- $(COFFEE) --compile -o $(@D) $<
-
-test/acceptance/js/%.js: test/acceptance/coffee/%.coffee
- @mkdir -p $(@D)
- $(COFFEE) --compile -o $(@D) $<
-
test/unit_frontend/js/%.js: test/unit_frontend/src/%.js
@mkdir -p $(@D)
$(BABEL) $< --out-file $@
-test/smoke/js/%.js: test/smoke/coffee/%.coffee
- @mkdir -p $(@D)
- $(COFFEE) --compile -o $(@D) $<
-
-
-public/js/ide.js: public/src/ide.js $(MODULE_IDE_SRC_FILES)
+public/js/ide.js: public/src/ide.js $(IDE_SRC_FILES)
@echo Compiling and injecting module includes into public/js/ide.js
@INCLUDES=""; \
for dir in modules/*; \
@@ -92,7 +65,7 @@ public/js/ide.js: public/src/ide.js $(MODULE_IDE_SRC_FILES)
sed -e s=\'__IDE_CLIENTSIDE_INCLUDES__\'=$$INCLUDES= \
> $@
-public/js/main.js: public/src/main.js $(MODULE_MAIN_SRC_FILES)
+public/js/main.js: public/src/main.js $(MAIN_SRC_FILES)
@echo Compiling and injecting module includes into public/js/main.js
@INCLUDES=""; \
for dir in modules/*; \
@@ -114,7 +87,7 @@ css_full: $(CSS_FILES)
css: $(CSS_OL_FILE)
-minify: $(CSS_FILES) $(JS_FILES) $(OUTPUT_SRC_FILES)
+minify: $(CSS_FILES) $(DIST_FILES)
$(GRUNT) compile:minify
$(MAKE) minify_css
$(MAKE) minify_es
@@ -128,18 +101,11 @@ minify_css: $(CSS_FILES)
minify_es:
npm -q run webpack:production
-compile: compile_app $(OUTPUT_SRC_FILES) css public/js/main.js public/js/ide.js
-
-compile_app: $(JS_FILES)
+compile: $(DIST_FILES) css public/js/main.js public/js/ide.js
@$(MAKE) compile_modules
compile_full:
- $(COFFEE) -c -p app.coffee > app.js
- $(COFFEE) -o app/js -c app/coffee
$(BABEL) public/src --out-dir public/js
- $(COFFEE) -o test/acceptance/js -c test/acceptance/coffee
- $(COFFEE) -o test/smoke/js -c test/smoke/coffee
- $(COFFEE) -o test/unit/js -c test/unit/coffee
$(BABEL) test/unit_frontend/src --out-dir test/unit_frontend/js
rm -f public/js/ide.js public/js/main.js # We need to generate ide.js, main.js manually later
$(MAKE) css_full
@@ -149,9 +115,6 @@ compile_full:
compile_css_full:
$(MAKE) css_full
-compile_module:
- cd modules/$(MODULE_NAME) && $(MAKE) compile
-
compile_modules: $(MODULE_MAKEFILES)
@set -e; \
for dir in $(MODULE_DIRS); \
@@ -184,33 +147,18 @@ $(MODULE_MAKEFILES): Makefile.module
cp Makefile.module $$makefile; \
done
-clean: clean_app clean_frontend clean_css clean_tests clean_modules
-
-clean_app:
- rm -f app.js app.js.map
- rm -rf app/js
+clean: clean_frontend clean_css clean_tests
clean_frontend:
rm -rf public/js/{analytics,directives,es,filters,ide,main,modules,services,utils}
rm -f public/js/*.{js,map}
-clean_tests:
- rm -rf test/unit/js
- rm -rf test/unit_frontend/js
- rm -rf test/acceptance/js
-
-clean_modules:
- for dir in modules/*; \
- do \
- rm -f $$dir/index.js; \
- rm -rf $$dir/app/js; \
- rm -rf $$dir/test/unit/js; \
- rm -rf $$dir/test/acceptance/js; \
- done
-
clean_css:
rm -f public/stylesheets/*.css*
+clean_tests:
+ rm -rf test/unit_frontend/js
+
clean_ci:
$(DOCKER_COMPOSE) down -v -t 0
docker container list | grep 'days ago' | cut -d ' ' -f 1 - | xargs -r docker container stop
@@ -219,12 +167,12 @@ clean_ci:
test: test_unit test_frontend test_acceptance
-test_module: compile_module test_unit_module_run test_acceptance_module_run
+test_module: test_unit_module_run test_acceptance_module_run
test_unit:
@[ ! -d test/unit ] && echo "web has no unit tests" || COMPOSE_PROJECT_NAME=unit_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --name unit_test_$(BUILD_DIR_NAME) --rm test_unit
-test_unit_module: compile_module test_unit_module_run
+test_unit_module: test_unit_module_run
test_unit_module_run:
COMPOSE_PROJECT_NAME=unit_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --name unit_test_$(BUILD_DIR_NAME) --rm test_unit bin/unit_test_module $(MODULE_NAME) --grep=$(MOCHA_GREP)
@@ -241,17 +189,17 @@ test_frontend_run:
test_frontend_build_run: build_test_frontend test_frontend_run
-test_acceptance: compile test_acceptance_app_run test_acceptance_modules_run
+test_acceptance: test_acceptance_app_run test_acceptance_modules_run
-test_acceptance_app: compile test_acceptance_app_run
+test_acceptance_app: test_acceptance_app_run
-test_acceptance_module: compile_module test_acceptance_module_run
+test_acceptance_module: test_acceptance_module_run
test_acceptance_run: test_acceptance_app_run test_acceptance_modules_run
test_acceptance_app_run:
COMPOSE_PROJECT_NAME=acceptance_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) down -v -t 0
- COMPOSE_PROJECT_NAME=acceptance_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --rm test_acceptance npm -q run test:acceptance:run_dir test/acceptance/js
+ COMPOSE_PROJECT_NAME=acceptance_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --rm test_acceptance npm -q run test:acceptance:run_dir test/acceptance/src
COMPOSE_PROJECT_NAME=acceptance_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) down -v -t 0
test_acceptance_modules_run:
diff --git a/services/web/Makefile.module b/services/web/Makefile.module
index 29af9d297a..4a165c7e17 100644
--- a/services/web/Makefile.module
+++ b/services/web/Makefile.module
@@ -1,22 +1,16 @@
MODULE_NAME := $(notdir $(shell pwd))
MODULE_DIR := modules/$(MODULE_NAME)
PROJECT_NAME = web
-COFFEE := ../../node_modules/.bin/coffee
BABEL := ../../node_modules/.bin/babel
-APP_COFFEE_FILES := $(shell [ -e app/coffee ] && find app/coffee -name '*.coffee') \
- $(shell [ -e test/unit/coffee ] && find test/unit/coffee -name '*.coffee') \
- $(shell [ -e test/acceptance/coffee ] && find test/acceptance/coffee -name '*.coffee')
-APP_JS_FILES := $(subst coffee,js,$(APP_COFFEE_FILES))
-
IDE_SRC_FILES := $(shell [ -e public/src/ide ] && find public/src/ide -name '*.js')
-IDE_OUTPUT_FILES := $(subst public/src/ide,../../public/js/ide/$(MODULE_NAME),$(IDE_SRC_FILES))
+IDE_DIST_FILES := $(subst public/src/ide,../../public/js/ide/$(MODULE_NAME),$(IDE_SRC_FILES))
IDE_TEST_SRC_FILES := $(shell [ -e test/unit_frontend/src/ide ] && find test/unit_frontend/src/ide -name '*.js')
-IDE_TEST_OUTPUT_FILES := $(subst test/unit_frontend/src/ide,../../test/unit_frontend/js/ide/$(MODULE_NAME),$(IDE_TEST_SRC_FILES))
+IDE_TEST_DIST_FILES := $(subst test/unit_frontend/src/ide,../../test/unit_frontend/js/ide/$(MODULE_NAME),$(IDE_TEST_SRC_FILES))
MAIN_SRC_FILES := $(shell [ -e public/src/main ] && find public/src/main -name '*.js')
-MAIN_OUTPUT_FILES := $(subst public/src/main,../../public/js/main/$(MODULE_NAME),$(MAIN_SRC_FILES))
+MAIN_DIST_FILES := $(subst public/src/main,../../public/js/main/$(MODULE_NAME),$(MAIN_SRC_FILES))
DOCKER_COMPOSE_FLAGS ?= -f docker-compose.yml
DOCKER_COMPOSE_MODULE_FLAGS := ${DOCKER_COMPOSE_FLAGS} -f $(MODULE_DIR)/docker-compose.yml
@@ -28,18 +22,6 @@ DOCKER_COMPOSE := cd ../../ && \
MOCHA_GREP=${MOCHA_GREP} \
docker-compose ${DOCKER_COMPOSE_MODULE_FLAGS}
-app/js/%.js: app/coffee/%.coffee
- @mkdir -p $(dir $@)
- $(COFFEE) --compile --print $< > $@
-
-test/unit/js/%.js: test/unit/coffee/%.coffee
- @mkdir -p $(dir $@)
- $(COFFEE) --compile --print $< > $@
-
-test/acceptance/js/%.js: test/acceptance/coffee/%.coffee
- @mkdir -p $(dir $@)
- $(COFFEE) --compile --print $< > $@
-
../../test/unit_frontend/js/ide/$(MODULE_NAME)/%.js: test/unit_frontend/src/ide/%.js
@mkdir -p $(dir $@)
$(BABEL) $< --out-file $@
@@ -52,20 +34,14 @@ test/acceptance/js/%.js: test/acceptance/coffee/%.coffee
@mkdir -p $(dir $@)
$(BABEL) $< --out-file $@
-index.js: index.coffee
- $(COFFEE) --compile --print $< > $@
-
-compile: $(APP_JS_FILES) $(IDE_OUTPUT_FILES) $(MAIN_OUTPUT_FILES) $(IDE_TEST_OUTPUT_FILES) index.js
+compile: $(IDE_DIST_FILES) $(MAIN_DIST_FILES) $(IDE_TEST_DIST_FILES)
@echo > /dev/null
compile_full:
- if [ -e app/coffee ]; then $(COFFEE) -o app/js -c app/coffee; fi
- if [ -e test/unit/coffee ]; then $(COFFEE) -o test/unit/js -c test/unit/coffee; fi
- if [ -e test/acceptance/coffee ]; then $(COFFEE) -o test/acceptance/js -c test/acceptance/coffee; fi
if [ -e public/src/ide ]; then $(BABEL) public/src/ide --out-dir ../../public/js/ide/$(MODULE_NAME); fi
if [ -e public/src/main ]; then $(BABEL) public/src/main --out-dir ../../public/js/main/$(MODULE_NAME); fi
if [ -e test/unit_frontend/src/ide ]; then $(BABEL) test/unit_frontend/src/ide --out-dir ../../test/unit_frontend/js/ide/$(MODULE_NAME); fi
- @$(MAKE) compile
+ @$(MAKE) compile # Anything else missed
test_acceptance:
- ${DOCKER_COMPOSE} run --rm test_acceptance npm -q run test:acceptance:run_dir -- ${MOCHA_ARGS} $(MODULE_DIR)/test/acceptance/js
+ ${DOCKER_COMPOSE} run --rm test_acceptance npm -q run test:acceptance:run_dir -- ${MOCHA_ARGS} $(MODULE_DIR)/test/acceptance/src
diff --git a/services/web/app.coffee b/services/web/app.coffee
deleted file mode 100644
index e9033f8d1b..0000000000
--- a/services/web/app.coffee
+++ /dev/null
@@ -1,41 +0,0 @@
-metrics = require("metrics-sharelatex")
-metrics.initialize(process.env['METRICS_APP_NAME'] or "web")
-Settings = require('settings-sharelatex')
-logger = require 'logger-sharelatex'
-logger.initialize(process.env['METRICS_APP_NAME'] or "web")
-logger.logger.serializers.user = require("./app/js/infrastructure/LoggerSerializers").user
-logger.logger.serializers.docs = require("./app/js/infrastructure/LoggerSerializers").docs
-logger.logger.serializers.files = require("./app/js/infrastructure/LoggerSerializers").files
-logger.logger.serializers.project = require("./app/js/infrastructure/LoggerSerializers").project
-if Settings.sentry?.dsn?
- logger.initializeErrorReporting(Settings.sentry.dsn)
-
-metrics.memory.monitor(logger)
-Server = require("./app/js/infrastructure/Server")
-
-argv = require("optimist")
- .options("user", {alias : "u", description : "Run the server with permissions of the specified user"})
- .options("group", {alias : "g", description : "Run the server with permissions of the specified group"})
- .usage("Usage: $0")
- .argv
-
-if Settings.catchErrors
- process.removeAllListeners "uncaughtException"
- process.on "uncaughtException", (error) ->
- logger.error err: error, "uncaughtException"
-
-port = Settings.port or Settings.internal?.web?.port or 3000
-host = Settings.internal.web.host or "localhost"
-if !module.parent # Called directly
- Server.server.listen port, host, ->
- logger.info "web starting up, listening on #{host}:#{port}"
- logger.info("#{require('http').globalAgent.maxSockets} sockets enabled")
- if argv.user
- process.setuid argv.user
- logger.info "Running as user: #{argv.user}"
- if argv.group
- process.setgid argv.group
- logger.info "Running as group: #{argv.group}"
-
-module.exports = Server.server
-
diff --git a/services/web/app.js b/services/web/app.js
new file mode 100644
index 0000000000..2b92330cd9
--- /dev/null
+++ b/services/web/app.js
@@ -0,0 +1,77 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const metrics = require('metrics-sharelatex')
+metrics.initialize(process.env['METRICS_APP_NAME'] || 'web')
+const Settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+logger.initialize(process.env['METRICS_APP_NAME'] || 'web')
+logger.logger.serializers.user = require('./app/src/infrastructure/LoggerSerializers').user
+logger.logger.serializers.docs = require('./app/src/infrastructure/LoggerSerializers').docs
+logger.logger.serializers.files = require('./app/src/infrastructure/LoggerSerializers').files
+logger.logger.serializers.project = require('./app/src/infrastructure/LoggerSerializers').project
+if ((Settings.sentry != null ? Settings.sentry.dsn : undefined) != null) {
+ logger.initializeErrorReporting(Settings.sentry.dsn)
+}
+
+metrics.memory.monitor(logger)
+const Server = require('./app/src/infrastructure/Server')
+
+const { argv } = require('optimist')
+ .options('user', {
+ alias: 'u',
+ description: 'Run the server with permissions of the specified user'
+ })
+ .options('group', {
+ alias: 'g',
+ description: 'Run the server with permissions of the specified group'
+ })
+ .usage('Usage: $0')
+
+if (Settings.catchErrors) {
+ process.removeAllListeners('uncaughtException')
+ process.on('uncaughtException', error =>
+ logger.error({ err: error }, 'uncaughtException')
+ )
+}
+
+const port =
+ Settings.port ||
+ __guard__(
+ Settings.internal != null ? Settings.internal.web : undefined,
+ x => x.port
+ ) ||
+ 3000
+const host = Settings.internal.web.host || 'localhost'
+if (!module.parent) {
+ // Called directly
+ Server.server.listen(port, host, function() {
+ logger.info(`web starting up, listening on ${host}:${port}`)
+ logger.info(`${require('http').globalAgent.maxSockets} sockets enabled`)
+ if (argv.user) {
+ process.setuid(argv.user)
+ logger.info(`Running as user: ${argv.user}`)
+ }
+ if (argv.group) {
+ process.setgid(argv.group)
+ return logger.info(`Running as group: ${argv.group}`)
+ }
+ })
+}
+
+module.exports = Server.server
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee b/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee
deleted file mode 100644
index e407feb488..0000000000
--- a/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee
+++ /dev/null
@@ -1,42 +0,0 @@
-AnalyticsManager = require "./AnalyticsManager"
-Errors = require "../Errors/Errors"
-AuthenticationController = require("../Authentication/AuthenticationController")
-InstitutionsAPI = require("../Institutions/InstitutionsAPI")
-GeoIpLookup = require '../../infrastructure/GeoIpLookup'
-
-module.exports = AnalyticsController =
- updateEditingSession: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- projectId = req.params.projectId
- countryCode = null
-
- if userId?
- GeoIpLookup.getDetails req.ip, (err, geoDetails) ->
- if geoDetails?.country_code? and geoDetails.country_code != ""
- countryCode = geoDetails.country_code
- AnalyticsManager.updateEditingSession userId, projectId, countryCode, (error) ->
- respondWith(error, res, next)
- else
- res.send 204
-
- recordEvent: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req) or req.sessionID
- AnalyticsManager.recordEvent user_id, req.params.event, req.body, (error) ->
- respondWith(error, res, next)
-
- licences: (req, res, next) ->
- {resource_id, start_date, end_date, lag} = req.query
- InstitutionsAPI.getInstitutionLicences resource_id, start_date, end_date, lag, (error, licences) ->
- if error?
- next(error)
- else
- res.send licences
-
-respondWith = (error, res, next) ->
- if error instanceof Errors.ServiceNotConfiguredError
- # ignore, no-op
- res.send(204)
- else if error?
- next(error)
- else
- res.send 204
diff --git a/services/web/app/coffee/Features/Analytics/AnalyticsManager.coffee b/services/web/app/coffee/Features/Analytics/AnalyticsManager.coffee
deleted file mode 100644
index ebb985f7b5..0000000000
--- a/services/web/app/coffee/Features/Analytics/AnalyticsManager.coffee
+++ /dev/null
@@ -1,109 +0,0 @@
-settings = require "settings-sharelatex"
-logger = require "logger-sharelatex"
-_ = require "underscore"
-request = require "requestretry"
-Errors = require '../Errors/Errors'
-
-
-makeFaultTolerantRequest = (userId, options, callback) ->
- if userId+"" == settings.smokeTest?.userId+""
- return callback()
-
- options = Object.assign(options, {
- delayStrategy: exponentialBackoffStrategy()
- timeout: 30000
- })
-
- if settings.overleaf?
- options.qs = Object.assign({}, options.qs, { fromV2: 1 })
-
- makeRequest options, (err) ->
- if err?
- logger.err { err: err }, 'Request to analytics failed'
-
- callback() # Do not wait for all the attempts
-
-makeRequest = (opts, callback)->
- if settings.apis?.analytics?.url?
- urlPath = opts.url
- opts.url = "#{settings.apis.analytics.url}#{urlPath}"
- request opts, callback
- else
- callback(new Errors.ServiceNotConfiguredError('Analytics service not configured'))
-
-
-# Set an exponential backoff to retry calls to analytics. First retry will
-# happen after 4s, then 8, 16, 32, 64...
-exponentialBackoffStrategy = () ->
- attempts = 1 # This won't be called until there has been 1 failure
-
- () ->
- attempts += 1
- exponentialBackoffDelay(attempts)
-
-exponentialBackoffDelay = (attempts) ->
- delay = 2 ** attempts * 1000
-
- logger.warn "Error comunicating with the analytics service. " +
- "Will try again attempt #{attempts} in #{delay}ms"
-
- delay
-
-
-module.exports =
-
- identifyUser: (user_id, old_user_id, callback = (error)->)->
- opts =
- body:
- old_user_id:old_user_id
- json:true
- method:"POST"
- timeout:1000
- url: "/user/#{user_id}/identify"
- makeRequest opts, callback
-
- recordEvent: (user_id, event, segmentation = {}, callback = (error) ->) ->
- opts =
- body:
- event:event
- segmentation:segmentation
- json:true
- method:"POST"
- url: "/user/#{user_id}/event"
- maxAttempts: 7 # Give up after ~ 8min
-
- makeFaultTolerantRequest user_id, opts, callback
-
-
- updateEditingSession: (userId, projectId, countryCode, callback = (error) ->) ->
- query =
- userId: userId
- projectId: projectId
-
- if countryCode
- query.countryCode = countryCode
-
- opts =
- method: "PUT"
- url: "/editingSession"
- qs: query
- maxAttempts: 6 # Give up after ~ 4min
-
- makeFaultTolerantRequest userId, opts, callback
-
-
- getLastOccurrence: (user_id, event, callback = (error) ->) ->
- opts =
- body:
- event:event
- json:true
- method:"POST"
- timeout:1000
- url: "/user/#{user_id}/event/last_occurrence"
- makeRequest opts, (err, response, body)->
- if err?
- console.log response, opts
- logger.err {user_id, err}, "error getting last occurance of event"
- return callback err
- else
- return callback null, body
diff --git a/services/web/app/coffee/Features/Analytics/AnalyticsProxy.coffee b/services/web/app/coffee/Features/Analytics/AnalyticsProxy.coffee
deleted file mode 100644
index f513db8414..0000000000
--- a/services/web/app/coffee/Features/Analytics/AnalyticsProxy.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-settings = require "settings-sharelatex"
-Errors = require '../Errors/Errors'
-httpProxy = require 'express-http-proxy'
-URL = require 'url'
-
-module.exports =
- call: (basePath) ->
- analyticsUrl = settings?.apis?.analytics?.url
- if analyticsUrl?
- httpProxy(analyticsUrl,
- proxyReqPathResolver: (req) ->
- requestPath = URL.parse(req.url).path
- "#{basePath}#{requestPath}"
- proxyReqOptDecorator: (proxyReqOpts, srcReq) ->
- proxyReqOpts.headers = {} # unset all headers
- proxyReqOpts
- )
- else
- (req, res, next) ->
- next(new Errors.ServiceNotConfiguredError('Analytics service not configured'))
diff --git a/services/web/app/coffee/Features/Analytics/AnalyticsRouter.coffee b/services/web/app/coffee/Features/Analytics/AnalyticsRouter.coffee
deleted file mode 100644
index 57b131326f..0000000000
--- a/services/web/app/coffee/Features/Analytics/AnalyticsRouter.coffee
+++ /dev/null
@@ -1,26 +0,0 @@
-AuthenticationController = require './../Authentication/AuthenticationController'
-AnalyticsController = require('./AnalyticsController')
-AnalyticsProxy = require('./AnalyticsProxy')
-
-module.exports =
- apply: (webRouter, privateApiRouter, publicApiRouter) ->
- webRouter.post '/event/:event', AnalyticsController.recordEvent
-
- webRouter.put '/editingSession/:projectId',
- AnalyticsController.updateEditingSession
-
- publicApiRouter.use '/analytics/graphs',
- AuthenticationController.httpAuth,
- AnalyticsProxy.call('/graphs')
-
- publicApiRouter.use '/analytics/recentTeamActivity',
- AuthenticationController.httpAuth,
- AnalyticsProxy.call('/recentTeamActivity')
-
- publicApiRouter.use '/analytics/recentV1TemplateIdsActivity',
- AuthenticationController.httpAuth,
- AnalyticsProxy.call('/recentV1TemplateIdsActivity')
-
- publicApiRouter.use '/analytics/uniExternalCollaboration',
- AuthenticationController.httpAuth,
- AnalyticsProxy.call('/uniExternalCollaboration')
diff --git a/services/web/app/coffee/Features/Announcements/AnnouncementsController.coffee b/services/web/app/coffee/Features/Announcements/AnnouncementsController.coffee
deleted file mode 100644
index 9c3a9f4deb..0000000000
--- a/services/web/app/coffee/Features/Announcements/AnnouncementsController.coffee
+++ /dev/null
@@ -1,24 +0,0 @@
-AnnouncementsHandler = require("./AnnouncementsHandler")
-AuthenticationController = require("../Authentication/AuthenticationController")
-logger = require("logger-sharelatex")
-settings = require("settings-sharelatex")
-
-module.exports =
-
- getUndreadAnnouncements: (req, res, next)->
- if !settings?.apis?.analytics?.url? or !settings.apis.blog.url?
- return res.json []
-
- user = AuthenticationController.getSessionUser(req)
- logger.log {user_id:user?._id}, "getting unread announcements"
- AnnouncementsHandler.getUnreadAnnouncements user, (err, announcements)->
- if err?
- logger.err {err:err, user_id:user._id}, "unable to get unread announcements"
- next(err)
- else
- res.json announcements
-
-
-
-
-
diff --git a/services/web/app/coffee/Features/Announcements/AnnouncementsHandler.coffee b/services/web/app/coffee/Features/Announcements/AnnouncementsHandler.coffee
deleted file mode 100644
index ec3e92e980..0000000000
--- a/services/web/app/coffee/Features/Announcements/AnnouncementsHandler.coffee
+++ /dev/null
@@ -1,67 +0,0 @@
-AnalyticsManager = require("../Analytics/AnalyticsManager")
-BlogHandler = require("../Blog/BlogHandler")
-logger = require("logger-sharelatex")
-settings = require("settings-sharelatex")
-async = require("async")
-_ = require("lodash")
-
-module.exports = AnnouncementsHandler =
-
- _domainSpecificAnnouncements : (email)->
- domainSpecific = _.filter settings?.domainAnnouncements, (domainAnnouncment)->
- matches = _.filter domainAnnouncment.domains, (domain)->
- return email.indexOf(domain) != -1
- return matches.length > 0 and domainAnnouncment.id?
- return domainSpecific or []
-
-
- getUnreadAnnouncements : (user, callback = (err, announcements)->)->
- if !user? and !user._id?
- return callback("user not supplied")
-
- timestamp = user._id.toString().substring(0,8)
- userSignupDate = new Date( parseInt( timestamp, 16 ) * 1000 )
-
- async.parallel {
- lastEvent: (cb)->
- AnalyticsManager.getLastOccurrence user._id, "announcement-alert-dismissed", cb
- announcements: (cb)->
- BlogHandler.getLatestAnnouncements cb
- }, (err, results)->
- if err?
- logger.err err:err, user_id:user._id, "error getting unread announcements"
- return callback(err)
-
- domainSpecific = AnnouncementsHandler._domainSpecificAnnouncements(user?.email)
-
- domainSpecific = _.map domainSpecific, (domainAnnouncment)->
- try
- domainAnnouncment.date = new Date(domainAnnouncment.date)
- return domainAnnouncment
- catch e
- return callback(e)
-
- announcements = results.announcements
- announcements = _.union announcements, domainSpecific
- announcements = _.sortBy(announcements, "date").reverse()
-
- lastSeenBlogId = results?.lastEvent?.segmentation?.blogPostId
-
- announcementIndex = _.findIndex announcements, (announcement)->
- announcement.id == lastSeenBlogId
-
- announcements = _.map announcements, (announcement, index)->
- if announcement.date < userSignupDate
- read = true
- else if announcementIndex == -1
- read = false
- else if index >= announcementIndex
- read = true
- else
- read = false
- announcement.read = read
- return announcement
-
- logger.log announcementsLength:announcements?.length, user_id:user?._id, "returning announcements"
-
- callback null, announcements
diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee
deleted file mode 100644
index 408ae43400..0000000000
--- a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee
+++ /dev/null
@@ -1,321 +0,0 @@
-AuthenticationManager = require ("./AuthenticationManager")
-LoginRateLimiter = require("../Security/LoginRateLimiter")
-UserUpdater = require "../User/UserUpdater"
-Metrics = require('metrics-sharelatex')
-logger = require("logger-sharelatex")
-querystring = require('querystring')
-Url = require("url")
-Settings = require "settings-sharelatex"
-basicAuth = require('basic-auth-connect')
-UserHandler = require("../User/UserHandler")
-UserSessionsManager = require("../User/UserSessionsManager")
-Analytics = require "../Analytics/AnalyticsManager"
-passport = require 'passport'
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-SudoModeHandler = require '../SudoMode/SudoModeHandler'
-V1Api = require "../V1/V1Api"
-{User} = require "../../models/User"
-{ URL } = require('url')
-
-module.exports = AuthenticationController =
-
- serializeUser: (user, callback) ->
- lightUser =
- _id: user._id
- first_name: user.first_name
- last_name: user.last_name
- isAdmin: user.isAdmin
- staffAccess: user.staffAccess
- email: user.email
- referal_id: user.referal_id
- session_created: (new Date()).toISOString()
- ip_address: user._login_req_ip
- must_reconfirm: user.must_reconfirm
- v1_id: user.overleaf?.id
- callback(null, lightUser)
-
- deserializeUser: (user, cb) ->
- cb(null, user)
-
- afterLoginSessionSetup: (req, user, callback=(err)->) ->
- req.login user, (err) ->
- if err?
- logger.err {user_id: user._id, err}, "error from req.login"
- return callback(err)
- # Regenerate the session to get a new sessionID (cookie value) to
- # protect against session fixation attacks
- oldSession = req.session
- req.session.destroy (err) ->
- if err?
- logger.err {user_id: user._id, err}, "error when trying to destroy old session"
- return callback(err)
- req.sessionStore.generate(req)
- for key, value of oldSession
- req.session[key] = value unless key == '__tmp'
- # copy to the old `session.user` location, for backward-comptability
- req.session.user = req.session.passport.user
- req.session.save (err) ->
- if err?
- logger.err {user_id: user._id}, "error saving regenerated session after login"
- return callback(err)
- UserSessionsManager.trackSession(user, req.sessionID, () ->)
- callback(null)
-
- passportLogin: (req, res, next) ->
- # This function is middleware which wraps the passport.authenticate middleware,
- # so we can send back our custom `{message: {text: "", type: ""}}` responses on failure,
- # and send a `{redir: ""}` response on success
- passport.authenticate('local', (err, user, info) ->
- if err?
- return next(err)
- if user # `user` is either a user object or false
- AuthenticationController.finishLogin(user, req, res, next)
- else
- if info.redir?
- res.json {redir: info.redir}
- else
- res.json message: info
- )(req, res, next)
-
- finishLogin: (user, req, res, next) ->
- return res.redirect('/login') if user == false # OAuth2 'state' mismatch
- if user.must_reconfirm
- AuthenticationController._redirectToReconfirmPage req, res, user
- else
- redir = AuthenticationController._getRedirectFromSession(req) || "/project"
- AuthenticationController._loginAsyncHandlers(req, user)
- AuthenticationController.afterLoginSessionSetup req, user, (err) ->
- if err?
- return next(err)
- SudoModeHandler.activateSudoMode user._id, (err) ->
- if err?
- logger.err {err, user_id: user._id}, "Error activating Sudo Mode on login, continuing"
- AuthenticationController._clearRedirectFromSession(req)
- if req.headers?['accept']?.match(/^application\/json.*$/)
- res.json {redir: redir}
- else
- res.redirect(redir)
-
- doPassportLogin: (req, username, password, done) ->
- email = username.toLowerCase()
- Modules = require "../../infrastructure/Modules"
- Modules.hooks.fire 'preDoPassportLogin', req, email, (err, infoList) ->
- return next(err) if err?
- info = infoList.find((i) => i?)
- if info?
- return done(null, false, info)
- LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
- return done(err) if err?
- if !isAllowed
- logger.log email:email, "too many login requests"
- return done(null, null, {text: req.i18n.translate("to_many_login_requests_2_mins"), type: 'error'})
- AuthenticationManager.authenticate email: email, password, (error, user) ->
- return done(error) if error?
- if user?
- # async actions
- return done(null, user)
- else
- AuthenticationController._recordFailedLogin()
- logger.log email: email, "failed log in"
- return done(
- null,
- false,
- {text: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'}
- )
-
- _loginAsyncHandlers: (req, user) ->
- UserHandler.setupLoginData(user, ()->)
- LoginRateLimiter.recordSuccessfulLogin(user.email)
- AuthenticationController._recordSuccessfulLogin(user._id)
- AuthenticationController.ipMatchCheck(req, user)
- Analytics.recordEvent(user._id, "user-logged-in", {ip:req.ip})
- Analytics.identifyUser(user._id, req.sessionID)
- logger.log email: user.email, user_id: user._id.toString(), "successful log in"
- req.session.justLoggedIn = true
- # capture the request ip for use when creating the session
- user._login_req_ip = req.ip
-
- ipMatchCheck: (req, user) ->
- if req.ip != user.lastLoginIp
- NotificationsBuilder.ipMatcherAffiliation(user._id).create(req.ip)
- UserUpdater.updateUser user._id.toString(), {
- $set: { "lastLoginIp": req.ip }
- }
-
- setInSessionUser: (req, props) ->
- for key, value of props
- if req?.session?.passport?.user?
- req.session.passport.user[key] = value
- if req?.session?.user?
- req.session.user[key] = value
-
- isUserLoggedIn: (req) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- return (user_id not in [null, undefined, false])
-
- # TODO: perhaps should produce an error if the current user is not present
- getLoggedInUserId: (req) ->
- user = AuthenticationController.getSessionUser(req)
- if user
- return user._id
- else
- return null
-
- getLoggedInUserV1Id: (req) ->
- user = AuthenticationController.getSessionUser(req)
- if user?.v1_id?
- return user.v1_id
- else
- return null
-
- getSessionUser: (req) ->
- if req?.session?.user?
- return req.session.user
- else if req?.session?.passport?.user
- return req.session.passport.user
- else
- return null
-
- requireLogin: () ->
- doRequest = (req, res, next = (error) ->) ->
- if !AuthenticationController.isUserLoggedIn(req)
- AuthenticationController._redirectToLoginOrRegisterPage(req, res)
- else
- req.user = AuthenticationController.getSessionUser(req)
- next()
-
- return doRequest
-
- # access tokens might be associated with user stubs if the user is
- # not yet migrated to v2. if api can work with user stubs then set
- # allowUserStub true when adding middleware to route.
- requireOauth: (allowUserStub=false) ->
- # require this here because module may not be included in some versions
- Oauth2Server = require "../../../../modules/oauth2-server/app/js/Oauth2Server"
- return (req, res, next = (error) ->) ->
- request = new Oauth2Server.Request(req)
- response = new Oauth2Server.Response(res)
- Oauth2Server.server.authenticate request, response, {}, (err, token) ->
- if err?
- # use a 401 status code for malformed header for git-bridge
- err.code = 401 if err.code == 400 and err.message == 'Invalid request: malformed authorization header'
- # fall back to v1 on invalid token
- return AuthenticationController._requireOauthV1Fallback req, res, next if err.code == 401
- # send all other errors
- return res.status(err.code).json({error: err.name, error_description: err.message})
- return res.sendStatus 401 if token.user.constructor.modelName == "UserStub" and !allowUserStub
- req.oauth =
- access_token: token.accessToken
- req.oauth_token = token
- req.oauth_user = token.user
- return next()
-
- _requireOauthV1Fallback: (req, res, next) ->
- return res.sendStatus 401 unless req.token?
- options =
- expectedStatusCodes: [401]
- json: token: req.token
- method: "POST"
- uri: "/api/v1/sharelatex/oauth_authorize"
- V1Api.request options, (error, response, body) ->
- return next(error) if error?
- return res.status(401).json({error: "invalid_token"}) unless body?.user_profile?.id
- User.findOne { "overleaf.id": body.user_profile.id }, (error, user) ->
- return next(error) if error?
- return res.status(401).json({error: "invalid_token"}) unless user?
- req.oauth =
- access_token: body.access_token
- req.oauth_user = user
- next()
-
- _globalLoginWhitelist: []
- addEndpointToLoginWhitelist: (endpoint) ->
- AuthenticationController._globalLoginWhitelist.push endpoint
-
- requireGlobalLogin: (req, res, next) ->
- if req._parsedUrl.pathname in AuthenticationController._globalLoginWhitelist
- return next()
-
- if req.headers['authorization']?
- return AuthenticationController.httpAuth(req, res, next)
- else if AuthenticationController.isUserLoggedIn(req)
- return next()
- else
- logger.log url:req.url, "user trying to access endpoint not in global whitelist"
- AuthenticationController.setRedirectInSession(req)
- return res.redirect "/login"
-
- httpAuth: basicAuth (user, pass)->
- isValid = Settings.httpAuthUsers[user] == pass
- if !isValid
- logger.err user:user, pass:pass, "invalid login details"
- return isValid
-
- setRedirectInSession: (req, value) ->
- if !value?
- value = if Object.keys(req.query).length > 0 then "#{req.path}?#{querystring.stringify(req.query)}" else "#{req.path}"
- if (
- req.session? &&
- !/^\/(socket.io|js|stylesheets|img)\/.*$/.test(value) &&
- !/^.*\.(png|jpeg|svg)$/.test(value)
- )
- safePath = AuthenticationController._getSafeRedirectPath(value)
- req.session.postLoginRedirect = safePath
-
- _redirectToLoginOrRegisterPage: (req, res)->
- if (req.query.zipUrl? or req.query.project_name? or req.path == '/user/subscription/new')
- return AuthenticationController._redirectToRegisterPage(req, res)
- else
- AuthenticationController._redirectToLoginPage(req, res)
-
- _redirectToLoginPage: (req, res) ->
- logger.log url: req.url, "user not logged in so redirecting to login page"
- AuthenticationController.setRedirectInSession(req)
- url = "/login?#{querystring.stringify(req.query)}"
- res.redirect url
- Metrics.inc "security.login-redirect"
-
- _redirectToReconfirmPage: (req, res, user) ->
- logger.log url: req.url, "user needs to reconfirm so redirecting to reconfirm page"
- req.session.reconfirm_email = user?.email
- redir = "/user/reconfirm"
- if req.headers?['accept']?.match(/^application\/json.*$/)
- res.json {redir: redir}
- else
- res.redirect redir
-
- _redirectToRegisterPage: (req, res) ->
- logger.log url: req.url, "user not logged in so redirecting to register page"
- AuthenticationController.setRedirectInSession(req)
- url = "/register?#{querystring.stringify(req.query)}"
- res.redirect url
- Metrics.inc "security.login-redirect"
-
- _recordSuccessfulLogin: (user_id, callback = (error) ->) ->
- UserUpdater.updateUser user_id.toString(), {
- $set: { "lastLoggedIn": new Date() },
- $inc: { "loginCount": 1 }
- }, (error) ->
- callback(error) if error?
- Metrics.inc "user.login.success"
- callback()
-
- _recordFailedLogin: (callback = (error) ->) ->
- Metrics.inc "user.login.failed"
- callback()
-
- _getRedirectFromSession: (req) ->
- value = req?.session?.postLoginRedirect
- safePath = AuthenticationController._getSafeRedirectPath(value) if value
- return safePath || null
-
- _clearRedirectFromSession: (req) ->
- if req.session?
- delete req.session.postLoginRedirect
-
- _getSafeRedirectPath: (value) ->
- baseURL = Settings.siteUrl # base URL is required to construct URL from path
- url = new URL(value, baseURL)
- safePath = "#{url.pathname}#{url.search}#{url.hash}"
- safePath = undefined if safePath == '/'
- safePath
diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee
deleted file mode 100644
index 317fe00e73..0000000000
--- a/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee
+++ /dev/null
@@ -1,136 +0,0 @@
-Settings = require "settings-sharelatex"
-User = require("../../models/User").User
-{db, ObjectId} = require("../../infrastructure/mongojs")
-crypto = require 'crypto'
-bcrypt = require 'bcrypt'
-EmailHelper = require("../Helpers/EmailHelper")
-Errors = require("../Errors/Errors")
-UserGetter = require("../User/UserGetter")
-V1Handler = require '../V1/V1Handler'
-
-BCRYPT_ROUNDS = Settings?.security?.bcryptRounds or 12
-
-_checkWriteResult = (result, callback = (error, updated) ->) ->
- # for MongoDB
- if result and result.nModified == 1
- callback(null, true)
- else
- callback(null, false)
-
-module.exports = AuthenticationManager =
- authenticate: (query, password, callback = (error, user) ->) ->
- # Using Mongoose for legacy reasons here. The returned User instance
- # gets serialized into the session and there may be subtle differences
- # between the user returned by Mongoose vs mongojs (such as default values)
- User.findOne query, (error, user) =>
- return callback(error) if error?
- if user?
- if user.hashedPassword?
- bcrypt.compare password, user.hashedPassword, (error, match) ->
- return callback(error) if error?
- if match
- AuthenticationManager.checkRounds user, user.hashedPassword, password, (err) ->
- return callback(err) if err?
- callback null, user
- else
- callback null, null
- else
- callback null, null
- else
- callback null, null
-
- validateEmail: (email) ->
- parsed = EmailHelper.parseEmail(email)
- if !parsed?
- return { message: 'email not valid' }
- return null
-
- # validates a password based on a similar set of rules to `complexPassword.js` on the frontend
- # note that `passfield.js` enforces more rules than this, but these are the most commonly set.
- # returns null on success, or an error string.
- validatePassword: (password) ->
- return { message: 'password not set' } unless password?
-
- allowAnyChars = Settings.passwordStrengthOptions?.allowAnyChars == true
- min = Settings.passwordStrengthOptions?.length?.min || 6
- max = Settings.passwordStrengthOptions?.length?.max || 72
-
- # we don't support passwords > 72 characters in length, because bcrypt truncates them
- max = 72 if max > 72
-
- return { message: 'password is too short' } unless password.length >= min
- return { message: 'password is too long' } unless password.length <= max
- return { message: 'password contains an invalid character' } unless allowAnyChars || AuthenticationManager._passwordCharactersAreValid(password)
- return null
-
- setUserPassword: (user_id, password, callback = (error, changed) ->) ->
- validation = @validatePassword(password)
- return callback(validation.message) if validation?
-
- UserGetter.getUser user_id, { email:1, overleaf: 1 }, (error, user) ->
- return callback(error) if error?
- v1IdExists = user.overleaf?.id?
- if v1IdExists and Settings.overleaf? # v2 user in v2
- # v2 user in v2, change password in v1
- AuthenticationManager.setUserPasswordInV1(user.overleaf.id, password, callback)
- else if v1IdExists and !Settings.overleaf?
- # v2 user in SL
- return callback(new Errors.NotInV2Error("Password Reset Attempt"))
- else if !v1IdExists and !Settings.overleaf?
- # SL user in SL, change password in SL
- AuthenticationManager.setUserPasswordInV2(user_id, password, callback)
- else if !v1IdExists and Settings.overleaf?
- # SL user in v2, should not happen
- return callback(new Errors.SLInV2Error("Password Reset Attempt"))
- else
- return callback(new Error("Password Reset Attempt Failed"))
-
- checkRounds: (user, hashedPassword, password, callback = (error) ->) ->
- # Temporarily disable this function, TODO: re-enable this
- if Settings?.security?.disableBcryptRoundsUpgrades
- return callback()
- # check current number of rounds and rehash if necessary
- currentRounds = bcrypt.getRounds hashedPassword
- if currentRounds < BCRYPT_ROUNDS
- AuthenticationManager.setUserPassword user._id, password, callback
- else
- callback()
-
- setUserPasswordInV2: (user_id, password, callback) ->
- validation = @validatePassword(password)
- return callback(validation.message) if validation?
- minorVersion = 'a'
- bcrypt.genSalt BCRYPT_ROUNDS, minorVersion, (error, salt) ->
- return callback(error) if error?
- bcrypt.hash password, salt, (error, hash) ->
- return callback(error) if error?
- db.users.update({
- _id: ObjectId(user_id.toString())
- }, {
- $set: hashedPassword: hash
- $unset: password: true
- }, (updateError, result)->
- return callback(updateError) if updateError?
- _checkWriteResult(result, callback)
- )
-
- setUserPasswordInV1: (v1_user_id, password, callback) ->
- validation = @validatePassword(password)
- return callback(validation.message) if validation?
-
- V1Handler.doPasswordReset v1_user_id, password, (error, reset)->
- return callback(error) if error?
- return callback(error, reset)
-
- _passwordCharactersAreValid: (password) ->
- digits = Settings.passwordStrengthOptions?.chars?.digits || '1234567890'
- letters = Settings.passwordStrengthOptions?.chars?.letters || 'abcdefghijklmnopqrstuvwxyz'
- letters_up = Settings.passwordStrengthOptions?.chars?.letters_up || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- symbols = Settings.passwordStrengthOptions?.chars?.symbols || '@#$%^&*()-_=+[]{};:<>/?!£€.,'
-
- for charIndex in [0..password.length - 1]
- return false unless digits.indexOf(password[charIndex]) > -1 or
- letters.indexOf(password[charIndex]) > -1 or
- letters_up.indexOf(password[charIndex]) > -1 or
- symbols.indexOf(password[charIndex]) > -1
- return true
diff --git a/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee b/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee
deleted file mode 100644
index 0cebb45fb1..0000000000
--- a/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee
+++ /dev/null
@@ -1,118 +0,0 @@
-CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler")
-ProjectGetter = require('../Project/ProjectGetter')
-User = require("../../models/User").User
-PrivilegeLevels = require("./PrivilegeLevels")
-PublicAccessLevels = require("./PublicAccessLevels")
-Errors = require("../Errors/Errors")
-ObjectId = require("mongojs").ObjectId
-TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
-
-
-module.exports = AuthorizationManager =
-
- getPublicAccessLevel: (project_id, callback=(err, level)->) ->
- if !ObjectId.isValid(project_id)
- return callback(new Error("invalid project id"))
- # Note, the Project property in the DB is `publicAccesLevel`, without the second `s`
- ProjectGetter.getProject project_id, publicAccesLevel: 1, (error, project) ->
- return callback(error) if error?
- if !project?
- return callback new Errors.NotFoundError("no project found with id #{project_id}")
- callback null, project.publicAccesLevel
-
- # Get the privilege level that the user has for the project
- # Returns:
- # * privilegeLevel: "owner", "readAndWrite", of "readOnly" if the user has
- # access. false if the user does not have access
- # * becausePublic: true if the access level is only because the project is public.
- # * becauseSiteAdmin: true if access level is only because user is admin
- getPrivilegeLevelForProject: (
- user_id, project_id, token,
- callback = (error, privilegeLevel, becausePublic, becauseSiteAdmin) ->
- ) ->
- if !user_id?
- # User is Anonymous, Try Token-based access
- AuthorizationManager.getPublicAccessLevel project_id, (err, publicAccessLevel) ->
- return callback(err) if err?
- if publicAccessLevel == PublicAccessLevels.TOKEN_BASED
- # Anonymous users can have read-only access to token-based projects,
- # while read-write access must be logged in,
- # unless the `enableAnonymousReadAndWriteSharing` setting is enabled
- TokenAccessHandler.isValidToken project_id, token, (err, isValidReadAndWrite, isValidReadOnly) ->
- return callback(err) if err?
- if isValidReadOnly
- # Grant anonymous user read-only access
- callback null, PrivilegeLevels.READ_ONLY, false, false
- else if (
- isValidReadAndWrite and
- TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
- )
- # Grant anonymous user read-and-write access
- callback null, PrivilegeLevels.READ_AND_WRITE, false, false
- else
- # Deny anonymous access
- callback null, PrivilegeLevels.NONE, false, false
- else if publicAccessLevel == PublicAccessLevels.READ_ONLY
- # Legacy public read-only access for anonymous user
- callback null, PrivilegeLevels.READ_ONLY, true, false
- else if publicAccessLevel == PublicAccessLevels.READ_AND_WRITE
- # Legacy public read-write access for anonymous user
- callback null, PrivilegeLevels.READ_AND_WRITE, true, false
- else
- # Deny anonymous user access
- callback null, PrivilegeLevels.NONE, false, false
- else
- # User is present, get their privilege level from database
- CollaboratorsHandler.getMemberIdPrivilegeLevel user_id, project_id, (error, privilegeLevel) ->
- return callback(error) if error?
- if privilegeLevel? and privilegeLevel != PrivilegeLevels.NONE
- # The user has direct access
- callback null, privilegeLevel, false, false
- else
- AuthorizationManager.isUserSiteAdmin user_id, (error, isAdmin) ->
- return callback(error) if error?
- if isAdmin
- callback null, PrivilegeLevels.OWNER, false, true
- else
- # Legacy public-access system
- # User is present (not anonymous), but does not have direct access
- AuthorizationManager.getPublicAccessLevel project_id, (err, publicAccessLevel) ->
- return callback(err) if err?
- if publicAccessLevel == PublicAccessLevels.READ_ONLY
- callback null, PrivilegeLevels.READ_ONLY, true, false
- else if publicAccessLevel == PublicAccessLevels.READ_AND_WRITE
- callback null, PrivilegeLevels.READ_AND_WRITE, true, false
- else
- callback null, PrivilegeLevels.NONE, false, false
-
- canUserReadProject: (user_id, project_id, token, callback = (error, canRead) ->) ->
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel) ->
- return callback(error) if error?
- return callback null, (privilegeLevel in [PrivilegeLevels.OWNER, PrivilegeLevels.READ_AND_WRITE, PrivilegeLevels.READ_ONLY])
-
- canUserWriteProjectContent: (user_id, project_id, token, callback = (error, canWriteContent) ->) ->
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel) ->
- return callback(error) if error?
- return callback null, (privilegeLevel in [PrivilegeLevels.OWNER, PrivilegeLevels.READ_AND_WRITE])
-
- canUserWriteProjectSettings: (user_id, project_id, token, callback = (error, canWriteSettings) ->) ->
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel, becausePublic) ->
- return callback(error) if error?
- if privilegeLevel == PrivilegeLevels.OWNER
- return callback null, true
- else if privilegeLevel == PrivilegeLevels.READ_AND_WRITE and !becausePublic
- return callback null, true
- else
- return callback null, false
-
- canUserAdminProject: (user_id, project_id, token, callback = (error, canAdmin, becauseSiteAdmin) ->) ->
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel, becausePublic, becauseSiteAdmin) ->
- return callback(error) if error?
- return callback null, (privilegeLevel == PrivilegeLevels.OWNER), becauseSiteAdmin
-
- isUserSiteAdmin: (user_id, callback = (error, isAdmin) ->) ->
- if !user_id?
- return callback null, false
- User.findOne { _id: user_id }, { isAdmin: 1 }, (error, user) ->
- return callback(error) if error?
- return callback null, (user?.isAdmin == true)
diff --git a/services/web/app/coffee/Features/Authorization/AuthorizationMiddleware.coffee b/services/web/app/coffee/Features/Authorization/AuthorizationMiddleware.coffee
deleted file mode 100644
index e3b913cb91..0000000000
--- a/services/web/app/coffee/Features/Authorization/AuthorizationMiddleware.coffee
+++ /dev/null
@@ -1,122 +0,0 @@
-AuthorizationManager = require("./AuthorizationManager")
-async = require "async"
-logger = require "logger-sharelatex"
-ObjectId = require("mongojs").ObjectId
-Errors = require "../Errors/Errors"
-AuthenticationController = require "../Authentication/AuthenticationController"
-TokenAccessHandler = require '../TokenAccess/TokenAccessHandler'
-
-module.exports = AuthorizationMiddleware =
- ensureUserCanReadMultipleProjects: (req, res, next) ->
- project_ids = (req.query.project_ids or "").split(",")
- AuthorizationMiddleware._getUserId req, (error, user_id) ->
- return next(error) if error?
- # Remove the projects we have access to. Note rejectSeries doesn't use
- # errors in callbacks
- async.rejectSeries project_ids, (project_id, cb) ->
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.canUserReadProject user_id, project_id, token, (error, canRead) ->
- return next(error) if error?
- cb(canRead)
- , (unauthorized_project_ids) ->
- if unauthorized_project_ids.length > 0
- AuthorizationMiddleware.redirectToRestricted req, res, next
- else
- next()
-
- ensureUserCanReadProject: (req, res, next) ->
- AuthorizationMiddleware._getUserAndProjectId req, (error, user_id, project_id) ->
- return next(error) if error?
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.canUserReadProject user_id, project_id, token, (error, canRead) ->
- return next(error) if error?
- if canRead
- logger.log {user_id, project_id}, "allowing user read access to project"
- next()
- else
- logger.log {user_id, project_id}, "denying user read access to project"
- if req.headers?['accept']?.match(/^application\/json.*$/)
- res.sendStatus(403)
- else
- AuthorizationMiddleware.redirectToRestricted req, res, next
-
- ensureUserCanWriteProjectSettings: (req, res, next) ->
- AuthorizationMiddleware._getUserAndProjectId req, (error, user_id, project_id) ->
- return next(error) if error?
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.canUserWriteProjectSettings user_id, project_id, token, (error, canWrite) ->
- return next(error) if error?
- if canWrite
- logger.log {user_id, project_id}, "allowing user write access to project settings"
- next()
- else
- logger.log {user_id, project_id}, "denying user write access to project settings"
- AuthorizationMiddleware.redirectToRestricted req, res, next
-
- ensureUserCanWriteProjectContent: (req, res, next) ->
- AuthorizationMiddleware._getUserAndProjectId req, (error, user_id, project_id) ->
- return next(error) if error?
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.canUserWriteProjectContent user_id, project_id, token, (error, canWrite) ->
- return next(error) if error?
- if canWrite
- logger.log {user_id, project_id}, "allowing user write access to project content"
- next()
- else
- logger.log {user_id, project_id}, "denying user write access to project settings"
- AuthorizationMiddleware.redirectToRestricted req, res, next
-
- ensureUserCanAdminProject: (req, res, next) ->
- AuthorizationMiddleware._getUserAndProjectId req, (error, user_id, project_id) ->
- return next(error) if error?
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.canUserAdminProject user_id, project_id, token, (error, canAdmin) ->
- return next(error) if error?
- if canAdmin
- logger.log {user_id, project_id}, "allowing user admin access to project"
- next()
- else
- logger.log {user_id, project_id}, "denying user admin access to project"
- AuthorizationMiddleware.redirectToRestricted req, res, next
-
- ensureUserIsSiteAdmin: (req, res, next) ->
- AuthorizationMiddleware._getUserId req, (error, user_id) ->
- return next(error) if error?
- AuthorizationManager.isUserSiteAdmin user_id, (error, isAdmin) ->
- return next(error) if error?
- if isAdmin
- logger.log {user_id}, "allowing user admin access to site"
- next()
- else
- logger.log {user_id}, "denying user admin access to site"
- AuthorizationMiddleware.redirectToRestricted req, res, next
-
- _getUserAndProjectId: (req, callback = (error, user_id, project_id) ->) ->
- project_id = req.params?.project_id or req.params?.Project_id
- if !project_id?
- return callback(new Error("Expected project_id in request parameters"))
- if !ObjectId.isValid(project_id)
- return callback(new Errors.NotFoundError("invalid project_id: #{project_id}"))
- AuthorizationMiddleware._getUserId req, (error, user_id) ->
- return callback(error) if error?
- callback(null, user_id, project_id)
-
- _getUserId: (req, callback = (error, user_id) ->) ->
- user_id = AuthenticationController.getLoggedInUserId(req) || req?.oauth_user?._id || null
- return callback(null, user_id)
-
- redirectToRestricted: (req, res, next) ->
- # TODO: move this to throwing ForbiddenError
- res.redirect "/restricted?from=#{encodeURIComponent(req.url)}"
-
- restricted : (req, res, next)->
- if AuthenticationController.isUserLoggedIn(req)
- res.render 'user/restricted',
- title:'restricted'
- else
- from = req.query.from
- logger.log {from: from}, "redirecting to login"
- redirect_to = "/login"
- if from?
- AuthenticationController.setRedirectInSession(req, from)
- res.redirect redirect_to
diff --git a/services/web/app/coffee/Features/Authorization/PrivilegeLevels.coffee b/services/web/app/coffee/Features/Authorization/PrivilegeLevels.coffee
deleted file mode 100644
index 682ae08a02..0000000000
--- a/services/web/app/coffee/Features/Authorization/PrivilegeLevels.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports =
- NONE: false
- READ_ONLY: "readOnly"
- READ_AND_WRITE: "readAndWrite"
- OWNER: "owner"
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Authorization/PublicAccessLevels.coffee b/services/web/app/coffee/Features/Authorization/PublicAccessLevels.coffee
deleted file mode 100644
index e31426221e..0000000000
--- a/services/web/app/coffee/Features/Authorization/PublicAccessLevels.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports =
- READ_ONLY: "readOnly" # LEGACY
- READ_AND_WRITE: "readAndWrite" # LEGACY
- PRIVATE: "private"
- TOKEN_BASED: "tokenBased"
diff --git a/services/web/app/coffee/Features/Authorization/Sources.coffee b/services/web/app/coffee/Features/Authorization/Sources.coffee
deleted file mode 100644
index 149d296211..0000000000
--- a/services/web/app/coffee/Features/Authorization/Sources.coffee
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports =
- INVITE: 'invite'
- TOKEN: 'token'
- OWNER: 'owner'
diff --git a/services/web/app/coffee/Features/BetaProgram/BetaProgramController.coffee b/services/web/app/coffee/Features/BetaProgram/BetaProgramController.coffee
deleted file mode 100644
index 1e0577cfc1..0000000000
--- a/services/web/app/coffee/Features/BetaProgram/BetaProgramController.coffee
+++ /dev/null
@@ -1,40 +0,0 @@
-BetaProgramHandler = require './BetaProgramHandler'
-UserGetter = require "../User/UserGetter"
-Settings = require "settings-sharelatex"
-logger = require 'logger-sharelatex'
-AuthenticationController = require '../Authentication/AuthenticationController'
-
-
-module.exports = BetaProgramController =
-
- optIn: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {user_id}, "user opting in to beta program"
- if !user_id?
- return next(new Error("no user id in session"))
- BetaProgramHandler.optIn user_id, (err) ->
- if err
- return next(err)
- return res.redirect "/beta/participate"
-
- optOut: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {user_id}, "user opting out of beta program"
- if !user_id?
- return next(new Error("no user id in session"))
- BetaProgramHandler.optOut user_id, (err) ->
- if err
- return next(err)
- return res.redirect "/beta/participate"
-
- optInPage: (req, res, next)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {user_id}, "showing beta participation page for user"
- UserGetter.getUser user_id, (err, user)->
- if err
- logger.err {err, user_id}, "error fetching user"
- return next(err)
- res.render 'beta_program/opt_in',
- title:'sharelatex_beta_program'
- user: user,
- languages: Settings.languages,
diff --git a/services/web/app/coffee/Features/BetaProgram/BetaProgramHandler.coffee b/services/web/app/coffee/Features/BetaProgram/BetaProgramHandler.coffee
deleted file mode 100644
index 0c902fcfe1..0000000000
--- a/services/web/app/coffee/Features/BetaProgram/BetaProgramHandler.coffee
+++ /dev/null
@@ -1,31 +0,0 @@
-User = require("../../models/User").User
-logger = require 'logger-sharelatex'
-metrics = require("metrics-sharelatex")
-
-module.exports = BetaProgramHandler =
-
- optIn: (user_id, callback=(err)->) ->
- User.findById user_id, (err, user) ->
- if err
- logger.err {err, user_id}, "problem adding user to beta"
- return callback(err)
- metrics.inc "beta-program.opt-in"
- user.betaProgram = true
- user.save (err) ->
- if err
- logger.err {err, user_id}, "problem adding user to beta"
- return callback(err)
- return callback(null)
-
- optOut: (user_id, callback=(err)->) ->
- User.findById user_id, (err, user) ->
- if err
- logger.err {err, user_id}, "problem removing user from beta"
- return callback(err)
- metrics.inc "beta-program.opt-out"
- user.betaProgram = false
- user.save (err) ->
- if err
- logger.err {err, user_id}, "problem removing user from beta"
- return callback(err)
- return callback(null)
diff --git a/services/web/app/coffee/Features/Blog/BlogController.coffee b/services/web/app/coffee/Features/Blog/BlogController.coffee
deleted file mode 100644
index eb2b3fad94..0000000000
--- a/services/web/app/coffee/Features/Blog/BlogController.coffee
+++ /dev/null
@@ -1,45 +0,0 @@
-request = require("request")
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-_ = require("underscore")
-ErrorController = require "../Errors/ErrorController"
-
-module.exports = BlogController =
-
- getPage: (req, res, next)->
- url = req.url?.toLowerCase()
- blogUrl = "#{settings.apis.blog.url}#{url}"
-
- extensionsToProxy = [".png", ".xml", ".jpeg", ".jpg", ".json", ".zip", ".eps", ".gif"]
-
- shouldProxy = _.find extensionsToProxy, (extension)->
- url.indexOf(extension) != -1
-
- if shouldProxy
- return BlogController._directProxy blogUrl, res
-
- logger.log url:url, "proxying request to blog api"
- request.get blogUrl, (err, r, data)->
- if r?.statusCode == 404 or r?.statusCode == 403
- return ErrorController.notFound(req, res, next)
- if err?
- return res.send 500
- data = data.trim()
- try
- data = JSON.parse(data)
- if settings.cdn?.web?.host?
- data?.content = data?.content?.replace(/src="(\/[^"]+)"/g, "src='#{settings.cdn?.web?.host}$1'");
- catch err
- logger.err err:err, data:data, "error parsing data from data"
- res.render "blog/blog_holder", data
-
-
- getIndexPage: (req, res)->
- req.url = "/blog/index.html"
- BlogController.getPage req, res
-
- _directProxy: (originUrl, res)->
- upstream = request.get(originUrl)
- upstream.on "error", (error) ->
- logger.error err: error, "blog proxy error"
- upstream.pipe res
diff --git a/services/web/app/coffee/Features/Blog/BlogHandler.coffee b/services/web/app/coffee/Features/Blog/BlogHandler.coffee
deleted file mode 100644
index c3fd33b8eb..0000000000
--- a/services/web/app/coffee/Features/Blog/BlogHandler.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-request = require "request"
-settings = require "settings-sharelatex"
-_ = require("underscore")
-logger = require "logger-sharelatex"
-
-module.exports = BlogHandler =
-
- getLatestAnnouncements: (callback)->
- blogUrl = "#{settings.apis.blog.url}/blog/latestannouncements.json"
- opts =
- url:blogUrl
- json:true
- timeout:1000
- request.get opts, (err, res, announcements)->
- if err?
- return callback err
- if res.statusCode != 200
- return callback("blog announcement returned non 200")
- logger.log announcementsLength: announcements?.length, "announcements returned"
- announcements = _.map announcements, (announcement)->
- announcement.date = new Date(announcement.date)
- return announcement
- callback(err, announcements)
diff --git a/services/web/app/coffee/Features/BrandVariations/BrandVariationsHandler.coffee b/services/web/app/coffee/Features/BrandVariations/BrandVariationsHandler.coffee
deleted file mode 100644
index 2836ee320b..0000000000
--- a/services/web/app/coffee/Features/BrandVariations/BrandVariationsHandler.coffee
+++ /dev/null
@@ -1,41 +0,0 @@
-url = require "url"
-settings = require "settings-sharelatex"
-logger = require "logger-sharelatex"
-V1Api = require "../V1/V1Api"
-
-module.exports = BrandVariationsHandler =
- getBrandVariationById: (brandVariationId, callback = (error, brandVariationDetails) ->)->
- if !brandVariationId? or brandVariationId == ""
- return callback(new Error("Branding variation id not provided"))
- logger.log brandVariationId: brandVariationId, "fetching brand variation details from v1"
- V1Api.request {
- uri: "/api/v2/brand_variations/#{brandVariationId}"
- }, (error, response, brandVariationDetails) ->
- if error?
- logger.err { brandVariationId, error}, "error getting brand variation details"
- return callback(error)
- _formatBrandVariationDetails brandVariationDetails
- callback(null, brandVariationDetails)
-
-_formatBrandVariationDetails = (details) ->
- if details.export_url?
- details.export_url = _setV1AsHostIfRelativeURL details.export_url
- if details.home_url?
- details.home_url = _setV1AsHostIfRelativeURL details.home_url
- if details.logo_url?
- details.logo_url = _setV1AsHostIfRelativeURL details.logo_url
- if details.journal_guidelines_url?
- details.journal_guidelines_url = _setV1AsHostIfRelativeURL details.journal_guidelines_url
- if details.journal_cover_url?
- details.journal_cover_url = _setV1AsHostIfRelativeURL details.journal_cover_url
- if details.submission_confirmation_page_logo_url?
- details.submission_confirmation_page_logo_url = _setV1AsHostIfRelativeURL details.submission_confirmation_page_logo_url
- if details.publish_menu_icon?
- details.publish_menu_icon = _setV1AsHostIfRelativeURL details.publish_menu_icon
-
-_setV1AsHostIfRelativeURL = (urlString) ->
- # The first argument is the base URL to resolve against if the second argument is not absolute.
- # As it only applies if the second argument is not absolute, we can use it to transform relative URLs into
- # absolute ones using v1 as the host. If the URL is absolute (e.g. a filepicker one), then the base
- # argument is just ignored
- url.resolve settings?.apis?.v1?.url, urlString
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Captcha/CaptchaMiddleware.coffee b/services/web/app/coffee/Features/Captcha/CaptchaMiddleware.coffee
deleted file mode 100644
index abe389daa7..0000000000
--- a/services/web/app/coffee/Features/Captcha/CaptchaMiddleware.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-request = require 'request'
-logger = require 'logger-sharelatex'
-Settings = require 'settings-sharelatex'
-
-module.exports = CaptchaMiddleware =
- validateCaptcha: (action) ->
- return (req, res, next) ->
- if !Settings.recaptcha?.siteKey?
- return next()
- inviteAndCaptchaDisabled = action == 'invite' and Settings.recaptcha.disabled.invite
- registerAndCaptchaDisabled = action == 'register' and Settings.recaptcha.disabled.register
- if inviteAndCaptchaDisabled or registerAndCaptchaDisabled
- return next()
- response = req.body['g-recaptcha-response']
- options =
- form:
- secret: Settings.recaptcha.secretKey
- response: response
- json: true
- request.post "https://www.google.com/recaptcha/api/siteverify", options, (error, response, body) ->
- return next(error) if error?
- if !body?.success
- logger.warn {statusCode: response.statusCode, body: body}, 'failed recaptcha siteverify request'
- return res.status(400).send({errorReason:"cannot_verify_user_not_robot", message:
- {text:"Sorry, we could not verify that you are not a robot. Please check that Google reCAPTCHA is not being blocked by an ad blocker or firewall."}
- })
- else
- return next()
diff --git a/services/web/app/coffee/Features/Chat/ChatApiHandler.coffee b/services/web/app/coffee/Features/Chat/ChatApiHandler.coffee
deleted file mode 100644
index 3cae19b7f3..0000000000
--- a/services/web/app/coffee/Features/Chat/ChatApiHandler.coffee
+++ /dev/null
@@ -1,82 +0,0 @@
-request = require("request")
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-
-module.exports = ChatApiHandler =
- _apiRequest: (opts, callback = (error, data) ->) ->
- request opts, (error, response, data) ->
- return callback(error) if error?
- if 200 <= response.statusCode < 300
- return callback null, data
- else
- error = new Error("chat api returned non-success code: #{response.statusCode}")
- error.statusCode = response.statusCode
- logger.error {err: error, opts}, "error sending request to chat api"
- return callback error
-
- sendGlobalMessage: (project_id, user_id, content, callback)->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/messages"
- method: "POST"
- json: {user_id, content}
- }, callback
-
- getGlobalMessages: (project_id, limit, before, callback)->
- qs = {}
- qs.limit = limit if limit?
- qs.before = before if before?
-
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/messages"
- method: "GET"
- qs: qs
- json: true
- }, callback
-
- sendComment: (project_id, thread_id, user_id, content, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}/messages"
- method: "POST"
- json: {user_id, content}
- }, callback
-
- getThreads: (project_id, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/threads"
- method: "GET"
- json: true
- }, callback
-
- resolveThread: (project_id, thread_id, user_id, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}/resolve"
- method: "POST"
- json: {user_id}
- }, callback
-
- reopenThread: (project_id, thread_id, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}/reopen"
- method: "POST"
- }, callback
-
- deleteThread: (project_id, thread_id, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}"
- method: "DELETE"
- }, callback
-
- editMessage: (project_id, thread_id, message_id, content, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}/messages/#{message_id}/edit"
- method: "POST"
- json:
- content: content
- }, callback
-
- deleteMessage: (project_id, thread_id, message_id, callback = (error) ->) ->
- ChatApiHandler._apiRequest {
- url: "#{settings.apis.chat.internal_url}/project/#{project_id}/thread/#{thread_id}/messages/#{message_id}"
- method: "DELETE"
- }, callback
-
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Chat/ChatController.coffee b/services/web/app/coffee/Features/Chat/ChatController.coffee
deleted file mode 100644
index ca5b84b024..0000000000
--- a/services/web/app/coffee/Features/Chat/ChatController.coffee
+++ /dev/null
@@ -1,65 +0,0 @@
-ChatApiHandler = require("./ChatApiHandler")
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-logger = require("logger-sharelatex")
-AuthenticationController = require('../Authentication/AuthenticationController')
-UserInfoManager = require('../User/UserInfoManager')
-UserInfoController = require('../User/UserInfoController')
-async = require "async"
-
-module.exports = ChatController =
- sendMessage: (req, res, next)->
- project_id = req.params.project_id
- content = req.body.content
- user_id = AuthenticationController.getLoggedInUserId(req)
- if !user_id?
- err = new Error('no logged-in user')
- return next(err)
- ChatApiHandler.sendGlobalMessage project_id, user_id, content, (err, message) ->
- return next(err) if err?
- UserInfoManager.getPersonalInfo message.user_id, (err, user) ->
- return next(err) if err?
- message.user = UserInfoController.formatPersonalInfo(user)
- EditorRealTimeController.emitToRoom project_id, "new-chat-message", message
- res.send(204)
-
- getMessages: (req, res, next)->
- project_id = req.params.project_id
- query = req.query
- logger.log project_id:project_id, query:query, "getting messages"
- ChatApiHandler.getGlobalMessages project_id, query.limit, query.before, (err, messages) ->
- return next(err) if err?
- ChatController._injectUserInfoIntoThreads {global: { messages: messages }}, (err) ->
- return next(err) if err?
- logger.log length: messages?.length, "sending messages to client"
- res.json messages
-
- _injectUserInfoIntoThreads: (threads, callback = (error, threads) ->) ->
- # There will be a lot of repitition of user_ids, so first build a list
- # of unique ones to perform db look ups on, then use these to populate the
- # user fields
- user_ids = {}
- for thread_id, thread of threads
- if thread.resolved
- user_ids[thread.resolved_by_user_id] = true
- for message in thread.messages
- user_ids[message.user_id] = true
-
- jobs = []
- users = {}
- for user_id, _ of user_ids
- do (user_id) ->
- jobs.push (cb) ->
- UserInfoManager.getPersonalInfo user_id, (err, user) ->
- return cb(error) if error?
- user = UserInfoController.formatPersonalInfo user
- users[user_id] = user
- cb()
-
- async.series jobs, (error) ->
- return callback(error) if error?
- for thread_id, thread of threads
- if thread.resolved
- thread.resolved_by_user = users[thread.resolved_by_user_id]
- for message in thread.messages
- message.user = users[message.user_id]
- return callback null, threads
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsController.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsController.coffee
deleted file mode 100644
index 1d5a147c95..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsController.coffee
+++ /dev/null
@@ -1,40 +0,0 @@
-ProjectGetter = require "../Project/ProjectGetter"
-CollaboratorsHandler = require "./CollaboratorsHandler"
-ProjectEditorHandler = require "../Project/ProjectEditorHandler"
-EditorRealTimeController = require "../Editor/EditorRealTimeController"
-LimitationsManager = require "../Subscription/LimitationsManager"
-UserGetter = require "../User/UserGetter"
-EmailHelper = require "../Helpers/EmailHelper"
-logger = require 'logger-sharelatex'
-
-
-module.exports = CollaboratorsController =
- removeUserFromProject: (req, res, next) ->
- project_id = req.params.Project_id
- user_id = req.params.user_id
- CollaboratorsController._removeUserIdFromProject project_id, user_id, (error) ->
- return next(error) if error?
- EditorRealTimeController.emitToRoom project_id, 'project:membership:changed', {members: true}
- res.sendStatus 204
-
- removeSelfFromProject: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- user_id = req.session?.user?._id
- CollaboratorsController._removeUserIdFromProject project_id, user_id, (error) ->
- return next(error) if error?
- res.sendStatus 204
-
- _removeUserIdFromProject: (project_id, user_id, callback = (error) ->) ->
- CollaboratorsHandler.removeUserFromProject project_id, user_id, (error)->
- return callback(error) if error?
- EditorRealTimeController.emitToRoom(project_id, 'userRemovedFromProject', user_id)
- callback()
-
- getAllMembers: (req, res, next) ->
- projectId = req.params.Project_id
- logger.log {projectId}, "getting all active members for project"
- CollaboratorsHandler.getAllInvitedMembers projectId, (err, members) ->
- if err?
- logger.err {projectId}, "error getting members for project"
- return next(err)
- res.json({members: members})
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee
deleted file mode 100644
index 913562f417..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-Project = require("../../models/Project").Project
-EmailHandler = require("../Email/EmailHandler")
-Settings = require "settings-sharelatex"
-
-
-module.exports = CollaboratorsEmailHandler =
-
- _buildInviteUrl: (project, invite) ->
- "#{Settings.siteUrl}/project/#{project._id}/invite/token/#{invite.token}?" + [
- "project_name=#{encodeURIComponent(project.name)}"
- "user_first_name=#{encodeURIComponent(project.owner_ref.first_name)}"
- ].join("&")
-
- notifyUserOfProjectInvite: (project_id, email, invite, sendingUser, callback)->
- Project
- .findOne(_id: project_id )
- .select("name owner_ref")
- .populate('owner_ref')
- .exec (err, project)->
- emailOptions =
- to: email
- replyTo: project.owner_ref.email
- project:
- name: project.name
- inviteUrl: CollaboratorsEmailHandler._buildInviteUrl(project, invite)
- owner: project.owner_ref
- sendingUser_id: sendingUser._id
- EmailHandler.sendEmail "projectInvite", emailOptions, callback
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsHandler.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsHandler.coffee
deleted file mode 100644
index 18f68a260c..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsHandler.coffee
+++ /dev/null
@@ -1,307 +0,0 @@
-UserCreator = require('../User/UserCreator')
-Project = require("../../models/Project").Project
-ProjectGetter = require('../Project/ProjectGetter')
-logger = require('logger-sharelatex')
-UserGetter = require "../User/UserGetter"
-ContactManager = require "../Contacts/ContactManager"
-CollaboratorsEmailHandler = require "./CollaboratorsEmailHandler"
-async = require "async"
-PrivilegeLevels = require "../Authorization/PrivilegeLevels"
-PublicAccessLevels = require "../Authorization/PublicAccessLevels"
-Errors = require "../Errors/Errors"
-EmailHelper = require "../Helpers/EmailHelper"
-ProjectEditorHandler = require "../Project/ProjectEditorHandler"
-Sources = require "../Authorization/Sources"
-ObjectId = require('mongojs').ObjectId
-
-module.exports = CollaboratorsHandler =
-
- getMemberIdsWithPrivilegeLevels: (project_id, callback = (error, members) ->) ->
- projection =
- owner_ref: 1,
- collaberator_refs: 1,
- readOnly_refs: 1,
- tokenAccessReadOnly_refs: 1,
- tokenAccessReadAndWrite_refs: 1
- publicAccesLevel: 1
- ProjectGetter.getProject project_id, projection, (error, project) ->
- return callback(error) if error?
- return callback new Errors.NotFoundError("no project found with id #{project_id}") if !project?
- members = []
- members.push {
- id: project.owner_ref.toString(),
- privilegeLevel: PrivilegeLevels.OWNER,
- source: Sources.OWNER
- }
- for member_id in project.collaberator_refs or []
- members.push {
- id: member_id.toString(),
- privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
- source: Sources.INVITE
- }
- for member_id in project.readOnly_refs or []
- members.push {
- id: member_id.toString(),
- privilegeLevel: PrivilegeLevels.READ_ONLY,
- source: Sources.INVITE
- }
- if project.publicAccesLevel == PublicAccessLevels.TOKEN_BASED
- for member_id in project.tokenAccessReadAndWrite_refs or []
- members.push {
- id: member_id.toString(),
- privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
- source: Sources.TOKEN
- }
- for member_id in project.tokenAccessReadOnly_refs or []
- members.push {
- id: member_id.toString(),
- privilegeLevel: PrivilegeLevels.READ_ONLY,
- source: Sources.TOKEN
- }
- return callback null, members
-
- getMemberIds: (project_id, callback = (error, member_ids) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members) ->
- return callback(error) if error?
- return callback null, members.map (m) -> m.id
-
- getInvitedMemberIds: (project_id, callback = (error, member_ids) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members) ->
- return callback(error) if error?
- return callback null, members.filter((m) -> m.source != Sources.TOKEN).map((m) -> m.id)
-
- USER_PROJECTION: {
- _id: 1,
- email: 1,
- features: 1,
- first_name: 1,
- last_name: 1,
- signUpDate: 1
- }
- _loadMembers: (members, callback=(error, users) ->) ->
- result = []
- async.mapLimit members, 3,
- (member, cb) ->
- UserGetter.getUserOrUserStubById member.id, CollaboratorsHandler.USER_PROJECTION, (error, user) ->
- return cb(error) if error?
- if user?
- result.push { user: user, privilegeLevel: member.privilegeLevel }
- cb()
- (error) ->
- return callback(error) if error?
- callback null, result
-
- getMembersWithPrivilegeLevels: (project_id, callback = (error, members) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members = []) ->
- return callback(error) if error?
- CollaboratorsHandler._loadMembers members, (error, users) ->
- callback error, users
-
- getInvitedMembersWithPrivilegeLevels: (project_id, callback = (error, members) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members = []) ->
- return callback(error) if error?
- members = members.filter((m) -> m.source != Sources.TOKEN)
- CollaboratorsHandler._loadMembers members, (error, users) ->
- callback error, users
-
- getTokenMembersWithPrivilegeLevels: (project_id, callback = (error, members) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members = []) ->
- return callback(error) if error?
- members = members.filter((m) -> m.source == Sources.TOKEN)
- CollaboratorsHandler._loadMembers members, (error, users) ->
- callback error, users
-
- getMemberIdPrivilegeLevel: (user_id, project_id, callback = (error, privilegeLevel) ->) ->
- # In future if the schema changes and getting all member ids is more expensive (multiple documents)
- # then optimise this.
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members = []) ->
- return callback(error) if error?
- for member in members
- if member.id == user_id?.toString()
- return callback null, member.privilegeLevel
- return callback null, PrivilegeLevels.NONE
-
- getInvitedMemberCount: (project_id, callback = (error, count) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members) ->
- return callback(error) if error?
- return callback null, (members or []).filter((m) -> m.source != Sources.TOKEN).length
-
- getInvitedCollaboratorCount: (project_id, callback = (error, count) ->) ->
- CollaboratorsHandler.getInvitedMemberCount project_id, (error, count) ->
- return callback(error) if error?
- return callback null, count - 1 # Don't count project owner
-
- isUserInvitedMemberOfProject: (user_id, project_id, callback = (error, isMember, privilegeLevel) ->) ->
- CollaboratorsHandler.getMemberIdsWithPrivilegeLevels project_id, (error, members = []) ->
- return callback(error) if error?
- for member in members
- if member.id.toString() == user_id.toString() and member.source != Sources.TOKEN
- return callback null, true, member.privilegeLevel
- return callback null, false, null
-
- getProjectsUserIsMemberOf: (user_id, fields, callback = (error, {readAndWrite:[],readOnly:[],tokenReadAndWrite:[],tokenReadOnly:[]}) ->) ->
- async.mapLimit(
- [
- {collaberator_refs: user_id},
- {readOnly_refs: user_id},
- {
- tokenAccessReadAndWrite_refs: user_id,
- publicAccesLevel: PublicAccessLevels.TOKEN_BASED
- },
- {
- tokenAccessReadOnly_refs: user_id,
- publicAccesLevel: PublicAccessLevels.TOKEN_BASED
- }
- ]
- , 2
- , (query, cb) ->
- Project.find query, fields, cb
- , (error, results) ->
- return callback(error) if error?
- projects = {
- readAndWrite: results[0]
- readOnly: results[1]
- tokenReadAndWrite: results[2]
- tokenReadOnly: results[3]
- }
- callback(null, projects)
- )
-
- removeUserFromProject: (project_id, user_id, callback = (error) ->)->
- logger.log user_id: user_id, project_id: project_id, "removing user"
- conditions = _id:project_id
- update = $pull:{}
- update["$pull"] =
- collaberator_refs:user_id,
- readOnly_refs:user_id
- tokenAccessReadOnly_refs:user_id
- tokenAccessReadAndWrite_refs:user_id
- Project.update conditions, update, (err)->
- if err?
- logger.error err: err, "problem removing user from project collaberators"
- callback(err)
-
- removeUserFromAllProjets: (user_id, callback = (error) ->) ->
- CollaboratorsHandler.getProjectsUserIsMemberOf user_id, { _id: 1 }, (error, {readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly}) ->
- return callback(error) if error?
- allProjects =
- readAndWrite
- .concat(readOnly)
- .concat(tokenReadAndWrite)
- .concat(tokenReadOnly)
- jobs = []
- for project in allProjects
- do (project) ->
- jobs.push (cb) ->
- return cb() if !project?
- CollaboratorsHandler.removeUserFromProject project._id, user_id, cb
- async.series jobs, callback
-
- addUserIdToProject: (project_id, adding_user_id, user_id, privilegeLevel, callback = (error) ->)->
- ProjectGetter.getProject project_id, { collaberator_refs: 1, readOnly_refs: 1 }, (error, project) ->
- return callback(error) if error?
- existing_users = (project.collaberator_refs or [])
- existing_users = existing_users.concat(project.readOnly_refs or [])
- existing_users = existing_users.map (u) -> u.toString()
- if existing_users.indexOf(user_id.toString()) > -1
- return callback null # User already in Project
-
- if privilegeLevel == PrivilegeLevels.READ_AND_WRITE
- level = {"collaberator_refs":user_id}
- logger.log {privileges: "readAndWrite", user_id, project_id}, "adding user"
- else if privilegeLevel == PrivilegeLevels.READ_ONLY
- level = {"readOnly_refs":user_id}
- logger.log {privileges: "readOnly", user_id, project_id}, "adding user"
- else
- return callback(new Error("unknown privilegeLevel: #{privilegeLevel}"))
-
- if adding_user_id
- ContactManager.addContact adding_user_id, user_id
-
- Project.update { _id: project_id }, { $addToSet: level }, (error) ->
- return callback(error) if error?
- # Flush to TPDS in background to add files to collaborator's Dropbox
- ProjectEntityHandler = require("../Project/ProjectEntityHandler")
- ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, (error) ->
- if error?
- logger.error {err: error, project_id, user_id}, "error flushing to TPDS after adding collaborator"
- callback()
-
- getAllInvitedMembers: (projectId, callback=(err, members)->) ->
- logger.log {projectId}, "fetching all members"
- CollaboratorsHandler.getInvitedMembersWithPrivilegeLevels projectId, (error, rawMembers) ->
- if error?
- logger.err {projectId, error}, "error getting members for project"
- return callback(error)
- {owner, members} = ProjectEditorHandler.buildOwnerAndMembersViews(rawMembers)
- callback(null, members)
-
- userIsTokenMember: (userId, projectId, callback=(err, isTokenMember)->) ->
- userId = ObjectId(userId.toString())
- projectId = ObjectId(projectId.toString())
- Project.findOne {
- _id: projectId,
- $or: [
- {tokenAccessReadOnly_refs: userId},
- {tokenAccessReadAndWrite_refs: userId}
- ]
- }, {
- _id: 1
- }, (err, project) ->
- if err?
- return callback(err)
- callback(null, project?)
-
- transferProjects: (from_user_id, to_user_id, callback=(err, projects) ->) ->
- MEMBER_KEYS = ['collaberator_refs', 'readOnly_refs']
-
- # Find all the projects this user is part of so we can flush them to TPDS
- query =
- $or:
- [{ owner_ref: from_user_id }]
- .concat(
- MEMBER_KEYS.map (key) ->
- q = {}
- q[key] = from_user_id
- return q
- ) # [{ collaberator_refs: from_user_id }, ...]
- Project.find query, { _id: 1 }, (error, projects = []) ->
- return callback(error) if error?
-
- project_ids = projects.map (p) -> p._id
- logger.log {project_ids, from_user_id, to_user_id}, "transferring projects"
-
- update_jobs = []
- update_jobs.push (cb) ->
- Project.update { owner_ref: from_user_id }, { $set: { owner_ref: to_user_id }}, { multi: true }, cb
- for key in MEMBER_KEYS
- do (key) ->
- update_jobs.push (cb) ->
- query = {}
- addNewUserUpdate = $addToSet: {}
- removeOldUserUpdate = $pull: {}
- query[key] = from_user_id
- removeOldUserUpdate.$pull[key] = from_user_id
- addNewUserUpdate.$addToSet[key] = to_user_id
- # Mongo won't let us pull and addToSet in the same query, so do it in
- # two. Note we need to add first, since the query is based on the old user.
- Project.update query, addNewUserUpdate, { multi: true }, (error) ->
- return cb(error) if error?
- Project.update query, removeOldUserUpdate, { multi: true }, cb
-
- # Flush each project to TPDS to add files to new user's Dropbox
- ProjectEntityHandler = require("../Project/ProjectEntityHandler")
- flush_jobs = []
- for project_id in project_ids
- do (project_id) ->
- flush_jobs.push (cb) ->
- ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, cb
-
- # Flush in background, no need to block on this
- async.series flush_jobs, (error) ->
- if error?
- logger.err {err: error, project_ids, from_user_id, to_user_id}, "error flushing tranferred projects to TPDS"
-
- async.series update_jobs, (err) ->
- logger.log("flushed transferred projects to TPDS")
- callback(err)
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee
deleted file mode 100644
index de4710e19a..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee
+++ /dev/null
@@ -1,171 +0,0 @@
-ProjectGetter = require "../Project/ProjectGetter"
-LimitationsManager = require "../Subscription/LimitationsManager"
-UserGetter = require "../User/UserGetter"
-CollaboratorsHandler = require('./CollaboratorsHandler')
-CollaboratorsInviteHandler = require('./CollaboratorsInviteHandler')
-logger = require('logger-sharelatex')
-Settings = require('settings-sharelatex')
-EmailHelper = require "../Helpers/EmailHelper"
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-AnalyticsManger = require("../Analytics/AnalyticsManager")
-AuthenticationController = require("../Authentication/AuthenticationController")
-rateLimiter = require("../../infrastructure/RateLimiter")
-request = require 'request'
-
-module.exports = CollaboratorsInviteController =
-
- getAllInvites: (req, res, next) ->
- projectId = req.params.Project_id
- logger.log {projectId}, "getting all active invites for project"
- CollaboratorsInviteHandler.getAllInvites projectId, (err, invites) ->
- if err?
- logger.err {projectId}, "error getting invites for project"
- return next(err)
- res.json({invites: invites})
-
- _checkShouldInviteEmail: (email, callback=(err, shouldAllowInvite)->) ->
- if Settings.restrictInvitesToExistingAccounts == true
- logger.log {email}, "checking if user exists with this email"
- UserGetter.getUserByAnyEmail email, {_id: 1}, (err, user) ->
- return callback(err) if err?
- userExists = user? and user?._id?
- callback(null, userExists)
- else
- callback(null, true)
-
- _checkRateLimit: (user_id, callback = (error) ->) ->
- LimitationsManager.allowedNumberOfCollaboratorsForUser user_id, (err, collabLimit = 1)->
- return callback(err) if err?
- if collabLimit == -1
- collabLimit = 20
- collabLimit = collabLimit * 10
- opts =
- endpointName: "invite-to-project-by-user-id"
- timeInterval: 60 * 30
- subjectName: user_id
- throttle: collabLimit
- rateLimiter.addCount opts, callback
-
- inviteToProject: (req, res, next) ->
- projectId = req.params.Project_id
- email = req.body.email
- sendingUser = AuthenticationController.getSessionUser(req)
- sendingUserId = sendingUser._id
- if email == sendingUser.email
- logger.log {projectId, email, sendingUserId}, "cannot invite yourself to project"
- return res.json {invite: null, error: 'cannot_invite_self'}
- logger.log {projectId, email, sendingUserId}, "inviting to project"
- LimitationsManager.canAddXCollaborators projectId, 1, (error, allowed) =>
- return next(error) if error?
- if !allowed
- logger.log {projectId, email, sendingUserId}, "not allowed to invite more users to project"
- return res.json {invite: null}
- {email, privileges} = req.body
- email = EmailHelper.parseEmail(email)
- if !email? or email == ""
- logger.log {projectId, email, sendingUserId}, "invalid email address"
- return res.status(400).send({errorReason:"invalid_email"})
- CollaboratorsInviteController._checkRateLimit sendingUserId, (error, underRateLimit) ->
- return next(error) if error?
- if !underRateLimit
- return res.sendStatus(429)
- CollaboratorsInviteController._checkShouldInviteEmail email, (err, shouldAllowInvite)->
- if err?
- logger.err {err, email, projectId, sendingUserId}, "error checking if we can invite this email address"
- return next(err)
- if !shouldAllowInvite
- logger.log {email, projectId, sendingUserId}, "not allowed to send an invite to this email address"
- return res.json {invite: null, error: 'cannot_invite_non_user'}
- CollaboratorsInviteHandler.inviteToProject projectId, sendingUser, email, privileges, (err, invite) ->
- if err?
- logger.err {projectId, email, sendingUserId}, "error creating project invite"
- return next(err)
- logger.log {projectId, email, sendingUserId}, "invite created"
- EditorRealTimeController.emitToRoom(projectId, 'project:membership:changed', {invites: true})
- return res.json {invite: invite}
-
- revokeInvite: (req, res, next) ->
- projectId = req.params.Project_id
- inviteId = req.params.invite_id
- logger.log {projectId, inviteId}, "revoking invite"
- CollaboratorsInviteHandler.revokeInvite projectId, inviteId, (err) ->
- if err?
- logger.err {projectId, inviteId}, "error revoking invite"
- return next(err)
- EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true}
- res.sendStatus(201)
-
- resendInvite: (req, res, next) ->
- projectId = req.params.Project_id
- inviteId = req.params.invite_id
- logger.log {projectId, inviteId}, "resending invite"
- sendingUser = AuthenticationController.getSessionUser(req)
- CollaboratorsInviteController._checkRateLimit sendingUser._id, (error, underRateLimit) ->
- return next(error) if error?
- if !underRateLimit
- return res.sendStatus(429)
- CollaboratorsInviteHandler.resendInvite projectId, sendingUser, inviteId, (err) ->
- if err?
- logger.err {projectId, inviteId}, "error resending invite"
- return next(err)
- res.sendStatus(201)
-
- viewInvite: (req, res, next) ->
- projectId = req.params.Project_id
- token = req.params.token
- _renderInvalidPage = () ->
- logger.log {projectId, token}, "invite not valid, rendering not-valid page"
- res.render "project/invite/not-valid", {title: "Invalid Invite"}
- # check if the user is already a member of the project
- currentUser = AuthenticationController.getSessionUser(req)
- CollaboratorsHandler.isUserInvitedMemberOfProject currentUser._id, projectId, (err, isMember, _privilegeLevel) ->
- if err?
- logger.err {err, projectId}, "error checking if user is member of project"
- return next(err)
- if isMember
- logger.log {projectId, userId: currentUser._id}, "user is already a member of this project, redirecting"
- return res.redirect "/project/#{projectId}"
- # get the invite
- CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) ->
- if err?
- logger.err {projectId, token}, "error getting invite by token"
- return next(err)
- # check if invite is gone, or otherwise non-existent
- if !invite?
- logger.log {projectId, token}, "no invite found for this token"
- return _renderInvalidPage()
- # check the user who sent the invite exists
- UserGetter.getUser {_id: invite.sendingUserId}, {email: 1, first_name: 1, last_name: 1}, (err, owner) ->
- if err?
- logger.err {err, projectId}, "error getting project owner"
- return next(err)
- if !owner?
- logger.log {projectId}, "no project owner found"
- return _renderInvalidPage()
- # fetch the project name
- ProjectGetter.getProject projectId, {}, (err, project) ->
- if err?
- logger.err {err, projectId}, "error getting project"
- return next(err)
- if !project?
- logger.log {projectId}, "no project found"
- return _renderInvalidPage()
- # finally render the invite
- res.render "project/invite/show", {invite, project, owner, title: "Project Invite"}
-
- acceptInvite: (req, res, next) ->
- projectId = req.params.Project_id
- token = req.params.token
- currentUser = AuthenticationController.getSessionUser(req)
- logger.log {projectId, userId: currentUser._id, token}, "got request to accept invite"
- CollaboratorsInviteHandler.acceptInvite projectId, token, currentUser, (err) ->
- if err?
- logger.err {projectId, token}, "error accepting invite by token"
- return next(err)
- EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true, members: true}
- AnalyticsManger.recordEvent(currentUser._id, "project-invite-accept", {projectId:projectId, userId:currentUser._id})
- if req.xhr
- res.sendStatus 204 # Done async via project page notification
- else
- res.redirect "/project/#{projectId}"
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteHandler.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteHandler.coffee
deleted file mode 100644
index 58121dae2c..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteHandler.coffee
+++ /dev/null
@@ -1,144 +0,0 @@
-ProjectInvite = require("../../models/ProjectInvite").ProjectInvite
-logger = require('logger-sharelatex')
-CollaboratorsEmailHandler = require "./CollaboratorsEmailHandler"
-CollaboratorsHandler = require "./CollaboratorsHandler"
-UserGetter = require "../User/UserGetter"
-ProjectGetter = require "../Project/ProjectGetter"
-Async = require "async"
-PrivilegeLevels = require "../Authorization/PrivilegeLevels"
-Errors = require "../Errors/Errors"
-Crypto = require 'crypto'
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-
-
-module.exports = CollaboratorsInviteHandler =
-
- getAllInvites: (projectId, callback=(err, invites)->) ->
- logger.log {projectId}, "fetching invites for project"
- ProjectInvite.find {projectId: projectId}, (err, invites) ->
- if err?
- logger.err {err, projectId}, "error getting invites from mongo"
- return callback(err)
- logger.log {projectId, count: invites.length}, "found invites for project"
- callback(null, invites)
-
- getInviteCount: (projectId, callback=(err, count)->) ->
- logger.log {projectId}, "counting invites for project"
- ProjectInvite.count {projectId: projectId}, (err, count) ->
- if err?
- logger.err {err, projectId}, "error getting invites from mongo"
- return callback(err)
- callback(null, count)
-
- _trySendInviteNotification: (projectId, sendingUser, invite, callback=(err)->) ->
- email = invite.email
- UserGetter.getUserByAnyEmail email, {_id: 1}, (err, existingUser) ->
- if err?
- logger.err {projectId, email}, "error checking if user exists"
- return callback(err)
- if !existingUser?
- logger.log {projectId, email}, "no existing user found, returning"
- return callback(null)
- ProjectGetter.getProject projectId, {_id: 1, name: 1}, (err, project) ->
- if err?
- logger.err {projectId, email}, "error getting project"
- return callback(err)
- if !project?
- logger.log {projectId}, "no project found while sending notification, returning"
- return callback(null)
- NotificationsBuilder.projectInvite(invite, project, sendingUser, existingUser).create(callback)
-
- _tryCancelInviteNotification: (inviteId, callback=()->) ->
- NotificationsBuilder.projectInvite({_id: inviteId}, null, null, null).read(callback)
-
- _sendMessages: (projectId, sendingUser, invite, callback=(err)->) ->
- logger.log {projectId, inviteId: invite._id}, "sending notification and email for invite"
- CollaboratorsEmailHandler.notifyUserOfProjectInvite projectId, invite.email, invite, sendingUser, (err)->
- return callback(err) if err?
- CollaboratorsInviteHandler._trySendInviteNotification projectId, sendingUser, invite, (err)->
- return callback(err) if err?
- callback()
-
- inviteToProject: (projectId, sendingUser, email, privileges, callback=(err,invite)->) ->
- logger.log {projectId, sendingUserId: sendingUser._id, email, privileges}, "adding invite"
- Crypto.randomBytes 24, (err, buffer) ->
- if err?
- logger.err {err, projectId, sendingUserId: sendingUser._id, email}, "error generating random token"
- return callback(err)
- token = buffer.toString('hex')
- invite = new ProjectInvite {
- email: email
- token: token
- sendingUserId: sendingUser._id
- projectId: projectId
- privileges: privileges
- }
- invite.save (err, invite) ->
- if err?
- logger.err {err, projectId, sendingUserId: sendingUser._id, email}, "error saving token"
- return callback(err)
- # Send email and notification in background
- CollaboratorsInviteHandler._sendMessages projectId, sendingUser, invite, (err) ->
- if err?
- logger.err {err, projectId, email}, "error sending messages for invite"
- callback(null, invite)
-
-
- revokeInvite: (projectId, inviteId, callback=(err)->) ->
- logger.log {projectId, inviteId}, "removing invite"
- ProjectInvite.remove {projectId: projectId, _id: inviteId}, (err) ->
- if err?
- logger.err {err, projectId, inviteId}, "error removing invite"
- return callback(err)
- CollaboratorsInviteHandler._tryCancelInviteNotification(inviteId, ()->)
- callback(null)
-
- resendInvite: (projectId, sendingUser, inviteId, callback=(err)->) ->
- logger.log {projectId, inviteId}, "resending invite email"
- ProjectInvite.findOne {_id: inviteId, projectId: projectId}, (err, invite) ->
- if err?
- logger.err {err, projectId, inviteId}, "error finding invite"
- return callback(err)
- if !invite?
- logger.err {err, projectId, inviteId}, "no invite found, nothing to resend"
- return callback(null)
- CollaboratorsInviteHandler._sendMessages projectId, sendingUser, invite, (err) ->
- if err?
- logger.err {projectId, inviteId}, "error resending invite messages"
- return callback(err)
- callback(null)
-
- getInviteByToken: (projectId, tokenString, callback=(err,invite)->) ->
- logger.log {projectId, tokenString}, "fetching invite by token"
- ProjectInvite.findOne {projectId: projectId, token: tokenString}, (err, invite) ->
- if err?
- logger.err {err, projectId}, "error fetching invite"
- return callback(err)
- if !invite?
- logger.err {err, projectId, token: tokenString}, "no invite found"
- return callback(null, null)
- callback(null, invite)
-
- acceptInvite: (projectId, tokenString, user, callback=(err)->) ->
- logger.log {projectId, userId: user._id, tokenString}, "accepting invite"
- CollaboratorsInviteHandler.getInviteByToken projectId, tokenString, (err, invite) ->
- if err?
- logger.err {err, projectId, tokenString}, "error finding invite"
- return callback(err)
- if !invite
- err = new Errors.NotFoundError("no matching invite found")
- logger.log {err, projectId, tokenString}, "no matching invite found"
- return callback(err)
- inviteId = invite._id
- CollaboratorsHandler.addUserIdToProject projectId, invite.sendingUserId, user._id, invite.privileges, (err) ->
- if err?
- logger.err {err, projectId, inviteId, userId: user._id}, "error adding user to project"
- return callback(err)
- # Remove invite
- logger.log {projectId, inviteId}, "removing invite"
- ProjectInvite.remove {_id: inviteId}, (err) ->
- if err?
- logger.err {err, projectId, inviteId}, "error removing invite"
- return callback(err)
- CollaboratorsInviteHandler._tryCancelInviteNotification inviteId, ()->
- callback()
diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsRouter.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsRouter.coffee
deleted file mode 100644
index 82d1b0fc9b..0000000000
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsRouter.coffee
+++ /dev/null
@@ -1,79 +0,0 @@
-CollaboratorsController = require('./CollaboratorsController')
-AuthenticationController = require('../Authentication/AuthenticationController')
-AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
-CollaboratorsInviteController = require('./CollaboratorsInviteController')
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-CaptchaMiddleware = require '../Captcha/CaptchaMiddleware'
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.post '/project/:Project_id/leave', AuthenticationController.requireLogin(), CollaboratorsController.removeSelfFromProject
-
- webRouter.delete '/project/:Project_id/users/:user_id', AuthorizationMiddleware.ensureUserCanAdminProject, CollaboratorsController.removeUserFromProject
-
- webRouter.get(
- '/project/:Project_id/members',
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanAdminProject,
- CollaboratorsController.getAllMembers
- )
-
- # invites
- webRouter.post(
- '/project/:Project_id/invite',
- RateLimiterMiddleware.rateLimit({
- endpointName: "invite-to-project-by-project-id"
- params: ["Project_id"]
- maxRequests: 100
- timeInterval: 60 * 10
- }),
- RateLimiterMiddleware.rateLimit({
- endpointName: "invite-to-project-by-ip"
- ipOnly:true
- maxRequests: 100
- timeInterval: 60 * 10
- }),
- CaptchaMiddleware.validateCaptcha('invite'),
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanAdminProject,
- CollaboratorsInviteController.inviteToProject
- )
-
- webRouter.get(
- '/project/:Project_id/invites',
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanAdminProject,
- CollaboratorsInviteController.getAllInvites
- )
-
- webRouter.delete(
- '/project/:Project_id/invite/:invite_id',
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanAdminProject,
- CollaboratorsInviteController.revokeInvite
- )
-
- webRouter.post(
- '/project/:Project_id/invite/:invite_id/resend',
- RateLimiterMiddleware.rateLimit({
- endpointName: "resend-invite"
- params: ["Project_id"]
- maxRequests: 200
- timeInterval: 60 * 10
- }),
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanAdminProject,
- CollaboratorsInviteController.resendInvite
- )
-
- webRouter.get(
- '/project/:Project_id/invite/token/:token',
- AuthenticationController.requireLogin(),
- CollaboratorsInviteController.viewInvite
- )
-
- webRouter.post(
- '/project/:Project_id/invite/token/:token/accept',
- AuthenticationController.requireLogin(),
- CollaboratorsInviteController.acceptInvite
- )
diff --git a/services/web/app/coffee/Features/Compile/ClsiCookieManager.coffee b/services/web/app/coffee/Features/Compile/ClsiCookieManager.coffee
deleted file mode 100644
index f2c982a077..0000000000
--- a/services/web/app/coffee/Features/Compile/ClsiCookieManager.coffee
+++ /dev/null
@@ -1,81 +0,0 @@
-Settings = require "settings-sharelatex"
-request = require('request')
-RedisWrapper = require("../../infrastructure/RedisWrapper")
-rclient = RedisWrapper.client("clsi_cookie")
-if Settings.redis.clsi_cookie_secondary?
- rclient_secondary = RedisWrapper.client("clsi_cookie_secondary")
-Cookie = require('cookie')
-logger = require "logger-sharelatex"
-
-
-clsiCookiesEnabled = Settings.clsiCookie?.key? and Settings.clsiCookie.key.length != 0
-
-
-module.exports = (backendGroup)->
-
- buildKey : (project_id)->
- if backendGroup?
- return "clsiserver:#{backendGroup}:#{project_id}"
- else
- return "clsiserver:#{project_id}"
-
- _getServerId : (project_id, callback = (err, serverId)->)->
- rclient.get @buildKey(project_id), (err, serverId)=>
- if err?
- return callback(err)
- if !serverId? or serverId == ""
- return @_populateServerIdViaRequest project_id, callback
- else
- return callback(null, serverId)
-
-
- _populateServerIdViaRequest :(project_id, callback = (err, serverId)->)->
- url = "#{Settings.apis.clsi.url}/project/#{project_id}/status"
- request.get url, (err, res, body)=>
- if err?
- logger.err err:err, project_id:project_id, "error getting initial server id for project"
- return callback(err)
- @setServerId project_id, res, (err, serverId)->
- if err?
- logger.err err:err, project_id:project_id, "error setting server id via populate request"
- callback(err, serverId)
-
- _parseServerIdFromResponse : (response)->
- cookies = Cookie.parse(response.headers["set-cookie"]?[0] or "")
- return cookies?[Settings.clsiCookie.key]
-
- setServerId: (project_id, response, callback = (err, serverId)->)->
- if !clsiCookiesEnabled
- return callback()
- serverId = @_parseServerIdFromResponse(response)
- if !serverId? # We don't get a cookie back if it hasn't changed
- return rclient.expire(@buildKey(project_id), Settings.clsiCookie.ttl, callback)
- if rclient_secondary?
- @_setServerIdInRedis rclient_secondary, project_id, serverId
- @_setServerIdInRedis rclient, project_id, serverId, (err) ->
- callback(err, serverId)
-
- _setServerIdInRedis: (rclient, project_id, serverId, callback = (err) ->) ->
- multi = rclient.multi()
- multi.set @buildKey(project_id), serverId
- multi.expire @buildKey(project_id), Settings.clsiCookie.ttl
- multi.exec callback
-
- clearServerId: (project_id, callback = (err)->)->
- if !clsiCookiesEnabled
- return callback()
- rclient.del @buildKey(project_id), callback
-
- getCookieJar: (project_id, callback = (err, jar)->)->
- if !clsiCookiesEnabled
- return callback(null, request.jar())
- @_getServerId project_id, (err, serverId)=>
- if err?
- logger.err err:err, project_id:project_id, "error getting server id"
- return callback(err)
- serverCookie = request.cookie("#{Settings.clsiCookie.key}=#{serverId}")
- jar = request.jar()
- jar.setCookie serverCookie, Settings.apis.clsi.url
- callback(null, jar)
-
-
diff --git a/services/web/app/coffee/Features/Compile/ClsiFormatChecker.coffee b/services/web/app/coffee/Features/Compile/ClsiFormatChecker.coffee
deleted file mode 100644
index 81807baf70..0000000000
--- a/services/web/app/coffee/Features/Compile/ClsiFormatChecker.coffee
+++ /dev/null
@@ -1,69 +0,0 @@
-_ = require("lodash")
-async = require("async")
-settings = require("settings-sharelatex")
-
-module.exports = ClsiFormatChecker =
-
- checkRecoursesForProblems: (resources, callback)->
- jobs =
- conflictedPaths: (cb)->
- ClsiFormatChecker._checkForConflictingPaths resources, cb
-
- sizeCheck: (cb)->
- ClsiFormatChecker._checkDocsAreUnderSizeLimit resources, cb
-
- async.series jobs, (err, problems)->
- if err?
- return callback(err)
-
- problems = _.omitBy(problems, _.isEmpty)
-
- if _.isEmpty(problems)
- return callback()
- else
- callback(null, problems)
-
-
- _checkForConflictingPaths: (resources, callback)->
- paths = _.map(resources, 'path')
-
- conflicts = _.filter paths, (path)->
- matchingPaths = _.filter paths, (checkPath)->
- return checkPath.indexOf(path+"/") != -1
-
- return matchingPaths.length > 0
-
- conflictObjects = _.map conflicts, (conflict)->
- path:conflict
-
- callback null, conflictObjects
-
- _checkDocsAreUnderSizeLimit: (resources, callback)->
-
- sizeLimit = 1000 * 1000 * settings.compileBodySizeLimitMb
-
- totalSize = 0
-
- sizedResources = _.map resources, (resource)->
- result = {path:resource.path}
- if resource.content?
- result.size = resource.content.replace(/\n/g).length
- result.kbSize = Math.ceil(result.size / 1000)
- else
- result.size = 0
- totalSize += result.size
- return result
-
- tooLarge = totalSize > sizeLimit
- if !tooLarge
- return callback()
- else
- sizedResources = _.sortBy(sizedResources, "size").reverse().slice(0, 10)
- return callback(null, {resources:sizedResources, totalSize:totalSize})
-
-
-
-
-
-
-
diff --git a/services/web/app/coffee/Features/Compile/ClsiManager.coffee b/services/web/app/coffee/Features/Compile/ClsiManager.coffee
deleted file mode 100755
index b0f7a01fa1..0000000000
--- a/services/web/app/coffee/Features/Compile/ClsiManager.coffee
+++ /dev/null
@@ -1,344 +0,0 @@
-Path = require "path"
-async = require "async"
-Settings = require "settings-sharelatex"
-request = require('request')
-Project = require("../../models/Project").Project
-ProjectGetter = require("../Project/ProjectGetter")
-ProjectEntityHandler = require("../Project/ProjectEntityHandler")
-logger = require "logger-sharelatex"
-Url = require("url")
-ClsiCookieManager = require("./ClsiCookieManager")(Settings.apis.clsi?.backendGroupName)
-NewBackendCloudClsiCookieManager = require("./ClsiCookieManager")(Settings.apis.clsi_new?.backendGroupName)
-ClsiStateManager = require("./ClsiStateManager")
-_ = require("underscore")
-async = require("async")
-ClsiFormatChecker = require("./ClsiFormatChecker")
-DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
-Metrics = require('metrics-sharelatex')
-Errors = require ('../Errors/Errors')
-
-module.exports = ClsiManager =
-
- sendRequest: (project_id, user_id, options = {}, callback) ->
- ClsiManager.sendRequestOnce project_id, user_id, options, (error, status, result...) ->
- return callback(error) if error?
- if status is 'conflict'
- options = _.clone(options)
- options.syncType = "full" # force full compile
- ClsiManager.sendRequestOnce project_id, user_id, options, callback # try again
- else
- callback(error, status, result...)
-
- sendRequestOnce: (project_id, user_id, options = {}, callback = (error, status, outputFiles, clsiServerId, validationProblems) ->) ->
- ClsiManager._buildRequest project_id, options, (error, req) ->
- if error?
- if error.message is "no main file specified"
- return callback(null, "validation-problems", null, null, {mainFile:error.message})
- else
- return callback(error)
- logger.log project_id: project_id, "sending compile to CLSI"
- ClsiManager._sendBuiltRequest project_id, user_id, req, options, (error, status, result...) ->
- return callback(error) if error?
- callback(error, status, result...)
-
- # for public API requests where there is no project id
- sendExternalRequest: (submission_id, clsi_request, options = {}, callback = (error, status, outputFiles, clsiServerId, validationProblems) ->) ->
- logger.log submission_id: submission_id, "sending external compile to CLSI", clsi_request
- ClsiManager._sendBuiltRequest submission_id, null, clsi_request, options, (error, status, result...) ->
- return callback(error) if error?
- callback(error, status, result...)
-
- stopCompile: (project_id, user_id, options, callback = (error) ->) ->
- compilerUrl = @_getCompilerUrl(options?.compileGroup, project_id, user_id, "compile/stop")
- opts =
- url:compilerUrl
- method:"POST"
- ClsiManager._makeRequest project_id, opts, callback
-
- deleteAuxFiles: (project_id, user_id, options, callback = (error) ->) ->
- compilerUrl = @_getCompilerUrl(options?.compileGroup, project_id, user_id)
- opts =
- url:compilerUrl
- method:"DELETE"
- ClsiManager._makeRequest project_id, opts, (clsiError) ->
- # always clear the project state from the docupdater, even if there
- # was a problem with the request to the clsi
- DocumentUpdaterHandler.clearProjectState project_id, (docUpdaterError) ->
- error = clsiError or docUpdaterError
- return callback(error) if error?
- callback()
-
- _sendBuiltRequest: (project_id, user_id, req, options = {}, callback = (error, status, outputFiles, clsiServerId, validationProblems) ->) ->
- ClsiFormatChecker.checkRecoursesForProblems req.compile?.resources, (err, validationProblems)->
- if err?
- logger.err err, project_id, "could not check resources for potential problems before sending to clsi"
- return callback(err)
- if validationProblems?
- logger.log project_id:project_id, validationProblems:validationProblems, "problems with users latex before compile was attempted"
- return callback(null, "validation-problems", null, null, validationProblems)
- ClsiManager._postToClsi project_id, user_id, req, options.compileGroup, (error, response) ->
- if error?
- logger.err err:error, project_id:project_id, "error sending request to clsi"
- return callback(error)
- logger.log project_id: project_id, outputFilesLength: response?.outputFiles?.length, status: response?.status, compile_status: response?.compile?.status, "received compile response from CLSI"
- ClsiCookieManager._getServerId project_id, (err, clsiServerId)->
- if err?
- logger.err err:err, project_id:project_id, "error getting server id"
- return callback(err)
- outputFiles = ClsiManager._parseOutputFiles(project_id, response?.compile?.outputFiles)
- callback(null, response?.compile?.status, outputFiles, clsiServerId)
-
- _makeRequest: (project_id, opts, callback)->
- async.series {
- currentBackend: (cb)->
- startTime = new Date()
- ClsiCookieManager.getCookieJar project_id, (err, jar)->
- if err?
- logger.err err:err, "error getting cookie jar for clsi request"
- return callback(err)
- opts.jar = jar
- timer = new Metrics.Timer("compile.currentBackend")
- request opts, (err, response, body)->
- timer.done()
- Metrics.inc "compile.currentBackend.response.#{response?.statusCode}"
- if err?
- logger.err err:err, project_id:project_id, url:opts?.url, "error making request to clsi"
- return callback(err)
- ClsiCookieManager.setServerId project_id, response, (err)->
- if err?
- logger.warn err:err, project_id:project_id, "error setting server id"
- callback err, response, body #return as soon as the standard compile has returned
- cb(err, {response:response, body:body, finishTime:new Date() - startTime })
- newBackend: (cb)->
- startTime = new Date()
- ClsiManager._makeNewBackendRequest project_id, opts, (err, response, body)->
- Metrics.inc "compile.newBackend.response.#{response?.statusCode}"
- cb(err, {response:response, body:body, finishTime:new Date() - startTime})
- }, (err, results)->
- timeDifference = results.newBackend?.finishTime - results.currentBackend?.finishTime
- statusCodeSame = results.newBackend?.response?.statusCode == results.currentBackend?.response?.statusCode
- currentCompileTime = results.currentBackend?.finishTime
- newBackendCompileTime = results.newBackend?.finishTime
- logger.log {statusCodeSame, timeDifference, currentCompileTime, newBackendCompileTime, project_id}, "both clsi requests returned"
-
-
-
- _makeNewBackendRequest: (project_id, baseOpts, callback)->
- if !Settings.apis.clsi_new?.url?
- return callback()
- opts = _.clone(baseOpts)
- opts.url = opts.url.replace(Settings.apis.clsi.url, Settings.apis.clsi_new?.url)
- NewBackendCloudClsiCookieManager.getCookieJar project_id, (err, jar)->
- if err?
- logger.err err:err, "error getting cookie jar for clsi request"
- return callback(err)
- opts.jar = jar
- timer = new Metrics.Timer("compile.newBackend")
- request opts, (err, response, body)->
- timer.done()
- if err?
- logger.warn err:err, project_id:project_id, url:opts?.url, "error making request to new clsi"
- return callback(err)
- NewBackendCloudClsiCookieManager.setServerId project_id, response, (err)->
- if err?
- logger.warn err:err, project_id:project_id, "error setting server id new backend"
- return callback err, response, body
-
-
- _getCompilerUrl: (compileGroup, project_id, user_id, action) ->
- host = Settings.apis.clsi.url
- path = "/project/#{project_id}"
- path += "/user/#{user_id}" if user_id?
- path += "/#{action}" if action?
- return "#{host}#{path}"
-
- _postToClsi: (project_id, user_id, req, compileGroup, callback = (error, response) ->) ->
- compileUrl = @_getCompilerUrl(compileGroup, project_id, user_id, "compile")
- opts =
- url: compileUrl
- json: req
- method: "POST"
- ClsiManager._makeRequest project_id, opts, (error, response, body) ->
- return callback(error) if error?
- if 200 <= response.statusCode < 300
- callback null, body
- else if response.statusCode == 413
- callback null, compile:status:"project-too-large"
- else if response.statusCode == 409
- callback null, compile:status:"conflict"
- else if response.statusCode == 423
- callback null, compile:status:"compile-in-progress"
- else
- error = new Error("CLSI returned non-success code: #{response.statusCode}")
- logger.error err: error, project_id: project_id, "CLSI returned failure code"
- callback error, body
-
- _parseOutputFiles: (project_id, rawOutputFiles = []) ->
- outputFiles = []
- for file in rawOutputFiles
- outputFiles.push
- path: file.path # the clsi is now sending this to web
- url: Url.parse(file.url).path # the location of the file on the clsi, excluding the host part
- type: file.type
- build: file.build
- return outputFiles
-
- VALID_COMPILERS: ["pdflatex", "latex", "xelatex", "lualatex"]
-
- _buildRequest: (project_id, options={}, callback = (error, request) ->) ->
- ProjectGetter.getProject project_id, {compiler: 1, rootDoc_id: 1, imageName: 1, rootFolder:1}, (error, project) ->
- return callback(error) if error?
- return callback(new Errors.NotFoundError("project does not exist: #{project_id}")) if !project?
- if project.compiler not in ClsiManager.VALID_COMPILERS
- project.compiler = "pdflatex"
-
- if options.incrementalCompilesEnabled or options.syncType? # new way, either incremental or full
- timer = new Metrics.Timer("editor.compile-getdocs-redis")
- ClsiManager.getContentFromDocUpdaterIfMatch project_id, project, options, (error, projectStateHash, docUpdaterDocs) ->
- timer.done()
- if error?
- logger.error err: error, project_id: project_id, "error checking project state"
- # note: we don't bail out when there's an error getting
- # incremental files from the docupdater, we just fall back
- # to a normal compile below
- else
- logger.log project_id: project_id, projectStateHash: projectStateHash, docs: docUpdaterDocs?, "checked project state"
- # see if we can send an incremental update to the CLSI
- if docUpdaterDocs? and (options.syncType isnt "full") and not error?
- Metrics.inc "compile-from-redis"
- ClsiManager._buildRequestFromDocupdater project_id, options, project, projectStateHash, docUpdaterDocs, callback
- else
- Metrics.inc "compile-from-mongo"
- ClsiManager._buildRequestFromMongo project_id, options, project, projectStateHash, callback
- else # old way, always from mongo
- timer = new Metrics.Timer("editor.compile-getdocs-mongo")
- ClsiManager._getContentFromMongo project_id, (error, docs, files) ->
- timer.done()
- return callback(error) if error?
- ClsiManager._finaliseRequest project_id, options, project, docs, files, callback
-
- getContentFromDocUpdaterIfMatch: (project_id, project, options, callback = (error, projectStateHash, docs) ->) ->
- ClsiStateManager.computeHash project, options, (error, projectStateHash) ->
- return callback(error) if error?
- DocumentUpdaterHandler.getProjectDocsIfMatch project_id, projectStateHash, (error, docs) ->
- return callback(error) if error?
- callback(null, projectStateHash, docs)
-
- getOutputFileStream: (project_id, user_id, build_id, output_file_path, callback=(err, readStream)->) ->
- url = "#{Settings.apis.clsi.url}/project/#{project_id}/user/#{user_id}/build/#{build_id}/output/#{output_file_path}"
- ClsiCookieManager.getCookieJar project_id, (err, jar)->
- return callback(err) if err?
- options = { url: url, method: "GET", timeout: 60 * 1000, jar : jar }
- readStream = request(options)
- callback(null, readStream)
-
- _buildRequestFromDocupdater: (project_id, options, project, projectStateHash, docUpdaterDocs, callback = (error, request) ->) ->
- ProjectEntityHandler.getAllDocPathsFromProject project, (error, docPath) ->
- return callback(error) if error?
- docs = {}
- for doc in docUpdaterDocs or []
- path = docPath[doc._id]
- docs[path] = doc
- # send new docs but not files as those are already on the clsi
- options = _.clone(options)
- options.syncType = "incremental"
- options.syncState = projectStateHash
- # create stub doc entries for any possible root docs, if not
- # present in the docupdater. This allows finaliseRequest to
- # identify the root doc.
- possibleRootDocIds = [options.rootDoc_id, project.rootDoc_id]
- for rootDoc_id in possibleRootDocIds when rootDoc_id? and rootDoc_id of docPath
- path = docPath[rootDoc_id]
- docs[path] ?= {_id: rootDoc_id, path: path}
- ClsiManager._finaliseRequest project_id, options, project, docs, [], callback
-
- _buildRequestFromMongo: (project_id, options, project, projectStateHash, callback = (error, request) ->) ->
- ClsiManager._getContentFromMongo project_id, (error, docs, files) ->
- return callback(error) if error?
- options = _.clone(options)
- options.syncType = "full"
- options.syncState = projectStateHash
- ClsiManager._finaliseRequest project_id, options, project, docs, files, callback
-
- _getContentFromMongo: (project_id, callback = (error, docs, files) ->) ->
- DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
- return callback(error) if error?
- ProjectEntityHandler.getAllDocs project_id, (error, docs = {}) ->
- return callback(error) if error?
- ProjectEntityHandler.getAllFiles project_id, (error, files = {}) ->
- return callback(error) if error?
- callback(null, docs, files)
-
- _finaliseRequest: (project_id, options, project, docs, files, callback = (error, params) -> ) ->
- resources = []
- rootResourcePath = null
- rootResourcePathOverride = null
- hasMainFile = false
- numberOfDocsInProject = 0
-
- for path, doc of docs
- path = path.replace(/^\//, "") # Remove leading /
- numberOfDocsInProject++
- if doc.lines? # add doc to resources unless it is just a stub entry
- resources.push
- path: path
- content: doc.lines.join("\n")
- if project.rootDoc_id? and doc._id.toString() == project.rootDoc_id.toString()
- rootResourcePath = path
- if options.rootDoc_id? and doc._id.toString() == options.rootDoc_id.toString()
- rootResourcePathOverride = path
- if path is "main.tex"
- hasMainFile = true
-
- rootResourcePath = rootResourcePathOverride if rootResourcePathOverride?
- if !rootResourcePath?
- if hasMainFile
- logger.warn {project_id}, "no root document found, setting to main.tex"
- rootResourcePath = "main.tex"
- else if numberOfDocsInProject is 1 # only one file, must be the main document
- for path, doc of docs
- rootResourcePath = path.replace(/^\//, "") # Remove leading /
- logger.warn {project_id, rootResourcePath: rootResourcePath}, "no root document found, single document in project"
- else
- return callback new Error("no main file specified")
-
- for path, file of files
- path = path.replace(/^\//, "") # Remove leading /
- resources.push
- path: path
- url: "#{Settings.apis.filestore.url}/project/#{project._id}/file/#{file._id}"
- modified: file.created?.getTime()
-
- callback null, {
- compile:
- options:
- compiler: project.compiler
- timeout: options.timeout
- imageName: project.imageName
- draft: !!options.draft
- check: options.check
- syncType: options.syncType
- syncState: options.syncState
- rootResourcePath: rootResourcePath
- resources: resources
- }
-
- wordCount: (project_id, user_id, file, options, callback = (error, response) ->) ->
- ClsiManager._buildRequest project_id, options, (error, req) ->
- filename = file || req?.compile?.rootResourcePath
- wordcount_url = ClsiManager._getCompilerUrl(options?.compileGroup, project_id, user_id, "wordcount")
- opts =
- url: wordcount_url
- qs:
- file: filename
- image: req.compile.options.imageName
- method: "GET"
- ClsiManager._makeRequest project_id, opts, (error, response, body) ->
- return callback(error) if error?
- if 200 <= response.statusCode < 300
- callback null, body
- else
- error = new Error("CLSI returned non-success code: #{response.statusCode}")
- logger.error err: error, project_id: project_id, "CLSI returned failure code"
- callback error, body
-
diff --git a/services/web/app/coffee/Features/Compile/ClsiStateManager.coffee b/services/web/app/coffee/Features/Compile/ClsiStateManager.coffee
deleted file mode 100644
index 9aff9c166d..0000000000
--- a/services/web/app/coffee/Features/Compile/ClsiStateManager.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-Settings = require "settings-sharelatex"
-logger = require "logger-sharelatex"
-crypto = require "crypto"
-ProjectEntityHandler = require "../Project/ProjectEntityHandler"
-
-# The "state" of a project is a hash of the relevant attributes in the
-# project object in this case we only need the rootFolder.
-#
-# The idea is that it will change if any doc or file is
-# created/renamed/deleted, and also if the content of any file (not
-# doc) changes.
-#
-# When the hash changes the full set of files on the CLSI will need to
-# be updated. If it doesn't change then we can overwrite changed docs
-# in place on the clsi, getting them from the docupdater.
-#
-# The docupdater is responsible for setting the key in redis, and
-# unsetting it if it removes any documents from the doc updater.
-
-buildState = (s) ->
- return crypto.createHash('sha1').update(s, 'utf8').digest('hex')
-
-module.exports = ClsiStateManager =
-
- computeHash: (project, options, callback = (err, hash) ->) ->
- ProjectEntityHandler.getAllEntitiesFromProject project, (err, docs, files) ->
- fileList = ("#{f.file._id}:#{f.file.rev}:#{f.file.created}:#{f.path}" for f in files or [])
- docList = ("#{d.doc._id}:#{d.path}" for d in docs or [])
- sortedEntityList = [docList..., fileList...].sort()
- # ignore the isAutoCompile options as it doesn't affect the
- # output, but include all other options e.g. draft
- optionsList = ("option #{key}:#{value}" for key, value of options or {} when not (key in ['isAutoCompile']))
- sortedOptionsList = optionsList.sort()
- hash = buildState([sortedEntityList..., sortedOptionsList...].join("\n"))
- callback(null, hash)
diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee
deleted file mode 100755
index 8e64e8a3cf..0000000000
--- a/services/web/app/coffee/Features/Compile/CompileController.coffee
+++ /dev/null
@@ -1,280 +0,0 @@
-Metrics = require "metrics-sharelatex"
-ProjectGetter = require('../Project/ProjectGetter')
-CompileManager = require("./CompileManager")
-ClsiManager = require("./ClsiManager")
-logger = require "logger-sharelatex"
-request = require "request"
-sanitize = require('sanitizer')
-Settings = require "settings-sharelatex"
-AuthenticationController = require "../Authentication/AuthenticationController"
-UserGetter = require "../User/UserGetter"
-RateLimiter = require("../../infrastructure/RateLimiter")
-ClsiCookieManager = require("./ClsiCookieManager")(Settings.apis.clsi?.backendGroupName)
-Path = require("path")
-
-module.exports = CompileController =
-
- compile: (req, res, next = (error) ->) ->
- res.setTimeout(5 * 60 * 1000)
- project_id = req.params.Project_id
- isAutoCompile = !!req.query?.auto_compile
- user_id = AuthenticationController.getLoggedInUserId req
- options = {
- isAutoCompile: isAutoCompile
- }
- if req.body?.rootDoc_id?
- options.rootDoc_id = req.body.rootDoc_id
- else if req.body?.settingsOverride?.rootDoc_id? # Can be removed after deploy
- options.rootDoc_id = req.body.settingsOverride.rootDoc_id
- if req.body?.compiler
- options.compiler = req.body.compiler
- if req.body?.draft
- options.draft = req.body.draft
- if req.body?.check in ['validate', 'error', 'silent']
- options.check = req.body.check
- if req.body?.incrementalCompilesEnabled
- options.incrementalCompilesEnabled = true
- logger.log {options:options, project_id:project_id, user_id:user_id}, "got compile request"
- CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
- return next(error) if error?
- res.contentType("application/json")
- res.status(200).send JSON.stringify {
- status: status
- outputFiles: outputFiles
- compileGroup: limits?.compileGroup
- clsiServerId:clsiServerId
- validationProblems:validationProblems
- pdfDownloadDomain: Settings.pdfDownloadDomain
- }
-
- stopCompile: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- user_id = AuthenticationController.getLoggedInUserId req
- logger.log {project_id:project_id, user_id:user_id}, "stop compile request"
- CompileManager.stopCompile project_id, user_id, (error) ->
- return next(error) if error?
- res.status(200).send()
-
- # Used for submissions through the public API
- compileSubmission: (req, res, next = (error) ->) ->
- res.setTimeout(5 * 60 * 1000)
- submission_id = req.params.submission_id
- options = {}
- if req.body?.rootResourcePath?
- options.rootResourcePath = req.body.rootResourcePath
- if req.body?.compiler
- options.compiler = req.body.compiler
- if req.body?.draft
- options.draft = req.body.draft
- if req.body?.check in ['validate', 'error', 'silent']
- options.check = req.body.check
- options.compileGroup = req.body?.compileGroup || Settings.defaultFeatures.compileGroup
- options.timeout = req.body?.timeout || Settings.defaultFeatures.compileTimeout
- logger.log {options:options, submission_id:submission_id}, "got compileSubmission request"
- ClsiManager.sendExternalRequest submission_id, req.body, options, (error, status, outputFiles, clsiServerId, validationProblems) ->
- return next(error) if error?
- logger.log {submission_id:submission_id, files:outputFiles}, "compileSubmission output files"
- res.contentType("application/json")
- res.status(200).send JSON.stringify {
- status: status
- outputFiles: outputFiles
- clsiServerId: clsiServerId
- validationProblems: validationProblems
- }
-
- _compileAsUser: (req, callback) ->
- # callback with user_id if per-user, undefined otherwise
- if not Settings.disablePerUserCompiles
- user_id = AuthenticationController.getLoggedInUserId req
- return callback(null, user_id)
- else
- callback() # do a per-project compile, not per-user
-
- _downloadAsUser: (req, callback) ->
- # callback with user_id if per-user, undefined otherwise
- if not Settings.disablePerUserCompiles
- user_id = AuthenticationController.getLoggedInUserId req
- return callback(null, user_id)
- else
- callback() # do a per-project compile, not per-user
-
- downloadPdf: (req, res, next = (error) ->)->
- Metrics.inc "pdf-downloads"
- project_id = req.params.Project_id
- isPdfjsPartialDownload = req.query?.pdfng
- rateLimit = (callback)->
- if isPdfjsPartialDownload
- callback null, true
- else
- rateLimitOpts =
- endpointName: "full-pdf-download"
- throttle: 1000
- subjectName : req.ip
- timeInterval : 60 * 60
- RateLimiter.addCount rateLimitOpts, callback
-
- ProjectGetter.getProject project_id, name: 1, (err, project) ->
- res.contentType("application/pdf")
- filename = "#{CompileController._getSafeProjectName(project)}.pdf"
-
- if !!req.query.popupDownload
- logger.log project_id: project_id, "download pdf as popup download"
- res.setContentDisposition('attachment', {filename})
- else
- logger.log project_id: project_id, "download pdf to embed in browser"
- res.setContentDisposition('', {filename})
-
- rateLimit (err, canContinue)->
- if err?
- logger.err err:err, "error checking rate limit for pdf download"
- return res.send 500
- else if !canContinue
- logger.log project_id:project_id, ip:req.ip, "rate limit hit downloading pdf"
- res.send 500
- else
- CompileController._downloadAsUser req, (error, user_id) ->
- url = CompileController._getFileUrl project_id, user_id, req.params.build_id, "output.pdf"
- CompileController.proxyToClsi(project_id, url, req, res, next)
-
- _getSafeProjectName: (project) ->
- safeProjectName = project.name.replace(new RegExp("\\W", "g"), '_')
- sanitize.escape(safeProjectName)
-
- deleteAuxFiles: (req, res, next) ->
- project_id = req.params.Project_id
- CompileController._compileAsUser req, (error, user_id) ->
- return next(error) if error?
- CompileManager.deleteAuxFiles project_id, user_id, (error) ->
- return next(error) if error?
- res.sendStatus(200)
-
- # this is only used by templates, so is not called with a user_id
- compileAndDownloadPdf: (req, res, next)->
- project_id = req.params.project_id
- # pass user_id as null, since templates are an "anonymous" compile
- CompileManager.compile project_id, null, {}, (err)->
- if err?
- logger.err err:err, project_id:project_id, "something went wrong compile and downloading pdf"
- res.sendStatus 500
- url = "/project/#{project_id}/output/output.pdf"
- CompileController.proxyToClsi project_id, url, req, res, next
-
- getFileFromClsi: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- CompileController._downloadAsUser req, (error, user_id) ->
- return next(error) if error?
- url = CompileController._getFileUrl project_id, user_id, req.params.build_id, req.params.file
- CompileController.proxyToClsi(project_id, url, req, res, next)
-
- getFileFromClsiWithoutUser: (req, res, next = (error) ->) ->
- submission_id = req.params.submission_id
- url = CompileController._getFileUrl submission_id, null, req.params.build_id, req.params.file
- limits = { compileGroup: req.body?.compileGroup || Settings.defaultFeatures.compileGroup }
- CompileController.proxyToClsiWithLimits(submission_id, url, limits, req, res, next)
-
- # compute a GET file url for a given project, user (optional), build (optional) and file
- _getFileUrl: (project_id, user_id, build_id, file) ->
- if user_id? and build_id?
- url = "/project/#{project_id}/user/#{user_id}/build/#{build_id}/output/#{file}"
- else if user_id?
- url = "/project/#{project_id}/user/#{user_id}/output/#{file}"
- else if build_id?
- url = "/project/#{project_id}/build/#{build_id}/output/#{file}"
- else
- url = "/project/#{project_id}/output/#{file}"
- return url
-
- # compute a POST url for a project, user (optional) and action
- _getUrl: (project_id, user_id, action) ->
- path = "/project/#{project_id}"
- path += "/user/#{user_id}" if user_id?
- return "#{path}/#{action}"
-
- proxySyncPdf: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- {page, h, v} = req.query
- if not page?.match(/^\d+$/)
- return next(new Error("invalid page parameter"))
- if not h?.match(/^-?\d+\.\d+$/)
- return next(new Error("invalid h parameter"))
- if not v?.match(/^-?\d+\.\d+$/)
- return next(new Error("invalid v parameter"))
- # whether this request is going to a per-user container
- CompileController._compileAsUser req, (error, user_id) ->
- return next(error) if error?
- url = CompileController._getUrl(project_id, user_id, "sync/pdf")
- destination = {url: url, qs: {page, h, v}}
- CompileController.proxyToClsi(project_id, destination, req, res, next)
-
- proxySyncCode: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- {file, line, column} = req.query
- if not file?
- return next(new Error("missing file parameter"))
- # Check that we are dealing with a simple file path (this is not
- # strictly needed because synctex uses this parameter as a label
- # to look up in the synctex output, and does not open the file
- # itself). Since we have valid synctex paths like foo/./bar we
- # allow those by replacing /./ with /
- testPath = file.replace '/./', '/'
- if Path.resolve("/", testPath) isnt "/#{testPath}"
- return next(new Error("invalid file parameter"))
- if not line?.match(/^\d+$/)
- return next(new Error("invalid line parameter"))
- if not column?.match(/^\d+$/)
- return next(new Error("invalid column parameter"))
- CompileController._compileAsUser req, (error, user_id) ->
- return next(error) if error?
- url = CompileController._getUrl(project_id, user_id, "sync/code")
- destination = {url:url, qs: {file, line, column}}
- CompileController.proxyToClsi(project_id, destination, req, res, next)
-
- proxyToClsi: (project_id, url, req, res, next = (error) ->) ->
- if req.query?.compileGroup
- CompileController.proxyToClsiWithLimits(project_id, url, {compileGroup: req.query.compileGroup}, req, res, next)
- else
- CompileManager.getProjectCompileLimits project_id, (error, limits) ->
- return next(error) if error?
- CompileController.proxyToClsiWithLimits(project_id, url, limits, req, res, next)
-
- proxyToClsiWithLimits: (project_id, url, limits, req, res, next = (error) ->) ->
- ClsiCookieManager.getCookieJar project_id, (err, jar)->
- if err?
- logger.err err:err, "error getting cookie jar for clsi request"
- return callback(err)
- # expand any url parameter passed in as {url:..., qs:...}
- if typeof url is "object"
- {url, qs} = url
- compilerUrl = Settings.apis.clsi.url
- url = "#{compilerUrl}#{url}"
- logger.log url: url, "proxying to CLSI"
- oneMinute = 60 * 1000
- # the base request
- options = { url: url, method: req.method, timeout: oneMinute, jar : jar }
- # add any provided query string
- options.qs = qs if qs?
- # if we have a build parameter, pass it through to the clsi
- if req.query?.pdfng && req.query?.build? # only for new pdf viewer
- options.qs ?= {}
- options.qs.build = req.query.build
- # if we are byte serving pdfs, pass through If-* and Range headers
- # do not send any others, there's a proxying loop if Host: is passed!
- if req.query?.pdfng
- newHeaders = {}
- for h, v of req.headers
- newHeaders[h] = req.headers[h] if /^(If-|Range)/i.test(h)
- options.headers = newHeaders
- proxy = request(options)
- proxy.pipe(res)
- proxy.on "error", (error) ->
- logger.warn err: error, url: url, "CLSI proxy error"
-
- wordCount: (req, res, next) ->
- project_id = req.params.Project_id
- file = req.query.file || false
- CompileController._compileAsUser req, (error, user_id) ->
- return next(error) if error?
- CompileManager.wordCount project_id, user_id, file, (error, body) ->
- return next(error) if error?
- res.contentType("application/json")
- res.send body
diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee
deleted file mode 100755
index 5e76104273..0000000000
--- a/services/web/app/coffee/Features/Compile/CompileManager.coffee
+++ /dev/null
@@ -1,109 +0,0 @@
-Settings = require('settings-sharelatex')
-RedisWrapper = require("../../infrastructure/RedisWrapper")
-rclient = RedisWrapper.client("clsi_recently_compiled")
-ProjectGetter = require('../Project/ProjectGetter')
-ProjectRootDocManager = require "../Project/ProjectRootDocManager"
-UserGetter = require "../User/UserGetter"
-ClsiManager = require "./ClsiManager"
-Metrics = require('metrics-sharelatex')
-logger = require("logger-sharelatex")
-rateLimiter = require("../../infrastructure/RateLimiter")
-
-module.exports = CompileManager =
-
-
- compile: (project_id, user_id, options = {}, _callback = (error) ->) ->
- timer = new Metrics.Timer("editor.compile")
- callback = (args...) ->
- timer.done()
- _callback(args...)
-
- logger.log project_id: project_id, user_id: user_id, "compiling project"
- CompileManager._checkIfRecentlyCompiled project_id, user_id, (error, recentlyCompiled) ->
- return callback(error) if error?
- if recentlyCompiled
- logger.warn {project_id, user_id}, "project was recently compiled so not continuing"
- return callback null, "too-recently-compiled", []
-
- CompileManager._checkIfAutoCompileLimitHasBeenHit options.isAutoCompile, "everyone", (err, canCompile)->
- if !canCompile
- return callback null, "autocompile-backoff", []
-
- ProjectRootDocManager.ensureRootDocumentIsSet project_id, (error) ->
- return callback(error) if error?
- CompileManager.getProjectCompileLimits project_id, (error, limits) ->
- return callback(error) if error?
- for key, value of limits
- options[key] = value
- # Put a lower limit on autocompiles for free users, based on compileGroup
- CompileManager._checkCompileGroupAutoCompileLimit options.isAutoCompile, limits.compileGroup, (err, canCompile)->
- if !canCompile
- return callback null, "autocompile-backoff", []
- # only pass user_id down to clsi if this is a per-user compile
- compileAsUser = if Settings.disablePerUserCompiles then undefined else user_id
- ClsiManager.sendRequest project_id, compileAsUser, options, (error, status, outputFiles, clsiServerId, validationProblems) ->
- return callback(error) if error?
- logger.log files: outputFiles, "output files"
- callback(null, status, outputFiles, clsiServerId, limits, validationProblems)
-
-
- stopCompile: (project_id, user_id, callback = (error) ->) ->
- CompileManager.getProjectCompileLimits project_id, (error, limits) ->
- return callback(error) if error?
- ClsiManager.stopCompile project_id, user_id, limits, callback
-
- deleteAuxFiles: (project_id, user_id, callback = (error) ->) ->
- CompileManager.getProjectCompileLimits project_id, (error, limits) ->
- return callback(error) if error?
- ClsiManager.deleteAuxFiles project_id, user_id, limits, callback
-
- getProjectCompileLimits: (project_id, callback = (error, limits) ->) ->
- ProjectGetter.getProject project_id, owner_ref: 1, (error, project) ->
- return callback(error) if error?
- UserGetter.getUser project.owner_ref, {"features":1}, (err, owner)->
- return callback(error) if error?
- callback null, {
- timeout: owner?.features?.compileTimeout || Settings.defaultFeatures.compileTimeout
- compileGroup: owner?.features?.compileGroup || Settings.defaultFeatures.compileGroup
- }
-
- COMPILE_DELAY: 1 # seconds
- _checkIfRecentlyCompiled: (project_id, user_id, callback = (error, recentlyCompiled) ->) ->
- key = "compile:#{project_id}:#{user_id}"
- rclient.set key, true, "EX", @COMPILE_DELAY, "NX", (error, ok) ->
- return callback(error) if error?
- if ok == "OK"
- return callback null, false
- else
- return callback null, true
-
- _checkCompileGroupAutoCompileLimit: (isAutoCompile, compileGroup, callback = (err, canCompile)->)->
- if !isAutoCompile
- return callback(null, true)
- if compileGroup is "standard"
- # apply extra limits to the standard compile group
- CompileManager._checkIfAutoCompileLimitHasBeenHit isAutoCompile, compileGroup, callback
- else
- Metrics.inc "auto-compile-#{compileGroup}"
- return callback(null, true) # always allow priority group users to compile
-
- _checkIfAutoCompileLimitHasBeenHit: (isAutoCompile, compileGroup, callback = (err, canCompile)->)->
- if !isAutoCompile
- return callback(null, true)
- Metrics.inc "auto-compile-#{compileGroup}"
- opts =
- endpointName:"auto_compile"
- timeInterval:20
- subjectName:compileGroup
- throttle: Settings?.rateLimit?.autoCompile?[compileGroup] || 25
- rateLimiter.addCount opts, (err, canCompile)->
- if err?
- canCompile = false
- if !canCompile
- Metrics.inc "auto-compile-#{compileGroup}-limited"
- callback err, canCompile
-
- wordCount: (project_id, user_id, file, callback = (error) ->) ->
- CompileManager.getProjectCompileLimits project_id, (error, limits) ->
- return callback(error) if error?
- ClsiManager.wordCount project_id, user_id, file, limits, callback
diff --git a/services/web/app/coffee/Features/Contacts/ContactController.coffee b/services/web/app/coffee/Features/Contacts/ContactController.coffee
deleted file mode 100644
index c2df6cc989..0000000000
--- a/services/web/app/coffee/Features/Contacts/ContactController.coffee
+++ /dev/null
@@ -1,42 +0,0 @@
-AuthenticationController = require "../Authentication/AuthenticationController"
-ContactManager = require "./ContactManager"
-UserGetter = require "../User/UserGetter"
-logger = require "logger-sharelatex"
-Modules = require "../../infrastructure/Modules"
-
-module.exports = ContactsController =
- getContacts: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId req
- ContactManager.getContactIds user_id, {limit: 50}, (error, contact_ids) ->
- return next(error) if error?
- UserGetter.getUsers contact_ids, {
- email: 1, first_name: 1, last_name: 1, holdingAccount: 1
- }, (error, contacts) ->
- return next(error) if error?
-
- # UserGetter.getUsers may not preserve order so put them back in order
- positions = {}
- for contact_id, i in contact_ids
- positions[contact_id] = i
- contacts.sort (a,b) -> positions[a._id?.toString()] - positions[b._id?.toString()]
-
- # Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
- contacts = contacts.filter (c) -> !c.holdingAccount
-
- contacts = contacts.map(ContactsController._formatContact)
-
- Modules.hooks.fire "getContacts", user_id, contacts, (error, additional_contacts) ->
- return next(error) if error?
- contacts = contacts.concat(additional_contacts...)
- res.send({
- contacts: contacts
- })
-
- _formatContact: (contact) ->
- return {
- id: contact._id?.toString()
- email: contact.email || ""
- first_name: contact.first_name || ""
- last_name: contact.last_name || ""
- type: "user"
- }
diff --git a/services/web/app/coffee/Features/Contacts/ContactManager.coffee b/services/web/app/coffee/Features/Contacts/ContactManager.coffee
deleted file mode 100644
index 8f08b5ea41..0000000000
--- a/services/web/app/coffee/Features/Contacts/ContactManager.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-request = require "request"
-settings = require "settings-sharelatex"
-logger = require "logger-sharelatex"
-
-module.exports = ContactManager =
- getContactIds: (user_id, options = { limits: 50 }, callback = (error, contacts) ->) ->
- logger.log {user_id}, "getting user contacts"
- url = "#{settings.apis.contacts.url}/user/#{user_id}/contacts"
- request.get {
- url: url
- qs: options
- json: true
- jar: false
- }, (error, res, data) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- callback(null, data?.contact_ids or [])
- else
- error = new Error("contacts api responded with non-success code: #{res.statusCode}")
- logger.error {err: error, user_id}, "error getting contacts for user"
- callback(error)
-
- addContact: (user_id, contact_id, callback = (error) ->) ->
- logger.log {user_id, contact_id}, "add user contact"
- url = "#{settings.apis.contacts.url}/user/#{user_id}/contacts"
- request.post {
- url: url
- json: {
- contact_id: contact_id
- }
- jar: false
- }, (error, res, data) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- callback(null, data?.contact_ids or [])
- else
- error = new Error("contacts api responded with non-success code: #{res.statusCode}")
- logger.error {err: error, user_id, contact_id}, "error adding contact for user"
- callback(error)
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Contacts/ContactRouter.coffee b/services/web/app/coffee/Features/Contacts/ContactRouter.coffee
deleted file mode 100644
index 211a83c18f..0000000000
--- a/services/web/app/coffee/Features/Contacts/ContactRouter.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-ContactController = require "./ContactController"
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.get '/user/contacts',
- AuthenticationController.requireLogin(),
- ContactController.getContacts
-
diff --git a/services/web/app/coffee/Features/Cooldown/CooldownManager.coffee b/services/web/app/coffee/Features/Cooldown/CooldownManager.coffee
deleted file mode 100644
index 9797cbf04d..0000000000
--- a/services/web/app/coffee/Features/Cooldown/CooldownManager.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-RedisWrapper = require('../../infrastructure/RedisWrapper')
-rclient = RedisWrapper.client('cooldown')
-logger = require('logger-sharelatex')
-
-
-COOLDOWN_IN_SECONDS = 60 * 10
-
-
-module.exports = CooldownManager =
-
- _buildKey: (projectId) ->
- "Cooldown:{#{projectId}}"
-
- putProjectOnCooldown: (projectId, callback=(err)->) ->
- logger.log {projectId}, "[Cooldown] putting project on cooldown for #{COOLDOWN_IN_SECONDS} seconds"
- rclient.set(CooldownManager._buildKey(projectId), '1', 'EX', COOLDOWN_IN_SECONDS, callback)
-
- isProjectOnCooldown: (projectId, callback=(err, isOnCooldown)->) ->
- rclient.get CooldownManager._buildKey(projectId), (err, result) ->
- if err?
- return callback(err)
- callback(null, result == "1")
-
diff --git a/services/web/app/coffee/Features/Cooldown/CooldownMiddleware.coffee b/services/web/app/coffee/Features/Cooldown/CooldownMiddleware.coffee
deleted file mode 100644
index ee8edd6def..0000000000
--- a/services/web/app/coffee/Features/Cooldown/CooldownMiddleware.coffee
+++ /dev/null
@@ -1,17 +0,0 @@
-CooldownManager = require('./CooldownManager')
-logger = require('logger-sharelatex')
-
-
-module.exports = CooldownMiddleware =
-
- freezeProject: (req, res, next) ->
- projectId = req.params.Project_id
- if !projectId?
- return next(new Error('[Cooldown] No projectId parameter on route'))
- CooldownManager.isProjectOnCooldown projectId, (err, projectIsOnCooldown) ->
- if err?
- return next(err)
- if projectIsOnCooldown
- logger.log {projectId}, "[Cooldown] project is on cooldown, denying request"
- return res.sendStatus(429)
- next()
diff --git a/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee b/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee
deleted file mode 100644
index 927121a6a1..0000000000
--- a/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee
+++ /dev/null
@@ -1,123 +0,0 @@
-request = require("request").defaults(jar: false)
-logger = require "logger-sharelatex"
-settings = require "settings-sharelatex"
-Errors = require "../Errors/Errors"
-
-module.exports = DocstoreManager =
- deleteDoc: (project_id, doc_id, callback = (error) ->) ->
- logger.log project_id: project_id, doc_id: doc_id, "deleting doc in docstore api"
- url = "#{settings.apis.docstore.url}/project/#{project_id}/doc/#{doc_id}"
- request.del url, (error, res, body) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- callback(null)
- else if res.statusCode is 404
- error = new Errors.NotFoundError("tried to delete doc not in docstore")
- logger.error err: error, project_id: project_id, doc_id: doc_id, "tried to delete doc not in docstore"
- callback(error) # maybe suppress the error when delete doc which is not present?
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.error err: error, project_id: project_id, doc_id: doc_id, "error deleting doc in docstore"
- callback(error)
-
- getAllDocs: (project_id, callback = (error) ->) ->
- logger.log project_id: project_id, "getting all docs for project in docstore api"
- url = "#{settings.apis.docstore.url}/project/#{project_id}/doc"
- request.get {
- url: url
- json: true
- }, (error, res, docs) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- callback(null, docs)
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.error err: error, project_id: project_id, "error getting all docs from docstore"
- callback(error)
-
- getAllRanges: (project_id, callback = (error) ->) ->
- logger.log { project_id }, "getting all doc ranges for project in docstore api"
- url = "#{settings.apis.docstore.url}/project/#{project_id}/ranges"
- request.get {
- url: url
- json: true
- }, (error, res, docs) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- callback(null, docs)
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.error err: error, project_id: project_id, "error getting all doc ranges from docstore"
- callback(error)
-
- getDoc: (project_id, doc_id, options = {}, callback = (error, lines, rev, version) ->) ->
- if typeof(options) == "function"
- callback = options
- options = {}
- logger.log project_id: project_id, doc_id: doc_id, options: options, "getting doc in docstore api"
- url = "#{settings.apis.docstore.url}/project/#{project_id}/doc/#{doc_id}"
- if options.include_deleted
- url += "?include_deleted=true"
- request.get {
- url: url
- json: true
- }, (error, res, doc) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- logger.log doc_id: doc_id, project_id: project_id, version: doc.version, rev: doc.rev, "got doc from docstore api"
- callback(null, doc.lines, doc.rev, doc.version, doc.ranges)
- else if res.statusCode is 404
- error = new Errors.NotFoundError("doc not found in docstore")
- logger.error err: error, project_id: project_id, doc_id: doc_id, "doc not found in docstore"
- callback(error)
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.error err: error, project_id: project_id, doc_id: doc_id, "error getting doc from docstore"
- callback(error)
-
- updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) ->
- logger.log project_id: project_id, doc_id: doc_id, "updating doc in docstore api"
- url = "#{settings.apis.docstore.url}/project/#{project_id}/doc/#{doc_id}"
- request.post {
- url: url
- json:
- lines: lines
- version: version
- ranges: ranges
- }, (error, res, result) ->
- return callback(error) if error?
- if 200 <= res.statusCode < 300
- logger.log project_id: project_id, doc_id: doc_id, "update doc in docstore url finished"
- callback(null, result.modified, result.rev)
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.error err: error, project_id: project_id, doc_id: doc_id, "error updating doc in docstore"
- callback(error)
-
- archiveProject: (project_id, callback)->
- url = "#{settings.apis.docstore.url}/project/#{project_id}/archive"
- logger.log project_id:project_id, "archiving project in docstore"
- request.post url, (err, res, docs) ->
- if err?
- logger.err err:err, project_id:project_id, "error archving project in docstore"
- return callback(err)
- if 200 <= res.statusCode < 300
- callback()
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.err err: error, project_id: project_id, "error archiving project in docstore"
- return callback(error)
-
- unarchiveProject: (project_id, callback)->
- url = "#{settings.apis.docstore.url}/project/#{project_id}/unarchive"
- logger.log project_id:project_id, "unarchiving project in docstore"
- request.post url, (err, res, docs) ->
- if err?
- logger.err err:err, project_id:project_id, "error unarchiving project in docstore"
- return callback(err)
- if 200 <= res.statusCode < 300
- callback()
- else
- error = new Error("docstore api responded with non-success code: #{res.statusCode}")
- logger.err err: error, project_id: project_id, "error unarchiving project in docstore"
- return callback(error)
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee b/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee
deleted file mode 100644
index 80206a2a1c..0000000000
--- a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee
+++ /dev/null
@@ -1,231 +0,0 @@
-request = require 'request'
-request = request.defaults()
-settings = require 'settings-sharelatex'
-_ = require 'underscore'
-async = require 'async'
-logger = require('logger-sharelatex')
-metrics = require('metrics-sharelatex')
-Project = require("../../models/Project").Project
-
-module.exports = DocumentUpdaterHandler =
- flushProjectToMongo: (project_id, callback = (error) ->)->
- logger.log project_id:project_id, "flushing project from document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/flush"
- method: "POST"
- }, project_id, "flushing.mongo.project", callback
-
- flushMultipleProjectsToMongo: (project_ids, callback = (error) ->) ->
- jobs = []
- for project_id in project_ids
- do (project_id) ->
- jobs.push (callback) ->
- DocumentUpdaterHandler.flushProjectToMongo project_id, callback
- async.series jobs, callback
-
- flushProjectToMongoAndDelete: (project_id, callback = ()->) ->
- timer = new metrics.Timer("delete.mongo.project")
- url = "#{settings.apis.documentupdater.url}"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}"
- method: "DELETE"
- }, project_id, "flushing.mongo.project", callback
-
- flushDocToMongo: (project_id, doc_id, callback = (error) ->) ->
- logger.log project_id:project_id, doc_id: doc_id, "flushing doc from document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}/flush"
- method: "POST"
- }, project_id, "flushing.mongo.doc", callback
-
- deleteDoc : (project_id, doc_id, callback = ()->)->
- logger.log project_id:project_id, doc_id: doc_id, "deleting doc from document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}"
- method: "DELETE"
- }, project_id, "delete.mongo.doc", callback
-
- getDocument: (project_id, doc_id, fromVersion, callback = (error, doclines, version, ranges, ops) ->) ->
- logger.log project_id:project_id, doc_id: doc_id, "getting doc from document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}?fromVersion=#{fromVersion}"
- json: true
- }, project_id, "get-document", (error, doc) ->
- return callback(error) if error?
- callback null, doc.lines, doc.version, doc.ranges, doc.ops
-
- setDocument : (project_id, doc_id, user_id, docLines, source, callback = (error) ->)->
- logger.log project_id:project_id, doc_id: doc_id, source: source, user_id: user_id, "setting doc in document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}"
- method: "POST"
- json:
- lines: docLines
- source: source
- user_id: user_id
- }, project_id, "set-document", callback
-
- getProjectDocsIfMatch: (project_id, projectStateHash, callback = (error, docs) ->) ->
- # If the project state hasn't changed, we can get all the latest
- # docs from redis via the docupdater. Otherwise we will need to
- # fall back to getting them from mongo.
- timer = new metrics.Timer("get-project-docs")
- url = "#{settings.apis.documentupdater.url}/project/#{project_id}/get_and_flush_if_old?state=#{projectStateHash}"
- logger.log project_id:project_id, "getting project docs from document updater"
- request.post url, (error, res, body)->
- timer.done()
- if error?
- logger.error err:error, url:url, project_id:project_id, "error getting project docs from doc updater"
- return callback(error)
- if res.statusCode is 409 # HTTP response code "409 Conflict"
- # Docupdater has checked the projectStateHash and found that
- # it has changed. This means that the docs currently in redis
- # aren't the only change to the project and the full set of
- # docs/files should be retreived from docstore/filestore
- # instead.
- return callback()
- else if res.statusCode >= 200 and res.statusCode < 300
- logger.log project_id:project_id, "got project docs from document document updater"
- try
- docs = JSON.parse(body)
- catch error
- return callback(error)
- callback null, docs
- else
- logger.error project_id:project_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}"
- callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
-
- clearProjectState: (project_id, callback = (error) ->) ->
- logger.log project_id:project_id, "clearing project state from document updater"
-
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/clearState"
- method: "POST"
- }, project_id, "clear-project-state", callback
-
- acceptChanges: (project_id, doc_id, change_ids = [], callback = (error) ->) ->
- logger.log {project_id, doc_id }, "accepting #{ change_ids.length } changes"
-
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}/change/accept"
- json:
- change_ids: change_ids
- method: "POST"
- }, project_id, "accept-changes", callback
-
- deleteThread: (project_id, doc_id, thread_id, callback = (error) ->) ->
- timer = new metrics.Timer("delete-thread")
- logger.log {project_id, doc_id, thread_id}, "deleting comment range in document updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/doc/#{doc_id}/comment/#{thread_id}"
- method: "DELETE"
- }, project_id, "delete-thread", callback
-
- resyncProjectHistory: (project_id, projectHistoryId, docs, files, callback) ->
- logger.info {project_id, docs, files}, "resyncing project history in doc updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}/history/resync"
- json: { docs, files, projectHistoryId }
- method: "POST"
- }, project_id, "resync-project-history", callback
-
- updateProjectStructure: (project_id, projectHistoryId, userId, changes, callback = (error) ->)->
- return callback() if !settings.apis.project_history?.sendProjectStructureOps
-
- docUpdates = DocumentUpdaterHandler._getUpdates('doc', changes.oldDocs, changes.newDocs)
- fileUpdates = DocumentUpdaterHandler._getUpdates('file', changes.oldFiles, changes.newFiles)
- projectVersion = changes?.newProject?.version
-
- return callback() if (docUpdates.length + fileUpdates.length) < 1
-
- if !projectVersion?
- logger.error {project_id, changes, projectVersion}, "did not receive project version in changes"
- return callback(new Error("did not receive project version in changes"))
-
- logger.log {project_id}, "updating project structure in doc updater"
- DocumentUpdaterHandler._makeRequest {
- path: "/project/#{project_id}"
- json: {
- docUpdates,
- fileUpdates,
- userId,
- version: projectVersion
- projectHistoryId
- }
- method: "POST"
- }, project_id, "update-project-structure", callback
-
- _makeRequest: (options, project_id, metricsKey, callback) ->
- timer = new metrics.Timer(metricsKey)
- request {
- url: "#{settings.apis.documentupdater.url}#{options.path}"
- json: options.json
- method: options.method || "GET"
- }, (error, res, body)->
- timer.done()
- if error?
- logger.error {error, project_id}, "error making request to document updater"
- callback error
- else if res.statusCode >= 200 and res.statusCode < 300
- callback null, body
- else
- error = new Error("document updater returned a failure status code: #{res.statusCode}")
- logger.error {error, project_id}, "document updater returned failure status code: #{res.statusCode}"
- callback error
-
- _getUpdates: (entityType, oldEntities, newEntities) ->
- oldEntities ||= []
- newEntities ||= []
- updates = []
-
- oldEntitiesHash = _.indexBy oldEntities, (entity) -> entity[entityType]._id.toString()
- newEntitiesHash = _.indexBy newEntities, (entity) -> entity[entityType]._id.toString()
-
- # Send deletes before adds (and renames) to keep a 1:1 mapping between
- # paths and ids
- #
- # When a file is replaced, we first delete the old file and then add the
- # new file. If the 'add' operation is sent to project history before the
- # 'delete' then we would have two files with the same path at that point
- # in time.
- for id, oldEntity of oldEntitiesHash
- newEntity = newEntitiesHash[id]
-
- if !newEntity?
- # entity deleted
- updates.push
- id: id
- pathname: oldEntity.path
- newPathname: ''
-
- for id, newEntity of newEntitiesHash
- oldEntity = oldEntitiesHash[id]
-
- if !oldEntity?
- # entity added
- updates.push
- id: id
- pathname: newEntity.path
- docLines: newEntity.docLines
- url: newEntity.url
- hash: newEntity.file?.hash
- else if newEntity.path != oldEntity.path
- # entity renamed
- updates.push
- id: id
- pathname: oldEntity.path
- newPathname: newEntity.path
-
- updates
-
-PENDINGUPDATESKEY = "PendingUpdates"
-DOCLINESKEY = "doclines"
-DOCIDSWITHPENDINGUPDATES = "DocsWithPendingUpdates"
-
-keys =
- pendingUpdates : (op) -> "#{PENDINGUPDATESKEY}:#{op.doc_id}"
- docsWithPendingUpdates: DOCIDSWITHPENDINGUPDATES
- docLines : (op) -> "#{DOCLINESKEY}:#{op.doc_id}"
- combineProjectIdAndDocId: (project_id, doc_id) -> "#{project_id}:#{doc_id}"
-
-
diff --git a/services/web/app/coffee/Features/Documents/DocumentController.coffee b/services/web/app/coffee/Features/Documents/DocumentController.coffee
deleted file mode 100644
index b687e74966..0000000000
--- a/services/web/app/coffee/Features/Documents/DocumentController.coffee
+++ /dev/null
@@ -1,48 +0,0 @@
-ProjectGetter = require "../Project/ProjectGetter"
-ProjectLocator = require "../Project/ProjectLocator"
-ProjectEntityHandler = require "../Project/ProjectEntityHandler"
-ProjectEntityUpdateHandler = require "../Project/ProjectEntityUpdateHandler"
-logger = require("logger-sharelatex")
-
-module.exports =
- getDocument: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- doc_id = req.params.doc_id
- plain = req?.query?.plain == 'true'
- logger.log doc_id:doc_id, project_id:project_id, "receiving get document request from api (docupdater)"
- ProjectGetter.getProject project_id, rootFolder: true, overleaf: true, (error, project) ->
- return next(error) if error?
- return res.sendStatus(404) if !project?
- ProjectLocator.findElement {project: project, element_id: doc_id, type: 'doc'}, (error, doc, path) ->
- if error?
- logger.err err:error, doc_id:doc_id, project_id:project_id, "error finding element for getDocument"
- return next(error)
- ProjectEntityHandler.getDoc project_id, doc_id, (error, lines, rev, version, ranges) ->
- if error?
- logger.err err:error, doc_id:doc_id, project_id:project_id, "error finding doc contents for getDocument"
- return next(error)
- if plain
- res.type "text/plain"
- res.send lines.join('\n')
-
- else
- projectHistoryId = project?.overleaf?.history?.id
- res.json {
- lines: lines
- version: version
- ranges: ranges
- pathname: path.fileSystem
- projectHistoryId: projectHistoryId
- }
-
- setDocument: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- doc_id = req.params.doc_id
- {lines, version, ranges, lastUpdatedAt, lastUpdatedBy} = req.body
- logger.log doc_id:doc_id, project_id:project_id, "receiving set document request from api (docupdater)"
- ProjectEntityUpdateHandler.updateDocLines project_id, doc_id, lines, version, ranges, lastUpdatedAt, lastUpdatedBy, (error) ->
- if error?
- logger.err err:error, doc_id:doc_id, project_id:project_id, "error finding element for getDocument"
- return next(error)
- logger.log doc_id:doc_id, project_id:project_id, "finished receiving set document request from api (docupdater)"
- res.sendStatus 200
diff --git a/services/web/app/coffee/Features/Documents/DocumentHelper.coffee b/services/web/app/coffee/Features/Documents/DocumentHelper.coffee
deleted file mode 100644
index 39cf812823..0000000000
--- a/services/web/app/coffee/Features/Documents/DocumentHelper.coffee
+++ /dev/null
@@ -1,34 +0,0 @@
-module.exports = DocumentHelper =
- getTitleFromTexContent: (content, maxContentToScan = 30000) ->
- TITLE_WITH_CURLY_BRACES = /\\[tT]itle\*?\s*{([^}]+)}/
- TITLE_WITH_SQUARE_BRACES = /\\[tT]itle\s*\[([^\]]+)\]/
- for line in DocumentHelper._getLinesFromContent(content, maxContentToScan)
- if match = line.match(TITLE_WITH_CURLY_BRACES) || line.match(TITLE_WITH_SQUARE_BRACES)
- return DocumentHelper.detex(match[1])
-
- return null
-
- contentHasDocumentclass: (content, maxContentToScan = 30000) ->
- for line in DocumentHelper._getLinesFromContent(content, maxContentToScan)
- # We've had problems with this regex locking up CPU.
- # Previously /.*\\documentclass/ would totally lock up on lines of 500kb (data text files :()
- # This regex will only look from the start of the line, including whitespace so will return quickly
- # regardless of line length.
- return true if line.match /^\s*\\documentclass/
-
- return false
-
- detex: (string) ->
- return string.replace(/\\LaTeX/g, 'LaTeX')
- .replace(/\\TeX/g, 'TeX')
- .replace(/\\TikZ/g, 'TikZ')
- .replace(/\\BibTeX/g, 'BibTeX')
- .replace(/\\\[[A-Za-z0-9. ]*\]/g, ' ') # line spacing
- .replace(/\\(?:[a-zA-Z]+|.|)/g, '')
- .replace(/{}|~/g, ' ')
- .replace(/[${}]/g, '')
- .replace(/ +/g, ' ')
- .trim()
-
- _getLinesFromContent: (content, maxContentToScan) ->
- return if typeof content is 'string' then content.substring(0, maxContentToScan).split("\n") else content
diff --git a/services/web/app/coffee/Features/Downloads/ProjectDownloadsController.coffee b/services/web/app/coffee/Features/Downloads/ProjectDownloadsController.coffee
deleted file mode 100644
index e73dc06eb2..0000000000
--- a/services/web/app/coffee/Features/Downloads/ProjectDownloadsController.coffee
+++ /dev/null
@@ -1,40 +0,0 @@
-logger = require "logger-sharelatex"
-Metrics = require "metrics-sharelatex"
-ProjectGetter = require('../Project/ProjectGetter')
-ProjectZipStreamManager = require "./ProjectZipStreamManager"
-DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
-
-module.exports = ProjectDownloadsController =
- downloadProject: (req, res, next) ->
- project_id = req.params.Project_id
- Metrics.inc "zip-downloads"
- logger.log project_id: project_id, "downloading project"
- DocumentUpdaterHandler.flushProjectToMongo project_id, (error)->
- return next(error) if error?
- ProjectGetter.getProject project_id, name: true, (error, project) ->
- return next(error) if error?
- ProjectZipStreamManager.createZipStreamForProject project_id, (error, stream) ->
- return next(error) if error?
- res.setContentDisposition(
- 'attachment',
- {filename: "#{project.name}.zip"}
- )
- res.contentType('application/zip')
- stream.pipe(res)
-
- downloadMultipleProjects: (req, res, next) ->
- project_ids = req.query.project_ids.split(",")
- Metrics.inc "zip-downloads-multiple"
- logger.log project_ids: project_ids, "downloading multiple projects"
- DocumentUpdaterHandler.flushMultipleProjectsToMongo project_ids, (error) ->
- return next(error) if error?
- ProjectZipStreamManager.createZipStreamForMultipleProjects project_ids, (error, stream) ->
- return next(error) if error?
- res.setContentDisposition(
- 'attachment',
- {filename: "Overleaf Projects (#{project_ids.length} items).zip"}
- )
- res.contentType('application/zip')
- stream.pipe(res)
-
-
diff --git a/services/web/app/coffee/Features/Downloads/ProjectZipStreamManager.coffee b/services/web/app/coffee/Features/Downloads/ProjectZipStreamManager.coffee
deleted file mode 100644
index ed20d1953c..0000000000
--- a/services/web/app/coffee/Features/Downloads/ProjectZipStreamManager.coffee
+++ /dev/null
@@ -1,80 +0,0 @@
-archiver = require "archiver"
-async = require "async"
-logger = require "logger-sharelatex"
-ProjectEntityHandler = require "../Project/ProjectEntityHandler"
-ProjectGetter = require('../Project/ProjectGetter')
-FileStoreHandler = require("../FileStore/FileStoreHandler")
-
-module.exports = ProjectZipStreamManager =
- createZipStreamForMultipleProjects: (project_ids, callback = (error, stream) ->) ->
- # We'll build up a zip file that contains multiple zip files
-
- archive = archiver("zip")
- archive.on "error", (err)->
- logger.err err:err, project_ids:project_ids, "something went wrong building archive of project"
- callback null, archive
-
- logger.log project_ids: project_ids, "creating zip stream of multiple projects"
-
- jobs = []
- for project_id in project_ids or []
- do (project_id) ->
- jobs.push (callback) ->
- ProjectGetter.getProject project_id, name: true, (error, project) ->
- return callback(error) if error?
- logger.log project_id: project_id, name: project.name, "appending project to zip stream"
- ProjectZipStreamManager.createZipStreamForProject project_id, (error, stream) ->
- return callback(error) if error?
- archive.append stream, name: "#{project.name}.zip"
- stream.on "end", () ->
- logger.log project_id: project_id, name: project.name, "zip stream ended"
- callback()
-
- async.series jobs, () ->
- logger.log project_ids: project_ids, "finished creating zip stream of multiple projects"
- archive.finalize()
-
- createZipStreamForProject: (project_id, callback = (error, stream) ->) ->
- archive = archiver("zip")
- # return stream immediately before we start adding things to it
- archive.on "error", (err)->
- logger.err err:err, project_id:project_id, "something went wrong building archive of project"
- callback(null, archive)
- @addAllDocsToArchive project_id, archive, (error) =>
- if error?
- logger.error err: error, project_id: project_id, "error adding docs to zip stream"
- @addAllFilesToArchive project_id, archive, (error) =>
- if error?
- logger.error err: error, project_id: project_id, "error adding files to zip stream"
- archive.finalize()
-
-
- addAllDocsToArchive: (project_id, archive, callback = (error) ->) ->
- ProjectEntityHandler.getAllDocs project_id, (error, docs) ->
- return callback(error) if error?
- jobs = []
- for path, doc of docs
- do (path, doc) ->
- path = path.slice(1) if path[0] == "/"
- jobs.push (callback) ->
- logger.log project_id: project_id, "Adding doc"
- archive.append doc.lines.join("\n"), name: path
- callback()
- async.series jobs, callback
-
- addAllFilesToArchive: (project_id, archive, callback = (error) ->) ->
- ProjectEntityHandler.getAllFiles project_id, (error, files) ->
- return callback(error) if error?
- jobs = []
- for path, file of files
- do (path, file) ->
- jobs.push (callback) ->
- FileStoreHandler.getFileStream project_id, file._id, {}, (error, stream) ->
- if error?
- logger.err err:error, project_id:project_id, file_id:file._id, "something went wrong adding file to zip archive"
- return callback(err)
- path = path.slice(1) if path[0] == "/"
- archive.append stream, name: path
- stream.on "end", () ->
- callback()
- async.parallelLimit jobs, 5, callback
diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee
deleted file mode 100644
index 701ea0085b..0000000000
--- a/services/web/app/coffee/Features/Editor/EditorController.coffee
+++ /dev/null
@@ -1,217 +0,0 @@
-logger = require('logger-sharelatex')
-Metrics = require('metrics-sharelatex')
-sanitize = require('sanitizer')
-ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
-ProjectOptionsHandler = require('../Project/ProjectOptionsHandler')
-ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
-ProjectDeleter = require("../Project/ProjectDeleter")
-DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-EditorRealTimeController = require("./EditorRealTimeController")
-async = require('async')
-PublicAccessLevels = require("../Authorization/PublicAccessLevels")
-_ = require('underscore')
-
-module.exports = EditorController =
- addDoc: (project_id, folder_id, docName, docLines, source, user_id, callback = (error, doc)->)->
- EditorController.addDocWithRanges(project_id, folder_id, docName, docLines, {}, source, user_id, callback)
-
- addDocWithRanges: (project_id, folder_id, docName, docLines, docRanges, source, user_id, callback = (error, doc)->)->
- docName = docName.trim()
- logger.log {project_id, folder_id, docName, source}, "sending new doc to project"
- Metrics.inc "editor.add-doc"
- ProjectEntityUpdateHandler.addDocWithRanges project_id, folder_id, docName, docLines, docRanges, user_id, (err, doc, folder_id)=>
- if err?
- logger.err err:err, project_id:project_id, docName:docName, "error adding doc without lock"
- return callback(err)
- EditorRealTimeController.emitToRoom(project_id, 'reciveNewDoc', folder_id, doc, source)
- callback(err, doc)
-
- addFile: (project_id, folder_id, fileName, fsPath, linkedFileData, source, user_id, callback = (error, file)->)->
- fileName = fileName.trim()
- logger.log {project_id, folder_id, fileName, fsPath, linkedFileData, source, user_id}, "sending new file to project"
- Metrics.inc "editor.add-file"
- ProjectEntityUpdateHandler.addFile project_id, folder_id, fileName, fsPath, linkedFileData, user_id, (err, fileRef, folder_id)=>
- if err?
- logger.err err:err, project_id:project_id, folder_id:folder_id, fileName:fileName, "error adding file without lock"
- return callback(err)
- EditorRealTimeController.emitToRoom(project_id, 'reciveNewFile', folder_id, fileRef, source, linkedFileData)
- callback(err, fileRef)
-
- upsertDoc: (project_id, folder_id, docName, docLines, source, user_id, callback = (err)->)->
- ProjectEntityUpdateHandler.upsertDoc project_id, folder_id, docName, docLines, source, user_id, (err, doc, didAddNewDoc) ->
- if didAddNewDoc
- EditorRealTimeController.emitToRoom(project_id, 'reciveNewDoc', folder_id, doc, source)
- callback err, doc
-
- upsertFile: (project_id, folder_id, fileName, fsPath, linkedFileData, source, user_id, callback = (err, file) ->) ->
- ProjectEntityUpdateHandler.upsertFile project_id, folder_id, fileName, fsPath, linkedFileData, user_id, (err, newFile, didAddFile, existingFile) ->
- return callback(err) if err?
- if not didAddFile # replacement, so remove the existing file from the client
- EditorRealTimeController.emitToRoom project_id, 'removeEntity', existingFile._id, source
- # now add the new file on the client
- EditorRealTimeController.emitToRoom project_id, 'reciveNewFile', folder_id, newFile, source, linkedFileData
- callback null, newFile
-
- upsertDocWithPath: (project_id, elementPath, docLines, source, user_id, callback) ->
- ProjectEntityUpdateHandler.upsertDocWithPath project_id, elementPath, docLines, source, user_id, (err, doc, didAddNewDoc, newFolders, lastFolder) ->
- return callback(err) if err?
- EditorController._notifyProjectUsersOfNewFolders project_id, newFolders, (err) ->
- return callback(err) if err?
- if didAddNewDoc
- EditorRealTimeController.emitToRoom project_id, 'reciveNewDoc', lastFolder._id, doc, source
- callback()
-
- upsertFileWithPath: (project_id, elementPath, fsPath, linkedFileData, source, user_id, callback) ->
- ProjectEntityUpdateHandler.upsertFileWithPath project_id, elementPath, fsPath, linkedFileData, user_id, (err, newFile, didAddFile, existingFile, newFolders, lastFolder) ->
- return callback(err) if err?
- EditorController._notifyProjectUsersOfNewFolders project_id, newFolders, (err) ->
- return callback(err) if err?
- if not didAddFile # replacement, so remove the existing file from the client
- EditorRealTimeController.emitToRoom project_id, 'removeEntity', existingFile._id, source
- # now add the new file on the client
- EditorRealTimeController.emitToRoom project_id, 'reciveNewFile', lastFolder._id, newFile, source, linkedFileData
- callback()
-
- addFolder : (project_id, folder_id, folderName, source, callback = (error, folder)->)->
- folderName = folderName.trim()
- logger.log {project_id, folder_id, folderName, source}, "sending new folder to project"
- Metrics.inc "editor.add-folder"
- ProjectEntityUpdateHandler.addFolder project_id, folder_id, folderName, (err, folder, folder_id)=>
- if err?
- logger.err {err, project_id, folder_id, folderName, source}, "could not add folder"
- return callback(err)
- EditorController._notifyProjectUsersOfNewFolder project_id, folder_id, folder, (err) ->
- return callback(err) if err?
- callback null, folder
-
- mkdirp : (project_id, path, callback = (error, newFolders, lastFolder)->)->
- logger.log project_id:project_id, path:path, "making directories if they don't exist"
- ProjectEntityUpdateHandler.mkdirp project_id, path, (err, newFolders, lastFolder)=>
- if err?
- logger.err err:err, project_id:project_id, path:path, "could not mkdirp"
- return callback(err)
-
- EditorController._notifyProjectUsersOfNewFolders project_id, newFolders, (err) ->
- return callback(err) if err?
- callback null, newFolders, lastFolder
-
- deleteEntity : (project_id, entity_id, entityType, source, userId, callback = (error)->)->
- logger.log {project_id, entity_id, entityType, source}, "start delete process of entity"
- Metrics.inc "editor.delete-entity"
- ProjectEntityUpdateHandler.deleteEntity project_id, entity_id, entityType, userId, (err)->
- if err?
- logger.err {err, project_id, entity_id, entityType}, "could not delete entity"
- return callback(err)
- logger.log {project_id, entity_id, entityType}, "telling users entity has been deleted"
- EditorRealTimeController.emitToRoom(project_id, 'removeEntity', entity_id, source)
- callback()
-
- deleteEntityWithPath: (project_id, path, source, user_id, callback) ->
- ProjectEntityUpdateHandler.deleteEntityWithPath project_id, path, user_id, (err, entity_id) ->
- return callback(err) if err?
- EditorRealTimeController.emitToRoom(project_id, 'removeEntity', entity_id, source)
- callback null, entity_id
-
- notifyUsersProjectHasBeenDeletedOrRenamed: (project_id, callback)->
- EditorRealTimeController.emitToRoom(project_id, 'projectRenamedOrDeletedByExternalSource')
- callback()
-
- updateProjectDescription: (project_id, description, callback = ->)->
- logger.log project_id:project_id, description:description, "updating project description"
- ProjectDetailsHandler.setProjectDescription project_id, description, (err)->
- if err?
- logger.err err:err, project_id:project_id, description:description, "something went wrong setting the project description"
- return callback(err)
- EditorRealTimeController.emitToRoom(project_id, 'projectDescriptionUpdated', description)
- callback()
-
- deleteProject: (project_id, callback)->
- Metrics.inc "editor.delete-project"
- logger.log project_id:project_id, "recived message to delete project"
- ProjectDeleter.deleteProject project_id, callback
-
- renameEntity: (project_id, entity_id, entityType, newName, userId, callback = (error) ->)->
- newName = sanitize.escape(newName)
- Metrics.inc "editor.rename-entity"
- logger.log entity_id:entity_id, entity_id:entity_id, entity_id:entity_id, "reciving new name for entity for project"
- ProjectEntityUpdateHandler.renameEntity project_id, entity_id, entityType, newName, userId, (err) ->
- if err?
- logger.err err:err, project_id:project_id, entity_id:entity_id, entityType:entityType, newName:newName, "error renaming entity"
- return callback(err)
- if newName.length > 0
- EditorRealTimeController.emitToRoom project_id, 'reciveEntityRename', entity_id, newName
- callback()
-
- moveEntity: (project_id, entity_id, folder_id, entityType, userId, callback = (error) ->)->
- Metrics.inc "editor.move-entity"
- ProjectEntityUpdateHandler.moveEntity project_id, entity_id, folder_id, entityType, userId, (err) ->
- if err?
- logger.err err:err, project_id:project_id, entity_id:entity_id, folder_id:folder_id, "error moving entity"
- return callback(err)
- EditorRealTimeController.emitToRoom project_id, 'reciveEntityMove', entity_id, folder_id
- callback()
-
- renameProject: (project_id, newName, callback = (err) ->) ->
- ProjectDetailsHandler.renameProject project_id, newName, (err) ->
- if err?
- logger.err err:err, project_id:project_id, newName:newName, "error renaming project"
- return callback(err)
- EditorRealTimeController.emitToRoom project_id, 'projectNameUpdated', newName
- callback()
-
- setCompiler : (project_id, compiler, callback = (err) ->) ->
- ProjectOptionsHandler.setCompiler project_id, compiler, (err) ->
- return callback(err) if err?
- logger.log compiler:compiler, project_id:project_id, "setting compiler"
- EditorRealTimeController.emitToRoom project_id, 'compilerUpdated', compiler
- callback()
-
- setImageName : (project_id, imageName, callback = (err) ->) ->
- ProjectOptionsHandler.setImageName project_id, imageName, (err) ->
- return callback(err) if err?
- logger.log imageName:imageName, project_id:project_id, "setting imageName"
- EditorRealTimeController.emitToRoom project_id, 'imageNameUpdated', imageName
- callback()
-
- setSpellCheckLanguage : (project_id, languageCode, callback = (err) ->) ->
- ProjectOptionsHandler.setSpellCheckLanguage project_id, languageCode, (err) ->
- return callback(err) if err?
- logger.log languageCode:languageCode, project_id:project_id, "setting languageCode for spell check"
- EditorRealTimeController.emitToRoom project_id, 'spellCheckLanguageUpdated', languageCode
- callback()
-
- setPublicAccessLevel : (project_id, newAccessLevel, callback = (err) ->) ->
- ProjectDetailsHandler.setPublicAccessLevel project_id, newAccessLevel, (err) ->
- return callback(err) if err?
- EditorRealTimeController.emitToRoom(
- project_id,
- 'project:publicAccessLevel:changed',
- {newAccessLevel}
- )
- if newAccessLevel == PublicAccessLevels.TOKEN_BASED
- ProjectDetailsHandler.ensureTokensArePresent project_id, (err, tokens) ->
- return callback(err) if err?
- EditorRealTimeController.emitToRoom(
- project_id,
- 'project:tokens:changed',
- {tokens}
- )
- callback()
- else
- callback()
-
- setRootDoc: (project_id, newRootDocID, callback = (err) ->) ->
- ProjectEntityUpdateHandler.setRootDoc project_id, newRootDocID, (err) ->
- return callback(err) if err?
- EditorRealTimeController.emitToRoom project_id, 'rootDocUpdated', newRootDocID
- callback()
-
- _notifyProjectUsersOfNewFolders: (project_id, folders, callback = (error)->)->
- async.eachSeries folders,
- (folder, cb) -> EditorController._notifyProjectUsersOfNewFolder project_id, folder.parentFolder_id, folder, cb
- callback
-
- _notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)->
- logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users"
- EditorRealTimeController.emitToRoom(project_id, "reciveNewFolder", folder_id, folder)
- callback()
diff --git a/services/web/app/coffee/Features/Editor/EditorHttpController.coffee b/services/web/app/coffee/Features/Editor/EditorHttpController.coffee
deleted file mode 100644
index 743b9ac190..0000000000
--- a/services/web/app/coffee/Features/Editor/EditorHttpController.coffee
+++ /dev/null
@@ -1,134 +0,0 @@
-ProjectEntityUpdateHandler = require "../Project/ProjectEntityUpdateHandler"
-ProjectDeleter = require "../Project/ProjectDeleter"
-logger = require "logger-sharelatex"
-EditorRealTimeController = require "./EditorRealTimeController"
-EditorController = require "./EditorController"
-ProjectGetter = require('../Project/ProjectGetter')
-UserGetter = require('../User/UserGetter')
-AuthorizationManager = require("../Authorization/AuthorizationManager")
-ProjectEditorHandler = require('../Project/ProjectEditorHandler')
-Metrics = require('metrics-sharelatex')
-CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler")
-CollaboratorsInviteHandler = require("../Collaborators/CollaboratorsInviteHandler")
-PrivilegeLevels = require "../Authorization/PrivilegeLevels"
-TokenAccessHandler = require '../TokenAccess/TokenAccessHandler'
-AuthenticationController = require "../Authentication/AuthenticationController"
-
-module.exports = EditorHttpController =
- joinProject: (req, res, next) ->
- project_id = req.params.Project_id
- user_id = req.query.user_id
- if user_id == "anonymous-user"
- user_id = null
- logger.log {user_id, project_id}, "join project request"
- Metrics.inc "editor.join-project"
- EditorHttpController._buildJoinProjectView req, project_id, user_id, (error, project, privilegeLevel) ->
- return next(error) if error?
- # Hide access tokens if this is not the project owner
- TokenAccessHandler.protectTokens(project, privilegeLevel)
- res.json {
- project: project
- privilegeLevel: privilegeLevel
- }
- # Only show the 'renamed or deleted' message once
- if project?.deletedByExternalDataSource
- ProjectDeleter.unmarkAsDeletedByExternalSource project_id
-
- _buildJoinProjectView: (req, project_id, user_id, callback = (error, project, privilegeLevel) ->) ->
- logger.log {project_id, user_id}, "building the joinProject view"
- ProjectGetter.getProjectWithoutDocLines project_id, (error, project) ->
- return callback(error) if error?
- return callback(new Error("not found")) if !project?
- CollaboratorsHandler.getInvitedMembersWithPrivilegeLevels project_id, (error, members) ->
- return callback(error) if error?
- token = TokenAccessHandler.getRequestToken(req, project_id)
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel) ->
- return callback(error) if error?
- if !privilegeLevel? or privilegeLevel == PrivilegeLevels.NONE
- logger.log {project_id, user_id, privilegeLevel}, "not an acceptable privilege level, returning null"
- return callback null, null, false
- CollaboratorsInviteHandler.getAllInvites project_id, (error, invites) ->
- return callback(error) if error?
- logger.log {project_id, user_id, memberCount: members.length, inviteCount: invites.length, privilegeLevel}, "returning project model view"
- callback(null,
- ProjectEditorHandler.buildProjectModelView(project, members, invites),
- privilegeLevel
- )
-
- _nameIsAcceptableLength: (name)->
- return name? and name.length < 150 and name.length != 0
-
- addDoc: (req, res, next) ->
- project_id = req.params.Project_id
- name = req.body.name
- parent_folder_id = req.body.parent_folder_id
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log project_id:project_id, name:name, parent_folder_id:parent_folder_id, "getting request to add doc to project"
- if !EditorHttpController._nameIsAcceptableLength(name)
- return res.sendStatus 400
- EditorController.addDoc project_id, parent_folder_id, name, [], "editor", user_id, (error, doc) ->
- if error == "project_has_to_many_files"
- res.status(400).json(req.i18n.translate("project_has_to_many_files"))
- else if error?
- next(error)
- else
- res.json doc
-
- addFolder: (req, res, next) ->
- project_id = req.params.Project_id
- name = req.body.name
- parent_folder_id = req.body.parent_folder_id
- if !EditorHttpController._nameIsAcceptableLength(name)
- return res.sendStatus 400
- EditorController.addFolder project_id, parent_folder_id, name, "editor", (error, doc) ->
- if error == "project_has_to_many_files"
- res.status(400).json(req.i18n.translate("project_has_to_many_files"))
- else if error?.message == 'invalid element name'
- res.status(400).json(req.i18n.translate('invalid_file_name'))
- else if error?
- next(error)
- else
- res.json doc
-
- renameEntity: (req, res, next) ->
- project_id = req.params.Project_id
- entity_id = req.params.entity_id
- entity_type = req.params.entity_type
- name = req.body.name
- if !EditorHttpController._nameIsAcceptableLength(name)
- return res.sendStatus 400
- user_id = AuthenticationController.getLoggedInUserId(req)
- EditorController.renameEntity project_id, entity_id, entity_type, name, user_id, (error) ->
- return next(error) if error?
- res.sendStatus 204
-
- moveEntity: (req, res, next) ->
- project_id = req.params.Project_id
- entity_id = req.params.entity_id
- entity_type = req.params.entity_type
- folder_id = req.body.folder_id
- user_id = AuthenticationController.getLoggedInUserId(req)
- EditorController.moveEntity project_id, entity_id, folder_id, entity_type, user_id, (error) ->
- return next(error) if error?
- res.sendStatus 204
-
- deleteDoc: (req, res, next)->
- req.params.entity_type = "doc"
- EditorHttpController.deleteEntity(req, res, next)
-
- deleteFile: (req, res, next)->
- req.params.entity_type = "file"
- EditorHttpController.deleteEntity(req, res, next)
-
- deleteFolder: (req, res, next)->
- req.params.entity_type = "folder"
- EditorHttpController.deleteEntity(req, res, next)
-
- deleteEntity: (req, res, next) ->
- project_id = req.params.Project_id
- entity_id = req.params.entity_id
- entity_type = req.params.entity_type
- user_id = AuthenticationController.getLoggedInUserId(req)
- EditorController.deleteEntity project_id, entity_id, entity_type, "editor", user_id, (error) ->
- return next(error) if error?
- res.sendStatus 204
diff --git a/services/web/app/coffee/Features/Editor/EditorRealTimeController.coffee b/services/web/app/coffee/Features/Editor/EditorRealTimeController.coffee
deleted file mode 100644
index 9d0a5e5084..0000000000
--- a/services/web/app/coffee/Features/Editor/EditorRealTimeController.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-Settings = require 'settings-sharelatex'
-RedisWrapper = require("../../infrastructure/RedisWrapper")
-rclient = RedisWrapper.client("realtime")
-os = require "os"
-crypto = require "crypto"
-
-HOST = os.hostname()
-RND = crypto.randomBytes(4).toString('hex') # generate a random key for this process
-COUNT = 0
-
-module.exports = EditorRealTimeController =
- emitToRoom: (room_id, message, payload...) ->
- # create a unique message id using a counter
- message_id = "web:#{HOST}:#{RND}-#{COUNT++}"
- rclient.publish "editor-events", JSON.stringify
- room_id: room_id
- message: message
- payload: payload
- _id: message_id
-
- emitToAll: (message, payload...) ->
- @emitToRoom "all", message, payload...
-
diff --git a/services/web/app/coffee/Features/Editor/EditorRouter.coffee b/services/web/app/coffee/Features/Editor/EditorRouter.coffee
deleted file mode 100644
index bcc2bd6d9e..0000000000
--- a/services/web/app/coffee/Features/Editor/EditorRouter.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-EditorHttpController = require('./EditorHttpController')
-AuthenticationController = require "../Authentication/AuthenticationController"
-AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.post '/project/:Project_id/doc', AuthorizationMiddleware.ensureUserCanWriteProjectContent,
- RateLimiterMiddleware.rateLimit({
- endpointName: "add-doc-to-project"
- params: ["Project_id"]
- maxRequests: 30
- timeInterval: 60
- }), EditorHttpController.addDoc
- webRouter.post '/project/:Project_id/folder', AuthorizationMiddleware.ensureUserCanWriteProjectContent,
- RateLimiterMiddleware.rateLimit({
- endpointName: "add-folder-to-project"
- params: ["Project_id"]
- maxRequests: 60
- timeInterval: 60
- }), EditorHttpController.addFolder
-
- webRouter.post '/project/:Project_id/:entity_type/:entity_id/rename', AuthorizationMiddleware.ensureUserCanWriteProjectContent, EditorHttpController.renameEntity
- webRouter.post '/project/:Project_id/:entity_type/:entity_id/move', AuthorizationMiddleware.ensureUserCanWriteProjectContent, EditorHttpController.moveEntity
-
- webRouter.delete '/project/:Project_id/file/:entity_id', AuthorizationMiddleware.ensureUserCanWriteProjectContent, EditorHttpController.deleteFile
- webRouter.delete '/project/:Project_id/doc/:entity_id', AuthorizationMiddleware.ensureUserCanWriteProjectContent, EditorHttpController.deleteDoc
- webRouter.delete '/project/:Project_id/folder/:entity_id', AuthorizationMiddleware.ensureUserCanWriteProjectContent, EditorHttpController.deleteFolder
-
- # Called by the real-time API to load up the current project state.
- # This is a post request because it's more than just a getting of data. We take actions
- # whenever a user joins a project, like updating the deleted status.
- apiRouter.post '/project/:Project_id/join', AuthenticationController.httpAuth,
- RateLimiterMiddleware.rateLimit({
- endpointName: "join-project"
- params: ["Project_id"]
- maxRequests: 30
- timeInterval: 60
- }), EditorHttpController.joinProject
diff --git a/services/web/app/coffee/Features/Email/EmailBuilder.coffee b/services/web/app/coffee/Features/Email/EmailBuilder.coffee
deleted file mode 100644
index 1a136d7e8c..0000000000
--- a/services/web/app/coffee/Features/Email/EmailBuilder.coffee
+++ /dev/null
@@ -1,230 +0,0 @@
-_ = require('underscore')
-settings = require("settings-sharelatex")
-marked = require('marked')
-StringHelper = require "../Helpers/StringHelper"
-
-PersonalEmailLayout = require("./Layouts/PersonalEmailLayout")
-NotificationEmailLayout = require("./Layouts/NotificationEmailLayout")
-BaseWithHeaderEmailLayout = require("./Layouts/" + settings.brandPrefix + "BaseWithHeaderEmailLayout")
-SpamSafe = require("./SpamSafe")
-
-SingleCTAEmailBody = require("./Bodies/" + settings.brandPrefix + "SingleCTAEmailBody")
-
-CTAEmailTemplate = (content) ->
- content.greeting ?= () -> 'Hi,'
- content.secondaryMessage ?= () -> ""
- return {
- subject: (opts) -> content.subject(opts),
- layout: BaseWithHeaderEmailLayout,
- plainTextTemplate: (opts) -> """
-#{content.greeting(opts)}
-
-#{content.message(opts).trim()}
-
-#{content.ctaText(opts)}: #{content.ctaURL(opts)}
-
-#{content.secondaryMessage?(opts).trim() or ""}
-
-Regards,
-The #{settings.appName} Team - #{settings.siteUrl}
- """
- compiledTemplate: (opts) ->
- SingleCTAEmailBody({
- title: content.title?(opts)
- greeting: content.greeting(opts)
- message: marked(content.message(opts).trim())
- secondaryMessage: marked(content.secondaryMessage(opts).trim())
- ctaText: content.ctaText(opts)
- ctaURL: content.ctaURL(opts)
- gmailGoToAction: content.gmailGoToAction?(opts)
- StringHelper: StringHelper
- })
- }
-
-templates = {}
-
-templates.accountMergeToOverleafAddress = CTAEmailTemplate({
- subject: () -> "Confirm Account Merge - #{settings.appName}"
- title: () -> "Confirm Account Merge"
- message: () ->
- """
- To merge your ShareLaTeX and Overleaf accounts, click the button below.
- If you think you have received this message in error,
- please contact us at https://www.overleaf.com/contact
- """
- ctaText: () -> "Confirm Account Merge"
- ctaURL: (opts) -> opts.tokenLinkUrl
-})
-
-templates.accountMergeToSharelatexAddress = templates.accountMergeToOverleafAddress
-
-templates.registered = CTAEmailTemplate({
- subject: () -> "Activate your #{settings.appName} Account"
- message: (opts) -> """
-Congratulations, you've just had an account created for you on #{settings.appName} with the email address '#{_.escape(opts.to)}'.
-
-Click here to set your password and log in:
-"""
- secondaryMessage: () -> "If you have any questions or problems, please contact #{settings.adminEmail}"
- ctaText: () -> "Set password"
- ctaURL: (opts) -> opts.setNewPasswordUrl
-})
-
-templates.canceledSubscription = CTAEmailTemplate({
- subject: () -> "#{settings.appName} thoughts"
- message: () -> """
-I'm sorry to see you cancelled your #{settings.appName} premium account. Would you mind giving us some feedback on what the site is lacking at the moment via this quick survey?
-"""
- secondaryMessage: () -> "Thank you in advance!"
- ctaText: () -> "Leave Feedback"
- ctaURL: (opts) -> "https://docs.google.com/forms/d/e/1FAIpQLScqU6Je1r4Afz6ul6oY0RAfN7RabdWv_oL1u7Rj1YBmXS4fiQ/viewform?usp=sf_link"
-})
-
-templates.reactivatedSubscription = CTAEmailTemplate({
- subject: () -> "Subscription Reactivated - #{settings.appName}"
- message: (opts) -> """
-Your subscription was reactivated successfully.
-"""
- ctaText: () -> "View Subscription Dashboard"
- ctaURL: (opts) -> "#{settings.siteUrl}/user/subscription"
-})
-
-templates.passwordResetRequested = CTAEmailTemplate({
- subject: () -> "Password Reset - #{settings.appName}"
- title: () -> "Password Reset"
- message: () -> "We got a request to reset your #{settings.appName} password."
- secondaryMessage: () -> """
-If you ignore this message, your password won't be changed.
-
-If you didn't request a password reset, let us know.
-"""
- ctaText: () -> "Reset password"
- ctaURL: (opts) -> opts.setNewPasswordUrl
-})
-
-templates.confirmEmail = CTAEmailTemplate({
- subject: () -> "Confirm Email - #{settings.appName}"
- title: () -> "Confirm Email"
- message: () -> "Please confirm your email on #{settings.appName}."
- ctaText: () -> "Confirm Email"
- ctaURL: (opts) -> opts.confirmEmailUrl
-})
-
-templates.projectInvite = CTAEmailTemplate({
- subject: (opts) -> "#{ _.escape(SpamSafe.safeProjectName(opts.project.name, "New Project")) } - shared by #{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) }"
- title: (opts) -> "#{ _.escape(SpamSafe.safeProjectName(opts.project.name, "New Project")) } - shared by #{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) }"
- message: (opts) -> "#{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) } wants to share #{ _.escape(SpamSafe.safeProjectName(opts.project.name, "a new project")) } with you."
- ctaText: () -> "View project"
- ctaURL: (opts) -> opts.inviteUrl
- gmailGoToAction: (opts) ->
- target: opts.inviteUrl
- name: "View project"
- description: "Join #{ _.escape(SpamSafe.safeProjectName(opts.project.name, "project")) } at #{ settings.appName }"
-})
-
-templates.verifyEmailToJoinTeam = CTAEmailTemplate({
- subject: (opts) -> "#{ _.escape(SpamSafe.safeUserName(opts.inviterName, "A collaborator")) } has invited you to join a team on #{ settings.appName }"
- title: (opts) -> "#{ _.escape(SpamSafe.safeUserName(opts.inviterName, "A collaborator")) } has invited you to join a team on #{ settings.appName }"
- message: (opts) -> "Please click the button below to join the team and enjoy the benefits of an upgraded #{ settings.appName } account."
- ctaText: (opts) -> "Join now"
- ctaURL: (opts) -> opts.acceptInviteUrl
-})
-
-templates.dropboxUnlinkedDuplicate = CTAEmailTemplate({
- subject: () -> "Your Dropbox Account has been Unlinked - #{settings.appName}"
- message: (opts) -> """
-Our automated systems have detected that your Dropbox account was linked to more than one Overleaf accounts. This should not have been allowed and might be causing issues with the Dropbox sync feature.
-
-We have now unlinked all your Dropbox and Overleaf Accounts. To ensure your project will keep syncing you can link your Dropbox account to the Overleaf account of your choice now.
-"""
- ctaText: () -> "Link Dropbox Account"
- ctaURL: (opts) -> "#{settings.siteUrl}/user/settings"
-})
-
-templates.testEmail = CTAEmailTemplate({
- subject: () -> "A Test Email from #{settings.appName}"
- title: () -> "A Test Email from #{settings.appName}"
- greeting: () -> "Hi,"
- message: () -> "This is a test Email from #{settings.appName}"
- ctaText: () -> "Open #{settings.appName}"
- ctaURL: () -> settings.siteUrl
-})
-
-templates.projectsTransferredFromSharelatex = CTAEmailTemplate({
- subject: () -> "ShareLaTeX projects transferred to your Overleaf account"
- title: () -> "ShareLaTeX projects transferred to your Overleaf account"
- message: (opts) -> """
-We are writing with important information about your Overleaf and ShareLaTeX accounts.
-
-As part of our ongoing work to [integrate Overleaf and ShareLaTeX](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf),
-we found a ShareLaTeX account with the email address #{opts.to} that matches your Overleaf account.
-
-We have now transferred the projects from this ShareLaTeX account into your Overleaf account, so you may notice some new
-projects on your Overleaf projects page.
-
-When you next log in, you may be prompted to reconfirm your email address in order to regain access to your account.
-If you have any questions, please contact our support team by reply.
-"""
- ctaText: () -> "Log in to #{ settings.appName }"
- ctaURL: () -> settings.siteUrl + "/login"
-})
-
-templates.emailAddressPoachedEmail = CTAEmailTemplate({
- subject: () -> "One of your email addresses has been moved to another #{ settings.appName } account"
- title: () -> "One of your email addresses has been moved to another #{ settings.appName } account"
- message: (opts) ->
- message = """
-We are writing with important information about your Overleaf account.
-
-You added the email address #{opts.poached} to your #{opts.to} Overleaf account as a secondary (or affiliation)
-email address, but we have had to remove it.
-
-This is because your #{opts.poached} email address was also in use as the primary email address for an older Overleaf
-account from before our [integration with ShareLaTeX to create Overleaf v2](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf).
-
-### What do I need to do?
-
-You now have two Overleaf accounts, one under #{opts.poached} and one under #{opts.to}.
-
-You may wish to log in to Overleaf as #{opts.poached} to check whether you have projects there that you would like to
-keep. If you are not sure of the password, you can send yourself a password reset email to #{opts.poached}, via
-https://www.overleaf.com/user/password/reset
-
-Once you have downloaded your projects, you may wish to delete your
-#{opts.poached} Overleaf account, which you can do from your account settings. You will then be able to add
-#{opts.poached} as a secondary email address on your #{opts.to} account again.
-
-
-"""
- if opts.proFeatures
- message += """
-Because your #{opts.poached} email address was an institutional affiliation through which you had Pro features. Your Pro
-features have been transferred to your #{opts.poached} account. If you would like to transfer them back to your
-#{opts.to} account, you will need to delete the #{opts.poached} account and re-add it as a secondary email address,
-as described above.
-
-
-"""
-
- message += """
-If you have any questions, you can contact our support team by reply.
-"""
- return message
- ctaText: () -> "Log in to #{ settings.appName }"
- ctaURL: () -> settings.siteUrl + "/login"
-})
-
-module.exports =
- templates: templates
- CTAEmailTemplate: CTAEmailTemplate
- buildEmail: (templateName, opts)->
- template = templates[templateName]
- opts.siteUrl = settings.siteUrl
- opts.body = template.compiledTemplate(opts)
- if settings.email?.templates?.customFooter?
- opts.body += settings.email?.templates?.customFooter
- return {
- subject : template.subject(opts)
- html: template.layout(opts)
- text: template?.plainTextTemplate?(opts)
- }
diff --git a/services/web/app/coffee/Features/Email/EmailHandler.coffee b/services/web/app/coffee/Features/Email/EmailHandler.coffee
deleted file mode 100644
index 048796b09a..0000000000
--- a/services/web/app/coffee/Features/Email/EmailHandler.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-settings = require("settings-sharelatex")
-EmailBuilder = require "./EmailBuilder"
-EmailSender = require "./EmailSender"
-
-if !settings.email?
- settings.email =
- lifecycleEnabled:false
-
-
-module.exports =
-
- sendEmail : (emailType, opts, callback = (err)->)->
- email = EmailBuilder.buildEmail emailType, opts
- if email.type == "lifecycle" and !settings.email.lifecycle
- return callback()
- opts.html = email.html
- opts.text = email.text
- opts.subject = email.subject
- EmailSender.sendEmail opts, (err)->
- callback(err)
diff --git a/services/web/app/coffee/Features/Email/EmailSender.coffee b/services/web/app/coffee/Features/Email/EmailSender.coffee
deleted file mode 100644
index d5ae949f74..0000000000
--- a/services/web/app/coffee/Features/Email/EmailSender.coffee
+++ /dev/null
@@ -1,79 +0,0 @@
-logger = require('logger-sharelatex')
-metrics = require('metrics-sharelatex')
-Settings = require('settings-sharelatex')
-nodemailer = require("nodemailer")
-sesTransport = require('nodemailer-ses-transport')
-sgTransport = require('nodemailer-sendgrid-transport')
-mandrillTransport = require('nodemailer-mandrill-transport')
-rateLimiter = require('../../infrastructure/RateLimiter')
-_ = require("underscore")
-
-if Settings.email? and Settings.email.fromAddress?
- defaultFromAddress = Settings.email.fromAddress
-else
- defaultFromAddress = ""
-
-# provide dummy mailer unless we have a better one configured.
-client =
- sendMail: (options, callback = (err,status) ->) ->
- logger.log options:options, "Would send email if enabled."
- callback()
-if Settings?.email?.parameters?.AWSAccessKeyID? or Settings?.email?.driver == 'ses'
- logger.log "using aws ses for email"
- nm_client = nodemailer.createTransport(sesTransport(Settings.email.parameters))
-else if Settings?.email?.parameters?.sendgridApiKey?
- logger.log "using sendgrid for email"
- nm_client = nodemailer.createTransport(sgTransport({auth:{api_key:Settings?.email?.parameters?.sendgridApiKey}}))
-else if Settings?.email?.parameters?.MandrillApiKey?
- logger.log "using mandril for email"
- nm_client = nodemailer.createTransport(mandrillTransport({auth:{apiKey:Settings?.email?.parameters?.MandrillApiKey}}))
-else if Settings?.email?.parameters?
- logger.log "using smtp for email"
- smtp = _.pick(Settings?.email?.parameters, "host", "port", "secure", "auth", "ignoreTLS")
- nm_client = nodemailer.createTransport(smtp)
-else
- logger.warn "Email transport and/or parameters not defined. No emails will be sent."
- nm_client = client
-
-if nm_client?
- client = nm_client
-else
- logger.warn "Failed to create email transport. Please check your settings. No email will be sent."
-
-checkCanSendEmail = (options, callback)->
- if !options.sendingUser_id? #email not sent from user, not rate limited
- return callback(null, true)
- opts =
- endpointName: "send_email"
- timeInterval: 60 * 60 * 3
- subjectName: options.sendingUser_id
- throttle: 100
- rateLimiter.addCount opts, callback
-
-module.exports =
- sendEmail : (options, callback = (error) ->)->
- logger.log receiver:options.to, subject:options.subject, "sending email"
- checkCanSendEmail options, (err, canContinue)->
- if err?
- return callback(err)
- if !canContinue
- logger.log sendingUser_id:options.sendingUser_id, to:options.to, subject:options.subject, canContinue:canContinue, "rate limit hit for sending email, not sending"
- return callback("rate limit hit sending email")
- metrics.inc "email"
- options =
- to: options.to
- from: defaultFromAddress
- subject: options.subject
- html: options.html
- text: options.text
- replyTo: options.replyTo || Settings.email.replyToAddress
- socketTimeout: 30 * 1000
- if Settings.email.textEncoding?
- opts.textEncoding = textEncoding
- client.sendMail options, (err, res)->
- if err?
- logger.err err:err, "error sending message"
- err = new Error('Cannot send email')
- else
- logger.log "Message sent to #{options.to}"
- callback(err)
diff --git a/services/web/app/coffee/Features/Email/SpamSafe.coffee b/services/web/app/coffee/Features/Email/SpamSafe.coffee
deleted file mode 100644
index 26ba49bc15..0000000000
--- a/services/web/app/coffee/Features/Email/SpamSafe.coffee
+++ /dev/null
@@ -1,38 +0,0 @@
-XRegExp = require('xregexp')
-
-# A note about SAFE_REGEX:
-# We have to escape the escape characters because XRegExp compiles it first.
-# So it's equivalent to `^[\p{L}\p{N}\s\-_!&\(\)]+$]
-# \p{L} = any letter in any language
-# \p{N} = any kind of numeric character
-# https://www.regular-expressions.info/unicode.html#prop is a good resource for
-# more obscure regex features. standard RegExp does not support these
-
-SAFE_REGEX = XRegExp("^[\\p{L}\\p{N}\\s\\-_!'&\\(\\)]+$")
-EMAIL_REGEX = XRegExp("^[\\p{L}\\p{N}.+_-]+@[\\w.-]+$")
-
-SpamSafe =
- isSafeUserName: (name) ->
- SAFE_REGEX.test(name) && name.length <= 30
-
- isSafeProjectName: (name) ->
- if XRegExp("\\p{Han}").test(name)
- SAFE_REGEX.test(name) && name.length <= 30
- SAFE_REGEX.test(name) && name.length <= 100
-
- isSafeEmail: (email) ->
- EMAIL_REGEX.test(email) && email.length <= 40
-
- safeUserName: (name, alternative, project = false) ->
- return name if SpamSafe.isSafeUserName name
- alternative
-
- safeProjectName: (name, alternative) ->
- return name if SpamSafe.isSafeProjectName name
- alternative
-
- safeEmail: (email, alternative) ->
- return email if SpamSafe.isSafeEmail email
- alternative
-
-module.exports = SpamSafe
diff --git a/services/web/app/coffee/Features/Errors/ErrorController.coffee b/services/web/app/coffee/Features/Errors/ErrorController.coffee
deleted file mode 100644
index fa252a24b2..0000000000
--- a/services/web/app/coffee/Features/Errors/ErrorController.coffee
+++ /dev/null
@@ -1,61 +0,0 @@
-Errors = require "./Errors"
-logger = require "logger-sharelatex"
-AuthenticationController = require '../Authentication/AuthenticationController'
-
-module.exports = ErrorController =
- notFound: (req, res)->
- res.status(404)
- res.render 'general/404',
- title: "page_not_found"
-
- forbidden: (req, res) ->
- res.status(403)
- res.render 'user/restricted'
-
- serverError: (req, res)->
- res.status(500)
- res.render 'general/500',
- title: "Server Error"
-
- accountMergeError: (req, res)->
- res.status(500)
- res.render 'general/account-merge-error',
- title: "Account Access Error"
-
- handleError: (error, req, res, next) ->
- user = AuthenticationController.getSessionUser(req)
- if error?.code is 'EBADCSRFTOKEN'
- logger.warn err: error,url:req.url, method:req.method, user:user, "invalid csrf"
- res.sendStatus(403)
- return
- if error instanceof Errors.NotFoundError
- logger.warn {err: error, url: req.url}, "not found error"
- ErrorController.notFound req, res
- else if error instanceof Errors.ForbiddenError
- logger.error err: error, "forbidden error"
- ErrorController.forbidden req, res
- else if error instanceof Errors.TooManyRequestsError
- logger.warn {err: error, url: req.url}, "too many requests error"
- res.sendStatus(429)
- else if error instanceof Errors.InvalidError
- logger.warn {err: error, url: req.url}, "invalid error"
- res.status(400)
- res.send(error.message)
- else if error instanceof Errors.InvalidNameError
- logger.warn {err: error, url: req.url}, "invalid name error"
- res.status(400)
- res.send(error.message)
- else if error instanceof Errors.AccountMergeError
- logger.error err: error, "account merge error"
- ErrorController.accountMergeError req, res
- else
- logger.error err: error, url:req.url, method:req.method, user:user, "error passed to top level next middleware"
- ErrorController.serverError req, res
-
- handleApiError: (error, req, res, next) ->
- if error instanceof Errors.NotFoundError
- logger.warn {err: error, url: req.url}, "not found error"
- res.sendStatus(404)
- else
- logger.error err: error, url:req.url, method:req.method, "error passed to top level next middleware"
- res.sendStatus(500)
diff --git a/services/web/app/coffee/Features/Errors/Errors.coffee b/services/web/app/coffee/Features/Errors/Errors.coffee
deleted file mode 100644
index fb1d305f7d..0000000000
--- a/services/web/app/coffee/Features/Errors/Errors.coffee
+++ /dev/null
@@ -1,147 +0,0 @@
-NotFoundError = (message) ->
- error = new Error(message)
- error.name = "NotFoundError"
- error.__proto__ = NotFoundError.prototype
- return error
-NotFoundError.prototype.__proto__ = Error.prototype
-
-ForbiddenError = (message) ->
- error = new Error(message)
- error.name = "ForbiddenError"
- error.__proto__ = ForbiddenError.prototype
- return error
-ForbiddenError.prototype.__proto__ = Error.prototype
-
-ServiceNotConfiguredError = (message) ->
- error = new Error(message)
- error.name = "ServiceNotConfiguredError"
- error.__proto__ = ServiceNotConfiguredError.prototype
- return error
-ServiceNotConfiguredError.prototype.__proto__ = Error.prototype
-
-TooManyRequestsError = (message) ->
- error = new Error(message)
- error.name = "TooManyRequestsError"
- error.__proto__ = TooManyRequestsError.prototype
- return error
-TooManyRequestsError.prototype.__proto__ = Error.prototype
-
-InvalidNameError = (message) ->
- error = new Error(message)
- error.name = "InvalidNameError"
- error.__proto__ = InvalidNameError.prototype
- return error
-InvalidNameError.prototype.__proto__ = Error.prototype
-
-UnsupportedFileTypeError = (message) ->
- error = new Error(message)
- error.name = "UnsupportedFileTypeError"
- error.__proto__ = UnsupportedFileTypeError.prototype
- return error
-UnsupportedFileTypeError.prototype.__proto__ = Error.prototype
-
-UnsupportedExportRecordsError = (message) ->
- error = new Error(message)
- error.name = "UnsupportedExportRecordsError"
- error.__proto__ = UnsupportedExportRecordsError.prototype
- return error
-UnsupportedExportRecordsError.prototype.__proto__ = Error.prototype
-
-V1HistoryNotSyncedError = (message) ->
- error = new Error(message)
- error.name = "V1HistoryNotSyncedError"
- error.__proto__ = V1HistoryNotSyncedError.prototype
- return error
-V1HistoryNotSyncedError.prototype.__proto__ = Error.prototype
-
-ProjectHistoryDisabledError = (message) ->
- error = new Error(message)
- error.name = "ProjectHistoryDisabledError"
- error.__proto__ = ProjectHistoryDisabledError.prototype
- return error
-ProjectHistoryDisabledError.prototype.__proto__ = Error.prototype
-
-V1ConnectionError = (message) ->
- error = new Error(message)
- error.name = "V1ConnectionError"
- error.__proto__ = V1ConnectionError.prototype
- return error
-V1ConnectionError.prototype.__proto__ = Error.prototype
-
-UnconfirmedEmailError = (message) ->
- error = new Error(message)
- error.name = "UnconfirmedEmailError"
- error.__proto__ = UnconfirmedEmailError.prototype
- return error
-UnconfirmedEmailError.prototype.__proto__ = Error.prototype
-
-EmailExistsError = (message) ->
- error = new Error(message)
- error.name = "EmailExistsError"
- error.__proto__ = EmailExistsError.prototype
- return error
-EmailExistsError.prototype.__proto__ = Error.prototype
-
-InvalidError = (message) ->
- error = new Error(message)
- error.name = "InvalidError"
- error.__proto__ = InvalidError.prototype
- return error
-InvalidError.prototype.__proto__ = Error.prototype
-
-AccountMergeError = (message) ->
- error = new Error(message)
- error.name = "AccountMergeError"
- error.__proto__ = AccountMergeError.prototype
- return error
-AccountMergeError.prototype.__proto__ = Error.prototype
-
-NotInV2Error = (message) ->
- error = new Error(message)
- error.name = "NotInV2Error"
- error.__proto__ = NotInV2Error.prototype
- return error
-NotInV2Error.prototype.__proto__ = Error.prototype
-
-SLInV2Error = (message) ->
- error = new Error(message)
- error.name = "SLInV2Error"
- error.__proto__ = SLInV2Error.prototype
- return error
-SLInV2Error.prototype.__proto__ = Error.prototype
-
-ThirdPartyUserNotFoundError = (message) ->
- message = "user not found for provider and external id" unless message?
- error = new Error(message)
- error.name = "ThirdPartyUserNotFoundError"
- error.__proto__ = SLInV2Error.prototype
- return error
-ThirdPartyUserNotFoundError.prototype.__proto__ = Error.prototype
-
-SubscriptionAdminDeletionError = (message) ->
- message = "subscription admins cannot be deleted" unless message?
- error = new Error(message)
- error.name = "SubscriptionAdminDeletionError"
- error.__proto__ = SubscriptionAdminDeletionError.prototype
- return error
-SubscriptionAdminDeletionError.prototype.__proto__ = Error.prototype
-
-module.exports = Errors =
- NotFoundError: NotFoundError
- ForbiddenError: ForbiddenError
- ServiceNotConfiguredError: ServiceNotConfiguredError
- TooManyRequestsError: TooManyRequestsError
- InvalidNameError: InvalidNameError
- UnsupportedFileTypeError: UnsupportedFileTypeError
- UnsupportedExportRecordsError: UnsupportedExportRecordsError
- V1HistoryNotSyncedError: V1HistoryNotSyncedError
- ProjectHistoryDisabledError: ProjectHistoryDisabledError
- V1ConnectionError: V1ConnectionError
- UnconfirmedEmailError: UnconfirmedEmailError
- EmailExistsError: EmailExistsError
- InvalidError: InvalidError
- AccountMergeError: AccountMergeError
- NotInV2Error: NotInV2Error
- SLInV2Error: SLInV2Error
- ThirdPartyUserNotFoundError: ThirdPartyUserNotFoundError
- SubscriptionAdminDeletionError: SubscriptionAdminDeletionError
diff --git a/services/web/app/coffee/Features/Exports/ExportsController.coffee b/services/web/app/coffee/Features/Exports/ExportsController.coffee
deleted file mode 100644
index 5ef5303e6a..0000000000
--- a/services/web/app/coffee/Features/Exports/ExportsController.coffee
+++ /dev/null
@@ -1,72 +0,0 @@
-ExportsHandler = require("./ExportsHandler")
-AuthenticationController = require("../Authentication/AuthenticationController")
-logger = require("logger-sharelatex")
-
-module.exports =
-
- exportProject: (req, res, next) ->
- {project_id, brand_variation_id} = req.params
- user_id = AuthenticationController.getLoggedInUserId(req)
- export_params = {
- project_id: project_id,
- brand_variation_id: brand_variation_id,
- user_id: user_id
- }
-
- if req.body
- export_params.first_name = req.body.firstName.trim() if req.body.firstName
- export_params.last_name = req.body.lastName.trim() if req.body.lastName
- # additional parameters for gallery exports
- export_params.title = req.body.title.trim() if req.body.title
- export_params.description = req.body.description.trim() if req.body.description
- export_params.author = req.body.author.trim() if req.body.author
- export_params.license = req.body.license.trim() if req.body.license
- export_params.show_source = req.body.showSource if req.body.showSource?
-
- ExportsHandler.exportProject export_params, (err, export_data) ->
- if err?
- if err.forwardResponse?
- logger.log {responseError: err.forwardResponse}, "forwarding response"
- statusCode = err.forwardResponse.status || 500
- return res.status(statusCode).json err.forwardResponse
- else
- return next(err)
- logger.log
- user_id:user_id
- project_id: project_id
- brand_variation_id:brand_variation_id
- export_v1_id:export_data.v1_id
- "exported project"
- res.json export_v1_id: export_data.v1_id
-
- exportStatus: (req, res) ->
- {export_id} = req.params
- ExportsHandler.fetchExport export_id, (err, export_json) ->
- if err?
- json = {
- status_summary: 'failed',
- status_detail: err.toString,
- }
- res.json export_json: json
- return err
- parsed_export = JSON.parse(export_json)
- json = {
- status_summary: parsed_export.status_summary,
- status_detail: parsed_export.status_detail,
- partner_submission_id: parsed_export.partner_submission_id,
- v2_user_email: parsed_export.v2_user_email,
- v2_user_first_name: parsed_export.v2_user_first_name,
- v2_user_last_name: parsed_export.v2_user_last_name,
- title: parsed_export.title,
- token: parsed_export.token
- }
- res.json export_json: json
-
- exportDownload: (req, res, next) ->
- {type, export_id} = req.params
-
- AuthenticationController.getLoggedInUserId(req)
- ExportsHandler.fetchDownload export_id, type, (err, export_file_url) ->
- return next(err) if err?
-
- res.redirect export_file_url
diff --git a/services/web/app/coffee/Features/Exports/ExportsHandler.coffee b/services/web/app/coffee/Features/Exports/ExportsHandler.coffee
deleted file mode 100644
index 69aaf122a1..0000000000
--- a/services/web/app/coffee/Features/Exports/ExportsHandler.coffee
+++ /dev/null
@@ -1,145 +0,0 @@
-ProjectGetter = require('../Project/ProjectGetter')
-ProjectHistoryHandler = require('../Project/ProjectHistoryHandler')
-ProjectLocator = require('../Project/ProjectLocator')
-ProjectRootDocManager = require('../Project/ProjectRootDocManager')
-UserGetter = require('../User/UserGetter')
-logger = require('logger-sharelatex')
-settings = require 'settings-sharelatex'
-async = require 'async'
-request = require 'request'
-request = request.defaults()
-settings = require 'settings-sharelatex'
-
-module.exports = ExportsHandler = self =
-
- exportProject: (export_params, callback=(error, export_data) ->) ->
- self._buildExport export_params, (err, export_data) ->
- return callback(err) if err?
- self._requestExport export_data, (err, export_v1_id) ->
- return callback(err) if err?
- export_data.v1_id = export_v1_id
- # TODO: possibly store the export data in Mongo
- callback null, export_data
-
- _buildExport: (export_params, callback=(err, export_data) ->) ->
- {project_id, user_id, brand_variation_id, title, description, author,
- license, show_source} = export_params
- jobs =
- project: (cb) ->
- ProjectGetter.getProject project_id, cb
- # TODO: when we update async, signature will change from (cb, results) to (results, cb)
- rootDoc: [ 'project', (cb, results) ->
- ProjectRootDocManager.ensureRootDocumentIsValid project_id, (error) ->
- return callback(error) if error?
- ProjectLocator.findRootDoc {project: results.project, project_id: project_id}, cb
- ]
- user: (cb) ->
- UserGetter.getUser user_id, {first_name: 1, last_name: 1, email: 1, overleaf: 1}, cb
- historyVersion: (cb) ->
- ProjectHistoryHandler.ensureHistoryExistsForProject project_id, (error) ->
- return callback(error) if error?
- self._requestVersion project_id, cb
-
- async.auto jobs, (err, results) ->
- if err?
- logger.err err:err, project_id:project_id, user_id:user_id, brand_variation_id:brand_variation_id, "error building project export"
- return callback(err)
-
- {project, rootDoc, user, historyVersion} = results
- if !rootDoc[1]?
- err = new Error("cannot export project without root doc")
- logger.err err:err, project_id: project_id
- return callback(err)
-
- if export_params.first_name && export_params.last_name
- user.first_name = export_params.first_name
- user.last_name = export_params.last_name
-
- export_data =
- project:
- id: project_id
- rootDocPath: rootDoc[1]?.fileSystem
- historyId: project.overleaf?.history?.id
- historyVersion: historyVersion
- v1ProjectId: project.overleaf?.id
- metadata:
- compiler: project.compiler
- imageName: project.imageName
- title: title
- description: description
- author: author
- license: license
- showSource: show_source
- user:
- id: user_id
- firstName: user.first_name
- lastName: user.last_name
- email: user.email
- orcidId: null # until v2 gets ORCID
- v1UserId: user.overleaf?.id
- destination:
- brandVariationId: brand_variation_id
- options:
- callbackUrl: null # for now, until we want v1 to call us back
- callback null, export_data
-
- _requestExport: (export_data, callback=(err, export_v1_id) ->) ->
- request.post {
- url: "#{settings.apis.v1.url}/api/v1/sharelatex/exports"
- auth: {user: settings.apis.v1.user, pass: settings.apis.v1.pass }
- json: export_data
- }, (err, res, body) ->
- if err?
- logger.err err:err, export:export_data, "error making request to v1 export"
- callback err
- else if 200 <= res.statusCode < 300
- callback null, body.exportId
- else
- logger.err export:export_data, "v1 export returned failure; forwarding: #{body}"
- # pass the v1 error along for the publish modal to handle
- callback {forwardResponse: body}
-
- _requestVersion: (project_id, callback=(err, export_v1_id) ->) ->
- request.get {
- url: "#{settings.apis.project_history.url}/project/#{project_id}/version"
- json: true
- }, (err, res, body) ->
- if err?
- logger.err err:err, project_id:project_id, "error making request to project history"
- callback err
- else if res.statusCode >= 200 and res.statusCode < 300
- callback null, body.version
- else
- err = new Error("project history version returned a failure status code: #{res.statusCode}")
- logger.err err:err, project_id:project_id, "project history version returned failure status code: #{res.statusCode}"
- callback err
-
- fetchExport: (export_id, callback=(err, export_json) ->) ->
- request.get {
- url: "#{settings.apis.v1.url}/api/v1/sharelatex/exports/#{export_id}"
- auth: {user: settings.apis.v1.user, pass: settings.apis.v1.pass }
- }, (err, res, body) ->
- if err?
- logger.err err:err, export:export_id, "error making request to v1 export"
- callback err
- else if 200 <= res.statusCode < 300
- callback null, body
- else
- err = new Error("v1 export returned a failure status code: #{res.statusCode}")
- logger.err err:err, export:export_id, "v1 export returned failure status code: #{res.statusCode}"
- callback err
-
- fetchDownload: (export_id, type, callback=(err, file_url) ->) ->
- request.get {
- url: "#{settings.apis.v1.url}/api/v1/sharelatex/exports/#{export_id}/#{type}_url"
- auth: {user: settings.apis.v1.user, pass: settings.apis.v1.pass }
- }, (err, res, body) ->
- if err?
- logger.err err:err, export:export_id, "error making request to v1 export"
- callback err
- else if 200 <= res.statusCode < 300
- callback null, body
- else
- err = new Error("v1 export returned a failure status code: #{res.statusCode}")
- logger.err err:err, export:export_id, "v1 export zip fetch returned failure status code: #{res.statusCode}"
- callback err
diff --git a/services/web/app/coffee/Features/FileStore/FileHashManager.coffee b/services/web/app/coffee/Features/FileStore/FileHashManager.coffee
deleted file mode 100644
index 8de0291512..0000000000
--- a/services/web/app/coffee/Features/FileStore/FileHashManager.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-crypto = require "crypto"
-logger = require("logger-sharelatex")
-fs = require("fs")
-_ = require("underscore")
-
-module.exports = FileHashManager =
-
- computeHash: (filePath, callback = (error, hashValue) ->) ->
- callback = _.once(callback) # avoid double callbacks
-
- # taken from v1/history/storage/lib/blob_hash.js
- getGitBlobHeader = (byteLength) ->
- return 'blob ' + byteLength + '\x00'
-
- getByteLengthOfFile = (cb) ->
- fs.stat filePath, (err, stats) ->
- return cb(err) if err?
- cb(null, stats.size)
-
- getByteLengthOfFile (err, byteLength) ->
- return callback(err) if err?
-
- input = fs.createReadStream(filePath)
- input.on 'error', (err) ->
- logger.err {filePath: filePath, err:err}, "error opening file in computeHash"
- return callback(err)
-
- hash = crypto.createHash("sha1")
- hash.setEncoding('hex')
- hash.update(getGitBlobHeader(byteLength))
- hash.on 'readable', () ->
- result = hash.read()
- if result?
- callback(null, result.toString('hex'))
- input.pipe(hash)
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/FileStore/FileStoreController.coffee b/services/web/app/coffee/Features/FileStore/FileStoreController.coffee
deleted file mode 100644
index eceb5aee4f..0000000000
--- a/services/web/app/coffee/Features/FileStore/FileStoreController.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-logger = require('logger-sharelatex')
-FileStoreHandler = require("./FileStoreHandler")
-ProjectLocator = require("../Project/ProjectLocator")
-_ = require('underscore')
-
-is_mobile_safari = (user_agent) ->
- user_agent and (user_agent.indexOf('iPhone') >= 0 or
- user_agent.indexOf('iPad') >= 0)
-
-is_html = (file) ->
- ends_with = (ext) ->
- file.name? and
- file.name.length > ext.length and
- (file.name.lastIndexOf(ext) == file.name.length - ext.length)
-
- ends_with('.html') or ends_with('.htm') or ends_with('.xhtml')
-
-module.exports =
-
- getFile : (req, res)->
- project_id = req.params.Project_id
- file_id = req.params.File_id
- queryString = req.query
- user_agent = req.get('User-Agent')
- logger.log project_id: project_id, file_id: file_id, queryString:queryString, "file download"
- ProjectLocator.findElement {project_id: project_id, element_id: file_id, type: "file"}, (err, file)->
- if err?
- logger.err err:err, project_id: project_id, file_id: file_id, queryString:queryString, "error finding element for downloading file"
- return res.sendStatus 500
- FileStoreHandler.getFileStream project_id, file_id, queryString, (err, stream)->
- if err?
- logger.err err:err, project_id: project_id, file_id: file_id, queryString:queryString, "error getting file stream for downloading file"
- return res.sendStatus 500
- # mobile safari will try to render html files, prevent this
- if (is_mobile_safari(user_agent) and is_html(file))
- logger.log filename: file.name, user_agent: user_agent, "sending html file to mobile-safari as plain text"
- res.setHeader('Content-Type', 'text/plain')
- res.setContentDisposition('attachment', {filename: file.name})
- stream.pipe res
diff --git a/services/web/app/coffee/Features/FileStore/FileStoreHandler.coffee b/services/web/app/coffee/Features/FileStore/FileStoreHandler.coffee
deleted file mode 100644
index 4e080902a2..0000000000
--- a/services/web/app/coffee/Features/FileStore/FileStoreHandler.coffee
+++ /dev/null
@@ -1,124 +0,0 @@
-logger = require("logger-sharelatex")
-fs = require("fs")
-request = require("request")
-settings = require("settings-sharelatex")
-Async = require('async')
-FileHashManager = require("./FileHashManager")
-File = require('../../models/File').File
-
-oneMinInMs = 60 * 1000
-fiveMinsInMs = oneMinInMs * 5
-
-module.exports = FileStoreHandler =
-
- RETRY_ATTEMPTS: 3
-
- uploadFileFromDisk: (project_id, file_args, fsPath, callback = (error, url, fileRef) ->)->
- fs.lstat fsPath, (err, stat)->
- if err?
- logger.err err:err, project_id:project_id, file_args:file_args, fsPath:fsPath, "error stating file"
- callback(err)
- if !stat?
- logger.err project_id:project_id, file_args:file_args, fsPath:fsPath, "stat is not available, can not check file from disk"
- return callback(new Error("error getting stat, not available"))
- if !stat.isFile()
- logger.log project_id:project_id, file_args:file_args, fsPath:fsPath, "tried to upload symlink, not contining"
- return callback(new Error("can not upload symlink"))
- Async.retry FileStoreHandler.RETRY_ATTEMPTS, (cb, results) ->
- FileStoreHandler._doUploadFileFromDisk project_id, file_args, fsPath, cb
- , (err, result) ->
- if err?
- logger.err {err, project_id, file_args}, "Error uploading file, retries failed"
- return callback(err)
- callback(err, result.url, result.fileRef)
-
- _doUploadFileFromDisk: (project_id, file_args, fsPath, callback = (err, result)->) ->
- _cb = callback
- callback = (err, result...) ->
- callback = -> # avoid double callbacks
- _cb(err, result...)
-
- FileHashManager.computeHash fsPath, (err, hashValue) ->
- return callback(err) if err?
- fileRef = new File(Object.assign({}, file_args, {hash: hashValue}))
- file_id = fileRef._id
- logger.log project_id:project_id, file_id:file_id, fsPath:fsPath, hash: hashValue, fileRef:fileRef, "uploading file from disk"
- readStream = fs.createReadStream(fsPath)
- readStream.on "error", (err)->
- logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "something went wrong on the read stream of uploadFileFromDisk"
- callback err
- readStream.on "open", () ->
- url = FileStoreHandler._buildUrl(project_id, file_id)
- opts =
- method: "post"
- uri: url
- timeout:fiveMinsInMs
- headers:
- "X-File-Hash-From-Web": hashValue # send the hash to the filestore as a custom header so it can be checked
- writeStream = request(opts)
- writeStream.on "error", (err)->
- logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "something went wrong on the write stream of uploadFileFromDisk"
- callback err
- writeStream.on 'response', (response) ->
- if response.statusCode not in [200, 201]
- err = new Error("non-ok response from filestore for upload: #{response.statusCode}")
- logger.err {err, statusCode: response.statusCode}, "error uploading to filestore"
- callback(err)
- else
- callback(null, {url, fileRef}) # have to pass back an object because async.retry only accepts a single result argument
- readStream.pipe writeStream
-
- getFileStream: (project_id, file_id, query, callback)->
- logger.log project_id:project_id, file_id:file_id, query:query, "getting file stream from file store"
- queryString = ""
- if query? and query["format"]?
- queryString = "?format=#{query['format']}"
- opts =
- method : "get"
- uri: "#{@_buildUrl(project_id, file_id)}#{queryString}"
- timeout:fiveMinsInMs
- headers: {}
- if query? and query['range']?
- rangeText = query['range']
- if rangeText && rangeText.match? && rangeText.match(/\d+-\d+/)
- opts.headers['range'] = "bytes=#{query['range']}"
- readStream = request(opts)
- readStream.on "error", (err) ->
- logger.err {err, project_id, file_id, query, opts}, "error in file stream"
- callback(null, readStream)
-
- deleteFile: (project_id, file_id, callback)->
- logger.log project_id:project_id, file_id:file_id, "telling file store to delete file"
- opts =
- method : "delete"
- uri: @_buildUrl(project_id, file_id)
- timeout:fiveMinsInMs
- request opts, (err, response)->
- if err?
- logger.err err:err, project_id:project_id, file_id:file_id, "something went wrong deleting file from filestore"
- callback(err)
-
- copyFile: (oldProject_id, oldFile_id, newProject_id, newFile_id, callback)->
- logger.log oldProject_id:oldProject_id, oldFile_id:oldFile_id, newProject_id:newProject_id, newFile_id:newFile_id, "telling filestore to copy a file"
- opts =
- method : "put"
- json:
- source:
- project_id:oldProject_id
- file_id:oldFile_id
- uri: @_buildUrl(newProject_id, newFile_id)
- timeout:fiveMinsInMs
- request opts, (err, response)->
- if err?
- logger.err err:err, oldProject_id:oldProject_id, oldFile_id:oldFile_id, newProject_id:newProject_id, newFile_id:newFile_id, "something went wrong telling filestore api to copy file"
- callback(err)
- else if 200 <= response.statusCode < 300
- # successful response
- callback(null, opts.uri)
- else
- err = new Error("non-ok response from filestore for copyFile: #{response.statusCode}")
- logger.err {uri: opts.uri, statusCode: response.statusCode}, "error uploading to filestore"
- callback(err)
-
- _buildUrl: (project_id, file_id)->
- return "#{settings.apis.filestore.url}/project/#{project_id}/file/#{file_id}"
diff --git a/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee b/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee
deleted file mode 100644
index 79163ded48..0000000000
--- a/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee
+++ /dev/null
@@ -1,87 +0,0 @@
-Mocha = require "mocha"
-Base = require("mocha/lib/reporters/base")
-RedisWrapper = require("../../infrastructure/RedisWrapper")
-rclient = RedisWrapper.client("health_check")
-settings = require("settings-sharelatex")
-logger = require "logger-sharelatex"
-domain = require "domain"
-UserGetter = require("../User/UserGetter")
-
-module.exports = HealthCheckController =
- check: (req, res, next = (error) ->) ->
- d = domain.create()
- d.on "error", (error) ->
- logger.err err: error, "error in mocha"
- d.run () ->
- mocha = new Mocha(reporter: Reporter(res), timeout: 10000)
- mocha.addFile("test/smoke/js/SmokeTests.js")
- mocha.run () ->
- # TODO: combine this with the smoke-test-sharelatex module
- # we need to clean up all references to the smokeTest module
- # so it can be garbage collected. The only reference should
- # be in its parent, when it is loaded by mocha.addFile.
- path = require.resolve(__dirname + "/../../../../test/smoke/js/SmokeTests.js")
- smokeTestModule = require.cache[path]
- if smokeTestModule?
- parent = smokeTestModule.parent
- while (idx = parent.children.indexOf(smokeTestModule)) != -1
- parent.children.splice(idx, 1)
- else
- logger.warn {path}, "smokeTestModule not defined"
- # remove the smokeTest from the module cache
- delete require.cache[path]
-
- checkRedis: (req, res, next)->
- rclient.healthCheck (error) ->
- if error?
- logger.err {err: error}, "failed redis health check"
- res.sendStatus 500
- else
- res.sendStatus 200
-
- checkMongo: (req, res, next)->
- logger.log "running mongo health check"
- UserGetter.getUserEmail settings.smokeTest.userId, (err, email)->
- if err?
- logger.err err:err, "mongo health check failed, error present"
- return res.sendStatus 500
- else if !email?
- logger.err err:err, "mongo health check failed, no emai present in find result"
- return res.sendStatus 500
- else
- logger.log email:email, "mongo health check passed"
- res.sendStatus 200
-
-
-Reporter = (res) ->
- (runner) ->
- Base.call(this, runner)
-
- tests = []
- passes = []
- failures = []
-
- runner.on 'test end', (test) -> tests.push(test)
- runner.on 'pass', (test) -> passes.push(test)
- runner.on 'fail', (test) -> failures.push(test)
-
- runner.on 'end', () =>
- clean = (test) ->
- title: test.fullTitle()
- duration: test.duration
- err: test.err
- timedOut: test.timedOut
-
- results = {
- stats: @stats
- failures: failures.map(clean)
- passes: passes.map(clean)
- }
-
- res.contentType("application/json")
- if failures.length > 0
- logger.err failures:failures, "health check failed"
- res.status(500).send(JSON.stringify(results, null, 2))
- else
- res.status(200).send(JSON.stringify(results, null, 2))
-
diff --git a/services/web/app/coffee/Features/Helpers/EmailHelper.coffee b/services/web/app/coffee/Features/Helpers/EmailHelper.coffee
deleted file mode 100644
index 8b769c1669..0000000000
--- a/services/web/app/coffee/Features/Helpers/EmailHelper.coffee
+++ /dev/null
@@ -1,13 +0,0 @@
-EMAIL_REGEXP = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\ ".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA -Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
-
-module.exports = EmailHelper =
-
- parseEmail: (email) ->
- return null unless email?
- return null if email.length > 254
- email = email.trim().toLowerCase()
-
- matched = email.match EMAIL_REGEXP
- return null unless matched? && matched[0]?
-
- matched[0]
diff --git a/services/web/app/coffee/Features/Helpers/StringHelper.coffee b/services/web/app/coffee/Features/Helpers/StringHelper.coffee
deleted file mode 100644
index f13c5afa3a..0000000000
--- a/services/web/app/coffee/Features/Helpers/StringHelper.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/g
-
-JSON_ESCAPE =
- '&': '\\u0026'
- '>': '\\u003e'
- '<': '\\u003c'
- '\u2028': '\\u2028'
- '\u2029': '\\u2029'
-
-module.exports = StringHelper =
- # stringifies and escapes a json object for use in a script. This ensures that &, < and > characters are escaped,
- # along with quotes. This ensures that the string can be safely rendered into HTML. See rationale at:
- # https://api.rubyonrails.org/classes/ERB/Util.html#method-c-json_escape
- # and implementation lifted from:
- # https://github.com/ember-fastboot/fastboot/blob/cafd96c48564d8384eb83dc908303dba8ece10fd/src/ember-app.js#L496-L510
- stringifyJsonForScript: (object) ->
- return JSON.stringify(object).replace JSON_ESCAPE_REGEXP, (match) ->
- return JSON_ESCAPE[match]
diff --git a/services/web/app/coffee/Features/Helpers/UrlHelper.coffee b/services/web/app/coffee/Features/Helpers/UrlHelper.coffee
deleted file mode 100644
index 6e28f1ed73..0000000000
--- a/services/web/app/coffee/Features/Helpers/UrlHelper.coffee
+++ /dev/null
@@ -1,14 +0,0 @@
-Settings = require 'settings-sharelatex'
-
-module.exports = UrlHelper =
-
- wrapUrlWithProxy: (url) ->
- # TODO: Consider what to do for Community and Enterprise edition?
- if !Settings.apis?.linkedUrlProxy?.url?
- throw new Error('no linked url proxy configured')
- return "#{Settings.apis.linkedUrlProxy.url}?url=#{encodeURIComponent(url)}"
-
- prependHttpIfNeeded: (url) ->
- if !url.match('://')
- url = 'http://' + url
- return url
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/History/HistoryController.coffee b/services/web/app/coffee/Features/History/HistoryController.coffee
deleted file mode 100644
index c11dcd8deb..0000000000
--- a/services/web/app/coffee/Features/History/HistoryController.coffee
+++ /dev/null
@@ -1,209 +0,0 @@
-_ = require "lodash"
-async = require "async"
-logger = require "logger-sharelatex"
-request = require "request"
-settings = require "settings-sharelatex"
-AuthenticationController = require "../Authentication/AuthenticationController"
-Errors = require "../Errors/Errors"
-HistoryManager = require "./HistoryManager"
-ProjectDetailsHandler = require "../Project/ProjectDetailsHandler"
-ProjectEntityUpdateHandler = require "../Project/ProjectEntityUpdateHandler"
-RestoreManager = require "./RestoreManager"
-
-module.exports = HistoryController =
- selectHistoryApi: (req, res, next = (error) ->) ->
- project_id = req.params?.Project_id
- # find out which type of history service this project uses
- ProjectDetailsHandler.getDetails project_id, (err, project) ->
- return next(err) if err?
- history = project.overleaf?.history
- if history?.id? and history?.display
- req.useProjectHistory = true
- else
- req.useProjectHistory = false
- next()
-
- ensureProjectHistoryEnabled: (req, res, next = (error) ->) ->
- if req.useProjectHistory?
- next()
- else
- logger.log {project_id}, "project history not enabled"
- res.sendStatus(404)
-
- proxyToHistoryApi: (req, res, next = (error) ->) ->
- user_id = AuthenticationController.getLoggedInUserId req
- url = HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
-
- logger.log url: url, "proxying to history api"
- getReq = request(
- url: url
- method: req.method
- headers:
- "X-User-Id": user_id
- )
- getReq.pipe(res)
- getReq.on "error", (error) ->
- logger.error url: url, err: error, "history API error"
- next(error)
-
- proxyToHistoryApiAndInjectUserDetails: (req, res, next = (error) ->) ->
- user_id = AuthenticationController.getLoggedInUserId req
- url = HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
- logger.log url: url, "proxying to history api"
- HistoryController._makeRequest {
- url: url
- method: req.method
- json: true
- headers:
- "X-User-Id": user_id
- }, (error, body) ->
- return next(error) if error?
- HistoryManager.injectUserDetails body, (error, data) ->
- return next(error) if error?
- res.json data
-
- buildHistoryServiceUrl: (useProjectHistory) ->
- # choose a history service, either document-level (trackchanges)
- # or project-level (project_history)
- if useProjectHistory
- return settings.apis.project_history.url
- else
- return settings.apis.trackchanges.url
-
- resyncProjectHistory: (req, res, next = (error) ->) ->
- project_id = req.params.Project_id
- ProjectEntityUpdateHandler.resyncProjectHistory project_id, (error) ->
- return res.sendStatus(404) if error instanceof Errors.ProjectHistoryDisabledError
- return next(error) if error?
- res.sendStatus 204
-
- restoreFileFromV2: (req, res, next) ->
- {project_id} = req.params
- {version, pathname} = req.body
- user_id = AuthenticationController.getLoggedInUserId req
- logger.log {project_id, version, pathname}, "restoring file from v2"
- RestoreManager.restoreFileFromV2 user_id, project_id, version, pathname, (error, entity) ->
- return next(error) if error?
- res.json {
- type: entity.type,
- id: entity._id
- }
-
- restoreDocFromDeletedDoc: (req, res, next) ->
- {project_id, doc_id} = req.params
- {name} = req.body
- user_id = AuthenticationController.getLoggedInUserId(req)
- if !name?
- return res.sendStatus 400 # Malformed request
- logger.log {project_id, doc_id, user_id}, "restoring doc from v1 deleted doc"
- RestoreManager.restoreDocFromDeletedDoc user_id, project_id, doc_id, name, (err, doc) =>
- return next(error) if error?
- res.json {
- doc_id: doc._id
- }
-
- getLabels: (req, res, next) ->
- project_id = req.params.Project_id
- user_id = AuthenticationController.getLoggedInUserId(req)
- HistoryController._makeRequest {
- method: "GET"
- url: "#{settings.apis.project_history.url}/project/#{project_id}/labels"
- json: true
- }, (error, labels) ->
- return next(error) if error?
- res.json labels
-
- createLabel: (req, res, next) ->
- project_id = req.params.Project_id
- {comment, version} = req.body
- user_id = AuthenticationController.getLoggedInUserId(req)
- HistoryController._makeRequest {
- method: "POST"
- url: "#{settings.apis.project_history.url}/project/#{project_id}/user/#{user_id}/labels"
- json: {comment, version}
- }, (error, label) ->
- return next(error) if error?
- res.json label
-
- deleteLabel: (req, res, next) ->
- project_id = req.params.Project_id
- label_id = req.params.label_id
- user_id = AuthenticationController.getLoggedInUserId(req)
- HistoryController._makeRequest {
- method: "DELETE"
- url: "#{settings.apis.project_history.url}/project/#{project_id}/user/#{user_id}/labels/#{label_id}"
- }, (error) ->
- return next(error) if error?
- res.sendStatus 204
-
- _makeRequest: (options, callback) ->
- request options, (error, response, body) ->
- return callback(error) if error?
- if 200 <= response.statusCode < 300
- callback(null, body)
- else
- error = new Error("history api responded with non-success code: #{response.statusCode}")
- logger.error err: error, "project-history api responded with non-success code: #{response.statusCode}"
- callback(error)
-
- downloadZipOfVersion: (req, res, next) ->
- {project_id, version} = req.params
- logger.log {project_id, version}, "got request for zip file at version"
- ProjectDetailsHandler.getDetails project_id, (err, project) ->
- return next(err) if err?
- v1_id = project.overleaf?.history?.id
- if !v1_id?
- logger.err {project_id, version}, 'got request for zip version of non-v1 history project'
- return res.sendStatus(402)
- HistoryController._pipeHistoryZipToResponse v1_id, version, "#{project.name} (Version #{version})", res, next
-
- _pipeHistoryZipToResponse: (v1_project_id, version, name, res, next) ->
- # increase timeout to 6 minutes
- res.setTimeout(6 * 60 * 1000)
- url = "#{settings.apis.v1_history.url}/projects/#{v1_project_id}/version/#{version}/zip"
- logger.log {v1_project_id, version, url}, "getting s3 url from history api"
- options =
- auth:
- user: settings.apis.v1_history.user
- pass: settings.apis.v1_history.pass
- json: true
- method: 'post'
- url: url
- request options, (err, response, body) ->
- if err
- logger.error {err, v1_project_id, version}, "history API error"
- return next(err)
- retryAttempt = 0
- retryDelay = 2000
- # retry for about 6 minutes starting with short delay
- async.retry 40,
- (callback) ->
- setTimeout(() ->
- # increase delay by 1 second up to 10
- retryDelay += 1000 if retryDelay < 10000
- retryAttempt++
- getReq = request(
- url: body.zipUrl
- sendImmediately: true
- )
- getReq.on 'response', (response) ->
- return callback new Error "invalid response" unless response.statusCode == 200
- # pipe also proxies the headers, but we want to customize these ones
- delete response.headers['content-disposition']
- delete response.headers['content-type']
- res.status response.statusCode
- res.setContentDisposition(
- 'attachment',
- {filename: "#{name}.zip"}
- )
- res.contentType('application/zip')
- getReq.pipe(res)
- callback()
- getReq.on "error", (err) ->
- logger.error {err, v1_project_id, version, retryAttempt}, "history s3 download error"
- callback(err)
- , retryDelay)
- (err) ->
- if err
- logger.error {err, v1_project_id, version, retryAttempt}, "history s3 download failed"
- next(err)
diff --git a/services/web/app/coffee/Features/History/HistoryManager.coffee b/services/web/app/coffee/Features/History/HistoryManager.coffee
deleted file mode 100644
index 0a45029b9b..0000000000
--- a/services/web/app/coffee/Features/History/HistoryManager.coffee
+++ /dev/null
@@ -1,99 +0,0 @@
-request = require "request"
-settings = require "settings-sharelatex"
-async = require 'async'
-UserGetter = require "../User/UserGetter"
-
-module.exports = HistoryManager =
- initializeProject: (callback = (error, history_id) ->) ->
- return callback() if !settings.apis.project_history?.initializeHistoryForNewProjects
- request.post {
- url: "#{settings.apis.project_history.url}/project"
- }, (error, res, body)->
- return callback(error) if error?
-
- if res.statusCode >= 200 and res.statusCode < 300
- try
- project = JSON.parse(body)
- catch error
- return callback(error)
-
- overleaf_id = project?.project?.id
- if !overleaf_id
- error = new Error("project-history did not provide an id", project)
- return callback(error)
-
- callback null, { overleaf_id }
- else
- error = new Error("project-history returned a non-success status code: #{res.statusCode}")
- callback error
-
- flushProject: (project_id, callback = (error) ->) ->
- request.post {
- url: "#{settings.apis.project_history.url}/project/#{project_id}/flush"
- }, (error, res, body)->
- return callback(error) if error?
- if res.statusCode >= 200 and res.statusCode < 300
- callback()
- else
- error = new Error("project-history returned a non-success status code: #{res.statusCode}")
- callback error
-
- resyncProject: (project_id, callback = (error) ->) ->
- request.post {
- url: "#{settings.apis.project_history.url}/project/#{project_id}/resync"
- }, (error, res, body)->
- return callback(error) if error?
- if res.statusCode >= 200 and res.statusCode < 300
- callback()
- else
- error = new Error("project-history returned a non-success status code: #{res.statusCode}")
- callback error
-
- injectUserDetails: (data, callback = (error, data_with_users) ->) ->
- # data can be either:
- # {
- # diff: [{
- # i: "foo",
- # meta: {
- # users: ["user_id", { first_name: "James", ... }, ...]
- # ...
- # }
- # }, ...]
- # }
- # or
- # {
- # updates: [{
- # pathnames: ["main.tex"]
- # meta: {
- # users: ["user_id", { first_name: "James", ... }, ...]
- # ...
- # },
- # ...
- # }, ...]
- # }
- # Either way, the top level key points to an array of objects with a meta.users property
- # that we need to replace user_ids with populated user objects.
- # Note that some entries in the users arrays may already have user objects from the v1 history
- # service
- user_ids = new Set()
- for entry in data.diff or data.updates or []
- for user in entry.meta?.users or []
- if typeof user == "string"
- user_ids.add user
- user_ids = Array.from(user_ids)
- UserGetter.getUsers user_ids, { first_name: 1, last_name: 1, email: 1 }, (error, users_array) ->
- return callback(error) if error?
- users = {}
- for user in users_array or []
- users[user._id.toString()] = HistoryManager._userView(user)
- for entry in data.diff or data.updates or []
- entry.meta?.users = (entry.meta?.users or []).map (user) ->
- if typeof user == "string"
- return users[user]
- else
- return user
- callback null, data
-
- _userView: (user) ->
- { _id, first_name, last_name, email } = user
- return { first_name, last_name, email, id: _id }
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/History/RestoreManager.coffee b/services/web/app/coffee/Features/History/RestoreManager.coffee
deleted file mode 100644
index ba7af44c5e..0000000000
--- a/services/web/app/coffee/Features/History/RestoreManager.coffee
+++ /dev/null
@@ -1,60 +0,0 @@
-Settings = require 'settings-sharelatex'
-Path = require 'path'
-FileWriter = require '../../infrastructure/FileWriter'
-FileSystemImportManager = require '../Uploads/FileSystemImportManager'
-ProjectEntityHandler = require '../Project/ProjectEntityHandler'
-ProjectLocator = require '../Project/ProjectLocator'
-EditorController = require '../Editor/EditorController'
-Errors = require '../Errors/Errors'
-moment = require 'moment'
-
-module.exports = RestoreManager =
- restoreDocFromDeletedDoc: (user_id, project_id, doc_id, name, callback = (error, doc, folder_id) ->) ->
- # This is the legacy method for restoring a doc from the SL track-changes/deletedDocs system.
- # It looks up the deleted doc's contents, and then creates a new doc with the same content.
- # We don't actually remove the deleted doc entry, just create a new one from its lines.
- ProjectEntityHandler.getDoc project_id, doc_id, include_deleted: true, (error, lines) ->
- return callback(error) if error?
- addDocWithName = (name, callback) ->
- EditorController.addDoc project_id, null, name, lines, 'restore', user_id, callback
- RestoreManager._addEntityWithUniqueName addDocWithName, name, callback
-
- restoreFileFromV2: (user_id, project_id, version, pathname, callback = (error, entity) ->) ->
- RestoreManager._writeFileVersionToDisk project_id, version, pathname, (error, fsPath) ->
- return callback(error) if error?
- basename = Path.basename(pathname)
- dirname = Path.dirname(pathname)
- if dirname == '.' # no directory
- dirname = ''
- RestoreManager._findOrCreateFolder project_id, dirname, (error, parent_folder_id) ->
- return callback(error) if error?
- addEntityWithName = (name, callback) ->
- FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, name, fsPath, false, callback
- RestoreManager._addEntityWithUniqueName addEntityWithName, basename, callback
-
- _findOrCreateFolder: (project_id, dirname, callback = (error, folder_id) ->) ->
- EditorController.mkdirp project_id, dirname, (error, newFolders, lastFolder) ->
- return callback(error) if error?
- return callback(null, lastFolder?._id)
-
- _addEntityWithUniqueName: (addEntityWithName, basename, callback = (error) ->) ->
- addEntityWithName basename, (error, entity) ->
- if error?
- if error instanceof Errors.InvalidNameError
- # likely a duplicate name, so try with a prefix
- date = moment(new Date()).format('Do MMM YY H:mm:ss')
- # Move extension to the end so the file type is preserved
- extension = Path.extname(basename)
- basename = Path.basename(basename, extension)
- basename = "#{basename} (Restored on #{date})"
- if extension != ''
- basename = "#{basename}#{extension}"
- addEntityWithName basename, callback
- else
- callback(error)
- else
- callback(null, entity)
-
- _writeFileVersionToDisk: (project_id, version, pathname, callback = (error, fsPath) ->) ->
- url = "#{Settings.apis.project_history.url}/project/#{project_id}/version/#{version}/#{encodeURIComponent(pathname)}"
- FileWriter.writeUrlToDisk project_id, url, callback
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/InactiveData/InactiveProjectController.coffee b/services/web/app/coffee/Features/InactiveData/InactiveProjectController.coffee
deleted file mode 100644
index 03db848838..0000000000
--- a/services/web/app/coffee/Features/InactiveData/InactiveProjectController.coffee
+++ /dev/null
@@ -1,25 +0,0 @@
-InactiveProjectManager = require("./InactiveProjectManager")
-logger = require("logger-sharelatex")
-
-
-module.exports =
-
- deactivateOldProjects: (req, res)->
- logger.log "recived request to deactivate old projects"
- numberOfProjectsToArchive = parseInt(req.body.numberOfProjectsToArchive, 10)
- ageOfProjects = req.body.ageOfProjects
- InactiveProjectManager.deactivateOldProjects numberOfProjectsToArchive, ageOfProjects, (err, projectsDeactivated)->
- if err?
- res.sendStatus(500)
- else
- res.send(projectsDeactivated)
-
-
- deactivateProject: (req, res)->
- project_id = req.params.project_id
- logger.log project_id:project_id, "recived request to deactivating project"
- InactiveProjectManager.deactivateProject project_id, (err)->
- if err?
- res.sendStatus 500
- else
- res.sendStatus 200
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/InactiveData/InactiveProjectManager.coffee b/services/web/app/coffee/Features/InactiveData/InactiveProjectManager.coffee
deleted file mode 100644
index 5c984dcb5d..0000000000
--- a/services/web/app/coffee/Features/InactiveData/InactiveProjectManager.coffee
+++ /dev/null
@@ -1,59 +0,0 @@
-async = require("async")
-_ = require("underscore")
-logger = require("logger-sharelatex")
-DocstoreManager = require("../Docstore/DocstoreManager")
-ProjectGetter = require("../Project/ProjectGetter")
-ProjectUpdateHandler = require("../Project/ProjectUpdateHandler")
-Project = require("../../models/Project").Project
-
-MILISECONDS_IN_DAY = 86400000
-module.exports = InactiveProjectManager =
-
- reactivateProjectIfRequired: (project_id, callback)->
- ProjectGetter.getProject project_id, {active:true}, (err, project)->
- if err?
- logger.err err:err, project_id:project_id, "error getting project"
- return callback(err)
- logger.log project_id:project_id, active:project.active, "seeing if need to reactivate project"
-
- if project.active
- return callback()
-
- DocstoreManager.unarchiveProject project_id, (err)->
- if err?
- logger.err err:err, project_id:project_id, "error reactivating project in docstore"
- return callback(err)
- ProjectUpdateHandler.markAsActive project_id, callback
-
- deactivateOldProjects: (limit = 10, daysOld = 360, callback)->
- oldProjectDate = new Date() - (MILISECONDS_IN_DAY * daysOld)
- logger.log oldProjectDate:oldProjectDate, limit:limit, daysOld:daysOld, "starting process of deactivating old projects"
- Project.find()
- .where("lastOpened").lt(oldProjectDate)
- .where("active").equals(true)
- .select("_id")
- .limit(limit)
- .exec (err, projects)->
- if err?
- logger.err err:err, "could not get projects for deactivating"
- jobs = _.map projects, (project)->
- return (cb)->
- InactiveProjectManager.deactivateProject project._id, cb
- logger.log numberOfProjects:projects?.length, "deactivating projects"
- async.series jobs, (err)->
- if err?
- logger.err err:err, "error deactivating projects"
- callback err, projects
-
-
- deactivateProject: (project_id, callback)->
- logger.log project_id:project_id, "deactivating inactive project"
- jobs = [
- (cb)-> DocstoreManager.archiveProject project_id, cb
- (cb)-> ProjectUpdateHandler.markAsInactive project_id, cb
- ]
- async.series jobs, (err)->
- if err?
- logger.err err:err, project_id:project_id, "error deactivating project"
- callback(err)
-
diff --git a/services/web/app/coffee/Features/Institutions/InstitutionsAPI.coffee b/services/web/app/coffee/Features/Institutions/InstitutionsAPI.coffee
deleted file mode 100644
index e996c5020f..0000000000
--- a/services/web/app/coffee/Features/Institutions/InstitutionsAPI.coffee
+++ /dev/null
@@ -1,111 +0,0 @@
-logger = require("logger-sharelatex")
-metrics = require("metrics-sharelatex")
-settings = require "settings-sharelatex"
-request = require "request"
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-
-module.exports = InstitutionsAPI =
- getInstitutionAffiliations: (institutionId, callback = (error, body) ->) ->
- makeAffiliationRequest {
- method: 'GET'
- path: "/api/v2/institutions/#{institutionId.toString()}/affiliations"
- defaultErrorMessage: "Couldn't get institution affiliations"
- }, (error, body) -> callback(error, body or [])
-
- getInstitutionLicences: (institutionId, startDate, endDate, lag, callback = (error, body) ->) ->
- makeAffiliationRequest {
- method: 'GET'
- path: "/api/v2/institutions/#{institutionId.toString()}/institution_licences"
- body: {start_date: startDate, end_date: endDate, lag}
- defaultErrorMessage: "Couldn't get institution licences"
- }, callback
-
- getUserAffiliations: (userId, callback = (error, body) ->) ->
- makeAffiliationRequest {
- method: 'GET'
- path: "/api/v2/users/#{userId.toString()}/affiliations"
- defaultErrorMessage: "Couldn't get user affiliations"
- }, (error, body) -> callback(error, body or [])
-
- addAffiliation: (userId, email, affiliationOptions, callback) ->
- unless callback? # affiliationOptions is optional
- callback = affiliationOptions
- affiliationOptions = {}
-
- { university, department, role, confirmedAt } = affiliationOptions
- makeAffiliationRequest {
- method: 'POST'
- path: "/api/v2/users/#{userId.toString()}/affiliations"
- body: { email, university, department, role, confirmedAt }
- defaultErrorMessage: "Couldn't create affiliation"
- }, (error, body) ->
- if error
- return callback(error, body)
- # have notifications delete any ip matcher notifications for this university
- logger.log university
- NotificationsBuilder.ipMatcherAffiliation(userId).read university?.id, (err) ->
- if err
- logger.err err:err, "Something went wrong marking ip notifications read"
- callback(error, body)
-
- removeAffiliation: (userId, email, callback = (error) ->) ->
- makeAffiliationRequest {
- method: 'POST'
- path: "/api/v2/users/#{userId.toString()}/affiliations/remove"
- body: { email }
- extraSuccessStatusCodes: [404] # `Not Found` responses are considered successful
- defaultErrorMessage: "Couldn't remove affiliation"
- }, callback
-
-
- endorseAffiliation: (userId, email, role, department, callback = (error) ->) ->
- makeAffiliationRequest {
- method: 'POST'
- path: "/api/v2/users/#{userId.toString()}/affiliations/endorse"
- body: { email, role, department }
- defaultErrorMessage: "Couldn't endorse affiliation"
- }, callback
-
-
- deleteAffiliations: (userId, callback = (error) ->) ->
- makeAffiliationRequest {
- method: 'DELETE'
- path: "/api/v2/users/#{userId.toString()}/affiliations"
- defaultErrorMessage: "Couldn't delete affiliations"
- }, callback
-
-
-makeAffiliationRequest = (requestOptions, callback = (error) ->) ->
- return callback(null) unless settings?.apis?.v1?.url # service is not configured
- requestOptions.extraSuccessStatusCodes ||= []
- request {
- method: requestOptions.method
- url: "#{settings.apis.v1.url}#{requestOptions.path}"
- body: requestOptions.body
- auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass }
- json: true,
- timeout: 20 * 1000
- }, (error, response, body) ->
- return callback(error) if error?
- isSuccess = 200 <= response.statusCode < 300
- isSuccess ||= response.statusCode in requestOptions.extraSuccessStatusCodes
- unless isSuccess
- if body?.errors
- errorMessage = "#{response.statusCode}: #{body.errors}"
- else
- errorMessage = "#{requestOptions.defaultErrorMessage}: #{response.statusCode}"
-
- logger.err path: requestOptions.path, body: requestOptions.body, errorMessage
- return callback(new Error(errorMessage))
-
- callback(null, body)
-
-[
- 'getInstitutionAffiliations'
- 'getUserAffiliations',
- 'addAffiliation',
- 'removeAffiliation',
-].map (method) ->
- metrics.timeAsyncMethod(
- InstitutionsAPI, method, 'mongo.InstitutionsAPI', logger
- )
diff --git a/services/web/app/coffee/Features/Institutions/InstitutionsController.coffee b/services/web/app/coffee/Features/Institutions/InstitutionsController.coffee
deleted file mode 100644
index f687c8a000..0000000000
--- a/services/web/app/coffee/Features/Institutions/InstitutionsController.coffee
+++ /dev/null
@@ -1,33 +0,0 @@
-logger = require("logger-sharelatex")
-UserGetter = require("../User/UserGetter")
-{ addAffiliation } = require("../Institutions/InstitutionsAPI")
-FeaturesUpdater = require('../Subscription/FeaturesUpdater')
-async = require('async')
-
-module.exports = InstitutionsController =
- confirmDomain: (req, res, next) ->
- hostname = req.body.hostname
- affiliateUsers hostname, (error) ->
- return next(error) if error?
- res.sendStatus 200
-
-affiliateUsers = (hostname, callback = (error)->) ->
- reversedHostname = hostname.trim().split('').reverse().join('')
- UserGetter.getUsersByHostname hostname, {_id:1, emails:1}, (error, users) ->
- if error?
- logger.err error: error, 'problem fetching users by hostname'
- return callback(error)
-
- async.map users, ((user, innerCallback) ->
- affiliateUserByReversedHostname user, reversedHostname, innerCallback
- ), callback
-
-affiliateUserByReversedHostname = (user, reversedHostname, callback) ->
- matchingEmails = user.emails.filter (email) -> email.reversedHostname == reversedHostname
- async.map matchingEmails, ((email, innerCallback) ->
- addAffiliation user._id, email.email, {confirmedAt: email.confirmedAt}, (error) =>
- if error?
- logger.err error: error, 'problem adding affiliation while confirming hostname'
- return innerCallback(error)
- FeaturesUpdater.refreshFeatures user._id, true, innerCallback
- ), callback
diff --git a/services/web/app/coffee/Features/Institutions/InstitutionsFeatures.coffee b/services/web/app/coffee/Features/Institutions/InstitutionsFeatures.coffee
deleted file mode 100644
index d780461492..0000000000
--- a/services/web/app/coffee/Features/Institutions/InstitutionsFeatures.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-InstitutionsGetter = require './InstitutionsGetter'
-PlansLocator = require '../Subscription/PlansLocator'
-Settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-
-module.exports = InstitutionsFeatures =
- getInstitutionsFeatures: (userId, callback = (error, features) ->) ->
- InstitutionsFeatures.getInstitutionsPlan userId, (error, plan) ->
- return callback error if error?
- plan = PlansLocator.findLocalPlanInSettings plan
- callback(null, plan?.features or {})
-
-
- getInstitutionsPlan: (userId, callback = (error, plan) ->) ->
- InstitutionsFeatures.hasLicence userId, (error, hasLicence) ->
- return callback error if error?
- return callback(null, null) unless hasLicence
- callback(null, Settings.institutionPlanCode)
-
-
- hasLicence: (userId, callback = (error, hasLicence) ->) ->
- InstitutionsGetter.getConfirmedInstitutions userId, (error, institutions) ->
- return callback error if error?
-
- hasLicence = institutions.some (institution) ->
- institution.licence and institution.licence != 'free'
-
- callback(null, hasLicence)
diff --git a/services/web/app/coffee/Features/Institutions/InstitutionsGetter.coffee b/services/web/app/coffee/Features/Institutions/InstitutionsGetter.coffee
deleted file mode 100644
index 8a9de16482..0000000000
--- a/services/web/app/coffee/Features/Institutions/InstitutionsGetter.coffee
+++ /dev/null
@@ -1,19 +0,0 @@
-UserGetter = require '../User/UserGetter'
-UserMembershipsHandler = require "../UserMembership/UserMembershipsHandler"
-UserMembershipEntityConfigs = require "../UserMembership/UserMembershipEntityConfigs"
-logger = require 'logger-sharelatex'
-
-module.exports = InstitutionsGetter =
- getConfirmedInstitutions: (userId, callback = (error, institutions) ->) ->
- UserGetter.getUserFullEmails userId, (error, emailsData) ->
- return callback error if error?
-
- confirmedInstitutions = emailsData.filter (emailData) ->
- emailData.confirmedAt? and emailData.affiliation?.institution?.confirmed
- .map (emailData) ->
- emailData.affiliation?.institution
-
- callback(null, confirmedInstitutions)
-
- getManagedInstitutions: (user_id, callback = (error, managedInstitutions) ->) ->
- UserMembershipsHandler.getEntitiesByUser UserMembershipEntityConfigs.institution, user_id, callback
diff --git a/services/web/app/coffee/Features/Institutions/InstitutionsManager.coffee b/services/web/app/coffee/Features/Institutions/InstitutionsManager.coffee
deleted file mode 100644
index 73a230ea39..0000000000
--- a/services/web/app/coffee/Features/Institutions/InstitutionsManager.coffee
+++ /dev/null
@@ -1,103 +0,0 @@
-logger = require 'logger-sharelatex'
-async = require 'async'
-db = require("../../infrastructure/mongojs").db
-_ = require("underscore")
-ObjectId = require("../../infrastructure/mongojs").ObjectId
-{ getInstitutionAffiliations } = require('./InstitutionsAPI')
-FeaturesUpdater = require('../Subscription/FeaturesUpdater')
-UserGetter = require('../User/UserGetter')
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-SubscriptionLocator = require("../Subscription/SubscriptionLocator")
-Institution = require("../../models/Institution").Institution
-Subscription = require("../../models/Subscription").Subscription
-
-ASYNC_LIMIT = 10
-module.exports = InstitutionsManager =
- upgradeInstitutionUsers: (institutionId, callback = (error) ->) ->
- async.waterfall [
- (cb) ->
- fetchInstitutionAndAffiliations institutionId, cb
- (institution, affiliations, cb) ->
- affiliations = _.map affiliations, (affiliation) ->
- affiliation.institutionName = institution.name
- affiliation.institutionId = institutionId
- return affiliation
- async.eachLimit affiliations, ASYNC_LIMIT, refreshFeatures, (err) -> cb(err)
- ], callback
-
- checkInstitutionUsers: (institutionId, callback = (error) ->) ->
- getInstitutionAffiliations institutionId, (error, affiliations) ->
- UserGetter.getUsersByAnyConfirmedEmail(
- affiliations.map((affiliation) -> affiliation.email),
- { features: 1 },
- (error, users) ->
- callback(error, checkFeatures(users))
- )
-
- getInstitutionUsersSubscriptions: (institutionId, callback = (error, subscriptions) ->) ->
- getInstitutionAffiliations institutionId, (error, affiliations) ->
- return callback(error) if error?
- userIds = affiliations.map (affiliation) -> ObjectId(affiliation.user_id)
- Subscription
- .find admin_id: userIds, planCode: { $not: /trial/ }
- .populate 'admin_id', 'email'
- .exec callback
-
-fetchInstitutionAndAffiliations = (institutionId, callback) ->
- async.waterfall [
- (cb) ->
- Institution.findOne {v1Id: institutionId}, (err, institution) -> cb(err, institution)
- (institution, cb) ->
- institution.fetchV1Data (err, institution) -> cb(err, institution)
- (institution, cb) ->
- getInstitutionAffiliations institutionId, (err, affiliations) -> cb(err, institution, affiliations)
- ], callback
-
-refreshFeatures = (affiliation, callback) ->
- userId = ObjectId(affiliation.user_id)
- async.waterfall [
- (cb) ->
- FeaturesUpdater.refreshFeatures userId, true, (err, features, featuresChanged) -> cb(err, featuresChanged)
- (featuresChanged, cb) ->
- getUserInfo userId, (error, user, subscription) -> cb(error, user, subscription, featuresChanged)
- (user, subscription, featuresChanged, cb) ->
- notifyUser user, affiliation, subscription, featuresChanged, cb
- ], callback
-
-getUserInfo = (userId, callback) ->
- async.waterfall [
- (cb) ->
- UserGetter.getUser userId, cb
- (user, cb) ->
- SubscriptionLocator.getUsersSubscription user, (err, subscription) -> cb(err, user, subscription)
- ], callback
-
-notifyUser = (user, affiliation, subscription, featuresChanged, callback) ->
- async.parallel [
- (cb) ->
- if featuresChanged
- NotificationsBuilder.featuresUpgradedByAffiliation(affiliation, user).create cb
- else
- cb()
- (cb) ->
- if subscription? and !subscription.planCode.match(/(free|trial)/)? and !subscription.groupPlan
- NotificationsBuilder.redundantPersonalSubscription(affiliation, user).create cb
- else
- cb()
- ], callback
-
-checkFeatures = (users) ->
- usersSummary = {
- totalConfirmedUsers: users.length
- totalConfirmedProUsers: 0
- totalConfirmedNonProUsers: 0
- confirmedNonProUsers: []
- }
- users.forEach((user) ->
- if user.features.collaborators == -1 and user.features.trackChanges
- usersSummary.totalConfirmedProUsers += 1
- else
- usersSummary.totalConfirmedNonProUsers += 1
- usersSummary.confirmedNonProUsers.push user._id
- )
- return usersSummary
diff --git a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesController.coffee b/services/web/app/coffee/Features/LinkedFiles/LinkedFilesController.coffee
deleted file mode 100644
index 03c4e6c975..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesController.coffee
+++ /dev/null
@@ -1,149 +0,0 @@
-AuthenticationController = require '../Authentication/AuthenticationController'
-EditorController = require '../Editor/EditorController'
-ProjectLocator = require '../Project/ProjectLocator'
-Settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-_ = require 'underscore'
-LinkedFilesHandler = require './LinkedFilesHandler'
-{
- UrlFetchFailedError,
- InvalidUrlError,
- OutputFileFetchFailedError,
- AccessDeniedError,
- BadEntityTypeError,
- BadDataError,
- ProjectNotFoundError,
- V1ProjectNotFoundError,
- SourceFileNotFoundError,
- NotOriginalImporterError,
- FeatureNotAvailableError,
- RemoteServiceError,
- FileCannotRefreshError
-} = require './LinkedFilesErrors'
-Modules = require '../../infrastructure/Modules'
-
-
-module.exports = LinkedFilesController = {
-
- Agents: _.extend(
- {
- url: require('./UrlAgent'),
- project_file: require('./ProjectFileAgent'),
- project_output_file: require('./ProjectOutputFileAgent'),
- },
- Modules.linkedFileAgentsIncludes()
- )
-
- _getAgent: (provider) ->
- if !LinkedFilesController.Agents.hasOwnProperty(provider)
- return null
- unless provider in Settings.enabledLinkedFileTypes
- return null
- LinkedFilesController.Agents[provider]
-
- createLinkedFile: (req, res, next) ->
- {project_id} = req.params
- {name, provider, data, parent_folder_id} = req.body
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {project_id, name, provider, data, parent_folder_id, user_id}, 'create linked file request'
-
- Agent = LinkedFilesController._getAgent(provider)
- if !Agent?
- return res.sendStatus(400)
-
- data.provider = provider
-
- Agent.createLinkedFile project_id,
- data,
- name,
- parent_folder_id,
- user_id,
- (err, newFileId) ->
- return LinkedFilesController.handleError(err, req, res, next) if err?
- res.json(new_file_id: newFileId)
-
- refreshLinkedFile: (req, res, next) ->
- {project_id, file_id} = req.params
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {project_id, file_id, user_id}, 'refresh linked file request'
-
- LinkedFilesHandler.getFileById project_id, file_id, (err, file, path, parentFolder) ->
- return next(err) if err?
- return res.sendStatus(404) if !file?
- name = file.name
- linkedFileData = file.linkedFileData
- if !linkedFileData? || !linkedFileData?.provider?
- return res.send(409)
- provider = linkedFileData.provider
- parent_folder_id = parentFolder._id
- Agent = LinkedFilesController._getAgent(provider)
- if !Agent?
- return res.sendStatus(400)
-
- Agent.refreshLinkedFile project_id,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, newFileId) ->
- return LinkedFilesController.handleError(err, req, res, next) if err?
- res.json(new_file_id: newFileId)
-
- handleError: (error, req, res, next) ->
- if error instanceof BadDataError
- res.status(400).send("The submitted data is not valid")
-
- else if error instanceof AccessDeniedError
- res.status(403).send("You do not have access to this project")
-
- else if error instanceof BadDataError
- res.status(400).send("The submitted data is not valid")
-
- else if error instanceof BadEntityTypeError
- res.status(400).send("The file is the wrong type")
-
- else if error instanceof SourceFileNotFoundError
- res.status(404).send("Source file not found")
-
- else if error instanceof ProjectNotFoundError
- res.status(404).send("Project not found")
-
- else if error instanceof V1ProjectNotFoundError
- res.status(409).send("Sorry, the source project is not yet imported to Overleaf v2. Please import it to Overleaf v2 to refresh this file")
-
- else if error instanceof OutputFileFetchFailedError
- res.status(404).send("Could not get output file")
-
- else if error instanceof UrlFetchFailedError
- res.status(422).send(
- "Your URL could not be reached (#{error.statusCode} status code). Please check it and try again."
- )
-
- else if error instanceof InvalidUrlError
- res.status(422).send(
- "Your URL is not valid. Please check it and try again."
- )
-
- else if error instanceof NotOriginalImporterError
- res.status(400).send(
- "You are not the user who originally imported this file"
- )
-
- else if error instanceof FeatureNotAvailableError
- res.status(400).send(
- "This feature is not enabled on your account"
- )
-
- else if error instanceof RemoteServiceError
- res.status(502).send(
- "The remote service produced an error"
- )
-
- else if error instanceof FileCannotRefreshError
- res.status(400).send(
- "This file cannot be refreshed"
- )
-
- else
- next(error)
-}
diff --git a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesErrors.coffee b/services/web/app/coffee/Features/LinkedFiles/LinkedFilesErrors.coffee
deleted file mode 100644
index 96509c91f1..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesErrors.coffee
+++ /dev/null
@@ -1,120 +0,0 @@
-UrlFetchFailedError = (message) ->
- error = new Error(message)
- error.name = 'UrlFetchFailedError'
- error.__proto__ = UrlFetchFailedError.prototype
- return error
-UrlFetchFailedError.prototype.__proto__ = Error.prototype
-
-
-InvalidUrlError = (message) ->
- error = new Error(message)
- error.name = 'InvalidUrlError'
- error.__proto__ = InvalidUrlError.prototype
- return error
-InvalidUrlError.prototype.__proto__ = Error.prototype
-
-
-OutputFileFetchFailedError = (message) ->
- error = new Error(message)
- error.name = 'OutputFileFetchFailedError'
- error.__proto__ = OutputFileFetchFailedError.prototype
- return error
-OutputFileFetchFailedError.prototype.__proto__ = Error.prototype
-
-
-AccessDeniedError = (message) ->
- error = new Error(message)
- error.name = 'AccessDenied'
- error.__proto__ = AccessDeniedError.prototype
- return error
-AccessDeniedError.prototype.__proto__ = Error.prototype
-
-
-BadEntityTypeError = (message) ->
- error = new Error(message)
- error.name = 'BadEntityType'
- error.__proto__ = BadEntityTypeError.prototype
- return error
-BadEntityTypeError.prototype.__proto__ = Error.prototype
-
-
-BadDataError = (message) ->
- error = new Error(message)
- error.name = 'BadData'
- error.__proto__ = BadDataError.prototype
- return error
-BadDataError.prototype.__proto__ = Error.prototype
-
-
-ProjectNotFoundError = (message) ->
- error = new Error(message)
- error.name = 'ProjectNotFound'
- error.__proto__ = ProjectNotFoundError.prototype
- return error
-ProjectNotFoundError.prototype.__proto__ = Error.prototype
-
-
-V1ProjectNotFoundError = (message) ->
- error = new Error(message)
- error.name = 'V1ProjectNotFound'
- error.__proto__ = V1ProjectNotFoundError.prototype
- return error
-V1ProjectNotFoundError.prototype.__proto__ = Error.prototype
-
-
-SourceFileNotFoundError = (message) ->
- error = new Error(message)
- error.name = 'SourceFileNotFound'
- error.__proto__ = SourceFileNotFoundError.prototype
- return error
-SourceFileNotFoundError.prototype.__proto__ = Error.prototype
-
-
-NotOriginalImporterError = (message) ->
- error = new Error(message)
- error.name = 'NotOriginalImporter'
- error.__proto__ = NotOriginalImporterError.prototype
- return error
-NotOriginalImporterError.prototype.__proto__ = Error.prototype
-
-
-FeatureNotAvailableError = (message) ->
- error = new Error(message)
- error.name = 'FeatureNotAvailable'
- error.__proto__ = FeatureNotAvailableError.prototype
- return error
-FeatureNotAvailableError.prototype.__proto__ = Error.prototype
-
-
-RemoteServiceError = (message) ->
- error = new Error(message)
- error.name = 'RemoteService'
- error.__proto__ = RemoteServiceError.prototype
- return error
-RemoteServiceError.prototype.__proto__ = Error.prototype
-
-
-FileCannotRefreshError = (message) ->
- error = new Error(message)
- error.name = 'RemoteService'
- error.__proto__ = FileCannotRefreshError.prototype
- return error
-FileCannotRefreshError.prototype.__proto__ = Error.prototype
-
-
-module.exports = {
-
- UrlFetchFailedError,
- InvalidUrlError,
- OutputFileFetchFailedError,
- AccessDeniedError,
- BadEntityTypeError,
- BadDataError,
- ProjectNotFoundError,
- V1ProjectNotFoundError,
- SourceFileNotFoundError,
- NotOriginalImporterError,
- FeatureNotAvailableError,
- RemoteServiceError,
- FileCannotRefreshError
-}
diff --git a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesHandler.coffee b/services/web/app/coffee/Features/LinkedFiles/LinkedFilesHandler.coffee
deleted file mode 100644
index 6262f0a5ab..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesHandler.coffee
+++ /dev/null
@@ -1,86 +0,0 @@
-FileWriter = require '../../infrastructure/FileWriter'
-EditorController = require '../Editor/EditorController'
-ProjectLocator = require '../Project/ProjectLocator'
-Project = require("../../models/Project").Project
-ProjectGetter = require("../Project/ProjectGetter")
-_ = require 'underscore'
-{
- ProjectNotFoundError,
- V1ProjectNotFoundError,
- BadDataError
-} = require './LinkedFilesErrors'
-
-
-module.exports = LinkedFilesHandler =
-
- getFileById: (project_id, file_id, callback=(err, file)->) ->
- ProjectLocator.findElement {
- project_id,
- element_id: file_id,
- type: 'file'
- }, (err, file, path, parentFolder) ->
- return callback(err) if err?
- callback(null, file, path, parentFolder)
-
- getSourceProject: (data, callback=(err, project)->) ->
- projection = {_id: 1, name: 1}
- if data.v1_source_doc_id?
- Project.findOne {'overleaf.id': data.v1_source_doc_id}, projection, (err, project) ->
- return callback(err) if err?
- if !project?
- return callback(new V1ProjectNotFoundError())
- callback(null, project)
- else if data.source_project_id?
- ProjectGetter.getProject data.source_project_id, projection, (err, project) ->
- return callback(err) if err?
- if !project?
- return callback(new ProjectNotFoundError())
- callback(null, project)
- else
- callback(new BadDataError('neither v1 nor v2 id present'))
-
- importFromStream: (
- project_id,
- readStream,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- callback=(err, file)->
- ) ->
- callback = _.once(callback)
- FileWriter.writeStreamToDisk project_id, readStream, (err, fsPath) ->
- return callback(err) if err?
- EditorController.upsertFile project_id,
- parent_folder_id,
- name,
- fsPath,
- linkedFileData,
- "upload",
- user_id,
- (err, file) =>
- return callback(err) if err?
- callback(null, file)
-
- importContent: (
- project_id,
- content,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- callback=(err, file)->
- ) ->
- callback = _.once(callback)
- FileWriter.writeContentToDisk project_id, content, (err, fsPath) ->
- return callback(err) if err?
- EditorController.upsertFile project_id,
- parent_folder_id,
- name,
- fsPath,
- linkedFileData,
- "upload",
- user_id,
- (err, file) =>
- return callback(err) if err?
- callback(null, file)
diff --git a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesRouter.coffee b/services/web/app/coffee/Features/LinkedFiles/LinkedFilesRouter.coffee
deleted file mode 100644
index 0d2bb89280..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/LinkedFilesRouter.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
-AuthenticationController = require('../Authentication/AuthenticationController')
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-LinkedFilesController = require "./LinkedFilesController"
-
-module.exports =
- apply: (webRouter) ->
- webRouter.post '/project/:project_id/linked_file',
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanWriteProjectContent,
- RateLimiterMiddleware.rateLimit({
- endpointName: "create-linked-file"
- params: ["project_id"]
- maxRequests: 100
- timeInterval: 60
- }),
- LinkedFilesController.createLinkedFile
-
- webRouter.post '/project/:project_id/linked_file/:file_id/refresh',
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanWriteProjectContent,
- RateLimiterMiddleware.rateLimit({
- endpointName: "refresh-linked-file"
- params: ["project_id"]
- maxRequests: 100
- timeInterval: 60
- }),
- LinkedFilesController.refreshLinkedFile
diff --git a/services/web/app/coffee/Features/LinkedFiles/ProjectFileAgent.coffee b/services/web/app/coffee/Features/LinkedFiles/ProjectFileAgent.coffee
deleted file mode 100644
index ed83379a60..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/ProjectFileAgent.coffee
+++ /dev/null
@@ -1,122 +0,0 @@
-AuthorizationManager = require('../Authorization/AuthorizationManager')
-ProjectLocator = require('../Project/ProjectLocator')
-ProjectGetter = require('../Project/ProjectGetter')
-DocstoreManager = require('../Docstore/DocstoreManager')
-DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-FileStoreHandler = require('../FileStore/FileStoreHandler')
-_ = require "underscore"
-Settings = require 'settings-sharelatex'
-LinkedFilesHandler = require './LinkedFilesHandler'
-{
- BadDataError,
- AccessDeniedError,
- BadEntityTypeError,
- SourceFileNotFoundError,
- ProjectNotFoundError,
- V1ProjectNotFoundError
-} = require './LinkedFilesErrors'
-
-module.exports = ProjectFileAgent = {
-
- createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- if !@_canCreate(linkedFileData)
- return callback(new AccessDeniedError())
- @_go(project_id, linkedFileData, name, parent_folder_id, user_id, callback)
-
- refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- @_go project_id, linkedFileData, name, parent_folder_id, user_id, callback
-
- _prepare: (project_id, linkedFileData, user_id, callback=(err, linkedFileData)->) ->
- @_checkAuth project_id, linkedFileData, user_id, (err, allowed) =>
- return callback(err) if err?
- return callback(new AccessDeniedError()) if !allowed
- if !@_validate(linkedFileData)
- return callback(new BadDataError())
- callback(null, linkedFileData)
-
- _go: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- linkedFileData = @_sanitizeData(linkedFileData)
- @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
- return callback(err) if err?
- if !@_validate(linkedFileData)
- return callback(new BadDataError())
- @_getEntity linkedFileData, user_id, (err, source_project, entity, type) =>
- return callback(err) if err?
- if type == 'doc'
- DocstoreManager.getDoc source_project._id, entity._id, (err, lines) ->
- return callback(err) if err?
- LinkedFilesHandler.importContent project_id,
- lines.join('\n'),
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, file) ->
- return callback(err) if err?
- callback(null, file._id) # Created
- else if type == 'file'
- FileStoreHandler.getFileStream source_project._id, entity._id, null, (err, fileStream) ->
- return callback(err) if err?
- LinkedFilesHandler.importFromStream project_id,
- fileStream,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, file) ->
- return callback(err) if err?
- callback(null, file._id) # Created
- else
- callback(new BadEntityTypeError())
-
- _getEntity:
- (linkedFileData, current_user_id, callback = (err, entity, type) ->) ->
- callback = _.once(callback)
- { source_entity_path } = linkedFileData
- @_getSourceProject linkedFileData, (err, project) ->
- return callback(err) if err?
- source_project_id = project._id
- DocumentUpdaterHandler.flushProjectToMongo source_project_id, (err) ->
- return callback(err) if err?
- ProjectLocator.findElementByPath {
- project_id: source_project_id,
- path: source_entity_path
- exactCaseMatch: true
- }, (err, entity, type) ->
- if err?
- if /^not found.*/.test(err.toString())
- err = new SourceFileNotFoundError()
- return callback(err)
- callback(null, project, entity, type)
-
- _sanitizeData: (data) ->
- return _.pick(
- data,
- 'provider',
- 'source_project_id',
- 'v1_source_doc_id',
- 'source_entity_path'
- )
-
- _validate: (data) ->
- return (
- (data.source_project_id? || data.v1_source_doc_id?) &&
- data.source_entity_path?
- )
-
- _canCreate: (data) ->
- # Don't allow creation of linked-files with v1 doc ids
- !data.v1_source_doc_id?
-
- _getSourceProject: LinkedFilesHandler.getSourceProject
-
- _checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
- callback = _.once(callback)
- if !ProjectFileAgent._validate(data)
- return callback(new BadDataError())
- @_getSourceProject data, (err, project) ->
- return callback(err) if err?
- AuthorizationManager.canUserReadProject current_user_id, project._id, null, (err, canRead) ->
- return callback(err) if err?
- callback(null, canRead)
-}
diff --git a/services/web/app/coffee/Features/LinkedFiles/ProjectOutputFileAgent.coffee b/services/web/app/coffee/Features/LinkedFiles/ProjectOutputFileAgent.coffee
deleted file mode 100644
index e6a5392ba2..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/ProjectOutputFileAgent.coffee
+++ /dev/null
@@ -1,164 +0,0 @@
-AuthorizationManager = require('../Authorization/AuthorizationManager')
-ProjectGetter = require('../Project/ProjectGetter')
-Settings = require 'settings-sharelatex'
-CompileManager = require '../Compile/CompileManager'
-ClsiManager = require '../Compile/ClsiManager'
-ProjectFileAgent = require './ProjectFileAgent'
-_ = require "underscore"
-{
- BadDataError,
- AccessDeniedError,
- BadEntityTypeError,
- OutputFileFetchFailedError
-} = require './LinkedFilesErrors'
-LinkedFilesHandler = require './LinkedFilesHandler'
-logger = require 'logger-sharelatex'
-
-
-module.exports = ProjectOutputFileAgent = {
-
- _prepare: (project_id, linkedFileData, user_id, callback=(err, linkedFileData)->) ->
- @_checkAuth project_id, linkedFileData, user_id, (err, allowed) =>
- return callback(err) if err?
- return callback(new AccessDeniedError()) if !allowed
- if !@_validate(linkedFileData)
- return callback(new BadDataError())
- callback(null, linkedFileData)
-
- createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- if !@_canCreate(linkedFileData)
- return callback(new AccessDeniedError())
- linkedFileData = @_sanitizeData(linkedFileData)
- @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
- return callback(err) if err?
- @_getFileStream linkedFileData, user_id, (err, readStream) =>
- return callback(err) if err?
- readStream.on "error", callback
- readStream.on "response", (response) =>
- if 200 <= response.statusCode < 300
- readStream.resume()
- LinkedFilesHandler.importFromStream project_id,
- readStream,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, file) ->
- return callback(err) if err?
- callback(null, file._id) # Created
- else
- err = new OutputFileFetchFailedError(
- "Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
- )
- err.statusCode = response.statusCode
- callback(err)
-
- refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
- return callback(err) if err?
- @_compileAndGetFileStream linkedFileData, user_id, (err, readStream, new_build_id) =>
- return callback(err) if err?
- readStream.on "error", callback
- readStream.on "response", (response) =>
- if 200 <= response.statusCode < 300
- readStream.resume()
- linkedFileData.build_id = new_build_id
- LinkedFilesHandler.importFromStream project_id,
- readStream,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, file) ->
- return callback(err) if err?
- callback(null, file._id) # Created
- else
- err = new OutputFileFetchFailedError(
- "Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
- )
- err.statusCode = response.statusCode
- callback(err)
-
-
- _sanitizeData: (data) ->
- return {
- provider: data.provider,
- source_project_id: data.source_project_id,
- source_output_file_path: data.source_output_file_path,
- build_id: data.build_id
- }
-
- _canCreate: ProjectFileAgent._canCreate
-
- _getSourceProject: LinkedFilesHandler.getSourceProject
-
- _validate: (data) ->
- if data.v1_source_doc_id?
- (
- data.v1_source_doc_id? &&
- data.source_output_file_path?
- )
- else
- (
- data.source_project_id? &&
- data.source_output_file_path? &&
- data.build_id?
- )
-
- _checkAuth: (project_id, data, current_user_id, callback = (err, allowed)->) ->
- callback = _.once(callback)
- if !@_validate(data)
- return callback(new BadDataError())
- @_getSourceProject data, (err, project) ->
- return callback(err) if err?
- AuthorizationManager.canUserReadProject current_user_id,
- project._id,
- null,
- (err, canRead) ->
- return callback(err) if err?
- callback(null, canRead)
-
- _getFileStream: (linkedFileData, user_id, callback=(err, fileStream)->) ->
- callback = _.once(callback)
- { source_output_file_path, build_id } = linkedFileData
- @_getSourceProject linkedFileData, (err, project) ->
- return callback(err) if err?
- source_project_id = project._id
- ClsiManager.getOutputFileStream source_project_id,
- user_id,
- build_id,
- source_output_file_path,
- (err, readStream) ->
- return callback(err) if err?
- readStream.pause()
- callback(null, readStream)
-
- _compileAndGetFileStream: (linkedFileData, user_id, callback=(err, stream, build_id)->) ->
- callback = _.once(callback)
- { source_output_file_path } = linkedFileData
- @_getSourceProject linkedFileData, (err, project) ->
- return callback(err) if err?
- source_project_id = project._id
- CompileManager.compile source_project_id,
- user_id,
- {},
- (err, status, outputFiles) ->
- return callback(err) if err?
- if status != 'success'
- return callback(new OutputFileFetchFailedError())
- outputFile = _.find(
- outputFiles,
- (o) => o.path == source_output_file_path
- )
- if !outputFile?
- return callback(new OutputFileFetchFailedError())
- build_id = outputFile.build
- ClsiManager.getOutputFileStream source_project_id,
- user_id,
- build_id,
- source_output_file_path,
- (err, readStream) ->
- return callback(err) if err?
- readStream.pause()
- callback(null, readStream, build_id)
-}
diff --git a/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee b/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee
deleted file mode 100644
index e9fe564009..0000000000
--- a/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee
+++ /dev/null
@@ -1,51 +0,0 @@
-request = require 'request'
-_ = require "underscore"
-urlValidator = require 'valid-url'
-{ InvalidUrlError, UrlFetchFailedError } = require './LinkedFilesErrors'
-LinkedFilesHandler = require './LinkedFilesHandler'
-UrlHelper = require '../Helpers/UrlHelper'
-
-module.exports = UrlAgent = {
-
- createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- linkedFileData = @._sanitizeData(linkedFileData)
- @_getUrlStream project_id, linkedFileData, user_id, (err, readStream) ->
- return callback(err) if err?
- readStream.on "error", callback
- readStream.on "response", (response) ->
- if 200 <= response.statusCode < 300
- readStream.resume()
- LinkedFilesHandler.importFromStream project_id,
- readStream,
- linkedFileData,
- name,
- parent_folder_id,
- user_id,
- (err, file) ->
- return callback(err) if err?
- callback(null, file._id) # Created
- else
- error = new UrlFetchFailedError("url fetch failed: #{linkedFileData.url}")
- error.statusCode = response.statusCode
- callback(error)
-
- refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
- @createLinkedFile project_id, linkedFileData, name, parent_folder_id, user_id, callback
-
- _sanitizeData: (data) ->
- return {
- provider: data.provider
- url: UrlHelper.prependHttpIfNeeded(data.url)
- }
-
- _getUrlStream: (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
- callback = _.once(callback)
- url = data.url
- if !urlValidator.isWebUri(url)
- return callback(new InvalidUrlError("invalid url: #{url}"))
- url = UrlHelper.wrapUrlWithProxy(url)
- readStream = request.get(url)
- readStream.pause()
- callback(null, readStream)
-
-}
diff --git a/services/web/app/coffee/Features/Metadata/MetaController.coffee b/services/web/app/coffee/Features/Metadata/MetaController.coffee
deleted file mode 100644
index 21320d4d25..0000000000
--- a/services/web/app/coffee/Features/Metadata/MetaController.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-EditorRealTimeController = require "../Editor/EditorRealTimeController"
-MetaHandler = require './MetaHandler'
-logger = require 'logger-sharelatex'
-
-
-module.exports = MetaController =
-
- getMetadata: (req, res, next) ->
- project_id = req.params.project_id
- logger.log {project_id}, "getting all labels for project"
- MetaHandler.getAllMetaForProject project_id, (err, projectMeta) ->
- if err?
- logger.err {project_id, err}, "[MetaController] error getting all labels from project"
- return next err
- res.json {projectId: project_id, projectMeta: projectMeta}
-
- broadcastMetadataForDoc: (req, res, next) ->
- project_id = req.params.project_id
- doc_id = req.params.doc_id
- logger.log {project_id, doc_id}, "getting labels for doc"
- MetaHandler.getMetaForDoc project_id, doc_id, (err, docMeta) ->
- if err?
- logger.err {project_id, doc_id, err}, "[MetaController] error getting labels from doc"
- return next err
- EditorRealTimeController.emitToRoom project_id, 'broadcastDocMeta', {
- docId: doc_id, meta: docMeta
- }
- res.sendStatus 200
diff --git a/services/web/app/coffee/Features/Metadata/MetaHandler.coffee b/services/web/app/coffee/Features/Metadata/MetaHandler.coffee
deleted file mode 100644
index 822bdbde07..0000000000
--- a/services/web/app/coffee/Features/Metadata/MetaHandler.coffee
+++ /dev/null
@@ -1,66 +0,0 @@
-ProjectEntityHandler = require "../Project/ProjectEntityHandler"
-DocumentUpdaterHandler = require '../DocumentUpdater/DocumentUpdaterHandler'
-packageMapping = require "./packageMapping"
-
-
-module.exports = MetaHandler =
-
- labelRegex: () ->
- /\\label{(.{0,80}?)}/g
-
- usepackageRegex: () ->
- /^\\usepackage(?:\[.{0,80}?])?{(.{0,80}?)}/g
-
- ReqPackageRegex: () ->
- /^\\RequirePackage(?:\[.{0,80}?])?{(.{0,80}?)}/g
-
- getAllMetaForProject: (projectId, callback=(err, projectMeta)->) ->
- DocumentUpdaterHandler.flushProjectToMongo projectId, (err) ->
- if err?
- return callback err
- ProjectEntityHandler.getAllDocs projectId, (err, docs) ->
- if err?
- return callback err
- projectMeta = MetaHandler.extractMetaFromProjectDocs docs
- callback null, projectMeta
-
- getMetaForDoc: (projectId, docId, callback=(err, docMeta)->) ->
- DocumentUpdaterHandler.flushDocToMongo projectId, docId, (err) ->
- if err?
- return callback err
- ProjectEntityHandler.getDoc projectId, docId, (err, lines) ->
- if err?
- return callback err
- docMeta = MetaHandler.extractMetaFromDoc lines
- callback null, docMeta
-
- extractMetaFromDoc: (lines) ->
- docMeta = {labels: [], packages: {}}
- packages = []
- label_re = MetaHandler.labelRegex()
- package_re = MetaHandler.usepackageRegex()
- req_package_re = MetaHandler.ReqPackageRegex()
- for line in lines
- while labelMatch = label_re.exec line
- if label = labelMatch[1]
- docMeta.labels.push label
- while packageMatch = package_re.exec line
- if messy = packageMatch[1]
- for pkg in messy.split ','
- if clean = pkg.trim()
- packages.push clean
- while packageMatch = req_package_re.exec line
- if messy = packageMatch[1]
- for pkg in messy.split ','
- if clean = pkg.trim()
- packages.push clean
- for pkg in packages
- if packageMapping[pkg]?
- docMeta.packages[pkg] = packageMapping[pkg]
- return docMeta
-
- extractMetaFromProjectDocs: (projectDocs) ->
- projectMeta = {}
- for _path, doc of projectDocs
- projectMeta[doc._id] = MetaHandler.extractMetaFromDoc doc.lines
- return projectMeta
diff --git a/services/web/app/coffee/Features/Metadata/packageMapping.coffee b/services/web/app/coffee/Features/Metadata/packageMapping.coffee
deleted file mode 100644
index e2bd07b8bc..0000000000
--- a/services/web/app/coffee/Features/Metadata/packageMapping.coffee
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = {"inputenc": [{"caption": "\\inputencoding{}", "snippet": "\\inputencoding{$1}", "meta": "inputenc-cmd", "score": 0.0002447047447770061}], "graphicx": [{"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "graphicx-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "graphicx-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "graphicx-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "graphicx-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "graphicx-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "graphicx-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "graphicx-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "graphicx-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "graphicx-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphicx-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "graphicx-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "graphicx-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "graphicx-cmd", "score": 0.004649150613625593}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "graphicx-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphicx-cmd", "score": 0.008565354665444157}], "amsmath": [{"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "amsmath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "amsmath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "amsmath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "amsmath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "amsmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "amsmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "amsmath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "amsmath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "amsmath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "amsmath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "amsmath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "amsmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "amsmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "amsmath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "amsmath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "amsmath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "amsmath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "amsmath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "amsmath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "amsmath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "amsmath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "amsmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "amsmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "amsmath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "amsmath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "amsmath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "amsmath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "amsmath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "amsmath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "amsmath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "amsmath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "amsmath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "amsmath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "amsmath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "amsmath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "amsmath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "amsmath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "amsmath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "amsmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "amsmath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "amsmath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "amsmath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "amsmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "amsmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "amsmath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "amsmath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "amsmath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "amsmath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "amsmath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "amsmath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "amsmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "amsmath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "amsmath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "amsmath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "amsmath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "amsmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "amsmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "amsmath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "amsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "amsmath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "amsmath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "amsmath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "amsmath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "amsmath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "amsmath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "amsmath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "amsmath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "amsmath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "amsmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "amsmath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "amsmath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "amsmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "amsmath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "amsmath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "amsmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "amsmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "amsmath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "amsmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "amsmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "amsmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "amsmath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "amsmath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "amsmath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "amsmath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "amsmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "amsmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "amsmath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "amsmath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "amsmath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "amsmath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "amsmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "amsmath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "amsmath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "amsmath-cmd", "score": 0.18137737738638837}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "amsmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "amsmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "amsmath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "amsmath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "amsmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "amsmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "amsmath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "amsmath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "amsmath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "amsmath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "amsmath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "amsmath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "amsmath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "amsmath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "amsmath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "amsmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "amsmath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "amsmath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "amsmath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "amsmath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "amsmath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "amsmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "amsmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "amsmath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "amsmath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "amsmath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "amsmath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "amsmath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "amsmath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "amsmath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "amsmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "amsmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "amsmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "amsmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "amsmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "amsmath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "amsmath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "amsmath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "amsmath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "amsmath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "amsmath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "amsmath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "amsmath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "amsmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "amsmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "amsmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "amsmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "amsmath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "amsmath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "amsmath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "amsmath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "amsmath-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "amsmath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "amsmath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "amsmath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "amsmath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "amsmath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amsmath-cmd", "score": 0.0063276692758974925}], "geometry": [{"caption": "\\savegeometry{}", "snippet": "\\savegeometry{$1}", "meta": "geometry-cmd", "score": 6.461638865465447e-05}, {"caption": "\\loadgeometry{}", "snippet": "\\loadgeometry{$1}", "meta": "geometry-cmd", "score": 6.461638865465447e-05}, {"caption": "\\newgeometry{}", "snippet": "\\newgeometry{$1}", "meta": "geometry-cmd", "score": 0.0025977479207639352}, {"caption": "\\geometry{}", "snippet": "\\geometry{$1}", "meta": "geometry-cmd", "score": 0.046218420429973615}, {"caption": "\\csname", "snippet": "\\csname", "meta": "geometry-cmd", "score": 0.008565354665444157}, {"caption": "\\restoregeometry", "snippet": "\\restoregeometry", "meta": "geometry-cmd", "score": 0.0007546303842143648}, {"caption": "\\csname", "snippet": "\\csname", "meta": "geometry-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "geometry-cmd", "score": 0.002958865219480927}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "geometry-cmd", "score": 0.00037306820619479756}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "geometry-cmd", "score": 0.00021116765384691477}], "amssymb": [{"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "amssymb-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "amssymb-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "amssymb-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "amssymb-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "amssymb-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "amssymb-cmd", "score": 0.0006671850995492977}], "hyperref": [{"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "hyperref-cmd", "score": 0.009472569279662113}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "hyperref-cmd", "score": 0.006492248863367502}, {"caption": "\\figureautorefname", "snippet": "\\figureautorefname", "meta": "hyperref-cmd", "score": 0.00014582556188448738}, {"caption": "\\figureautorefname{}", "snippet": "\\figureautorefname{$1}", "meta": "hyperref-cmd", "score": 0.00014582556188448738}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "hyperref-cmd", "score": 0.006963729684667191}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\footnoteautorefname", "snippet": "\\footnoteautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\roman{}", "snippet": "\\roman{$1}", "meta": "hyperref-cmd", "score": 0.005553384455935491}, {"caption": "\\roman", "snippet": "\\roman", "meta": "hyperref-cmd", "score": 0.005553384455935491}, {"caption": "\\string", "snippet": "\\string", "meta": "hyperref-cmd", "score": 0.001042697111754002}, {"caption": "\\MakeLowercase{}", "snippet": "\\MakeLowercase{$1}", "meta": "hyperref-cmd", "score": 0.017289599800633146}, {"caption": "\\textunderscore", "snippet": "\\textunderscore", "meta": "hyperref-cmd", "score": 0.001509072212764015}, {"caption": "\\do", "snippet": "\\do", "meta": "hyperref-cmd", "score": 0.009278344180101056}, {"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "hyperref-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "hyperref-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "hyperref-cmd", "score": 7.849662248028187}, {"caption": "\\FancyVerbLineautorefname", "snippet": "\\FancyVerbLineautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\hyperlink{}{}", "snippet": "\\hyperlink{$1}{$2}", "meta": "hyperref-cmd", "score": 0.00978652043902115}, {"caption": "\\tableautorefname", "snippet": "\\tableautorefname", "meta": "hyperref-cmd", "score": 0.00012704528567339081}, {"caption": "\\tableautorefname{}", "snippet": "\\tableautorefname{$1}", "meta": "hyperref-cmd", "score": 0.00012704528567339081}, {"caption": "\\equationautorefname", "snippet": "\\equationautorefname", "meta": "hyperref-cmd", "score": 0.00018777198999871106}, {"caption": "\\equationautorefname{}", "snippet": "\\equationautorefname{$1}", "meta": "hyperref-cmd", "score": 0.00018777198999871106}, {"caption": "\\chapterautorefname", "snippet": "\\chapterautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "hyperref-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "hyperref-cmd", "score": 0.02873756018238537}, {"caption": "\\protect", "snippet": "\\protect", "meta": "hyperref-cmd", "score": 0.0200686676229443}, {"caption": "\\appendixautorefname", "snippet": "\\appendixautorefname", "meta": "hyperref-cmd", "score": 7.950698053641679e-05}, {"caption": "\\appendixautorefname{}", "snippet": "\\appendixautorefname{$1}", "meta": "hyperref-cmd", "score": 7.950698053641679e-05}, {"caption": "\\newlabel{}{}", "snippet": "\\newlabel{$1}{$2}", "meta": "hyperref-cmd", "score": 0.00029737672328168955}, {"caption": "\\texorpdfstring{}{}", "snippet": "\\texorpdfstring{$1}{$2}", "meta": "hyperref-cmd", "score": 0.0073781967296121}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "hyperref-cmd", "score": 0.002140559856649122}, {"caption": "\\alph", "snippet": "\\alph", "meta": "hyperref-cmd", "score": 0.01034327266194849}, {"caption": "\\alph{}", "snippet": "\\alph{$1}", "meta": "hyperref-cmd", "score": 0.01034327266194849}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "hyperref-cmd", "score": 0.019788865471151957}, {"caption": "\\item", "snippet": "\\item", "meta": "hyperref-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "hyperref-cmd", "score": 3.800886892251021}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "hyperref-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "hyperref-cmd", "score": 0.2334089308452787}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\itemautorefname", "snippet": "\\itemautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "hyperref-cmd", "score": 1.2569477427490174}, {"caption": "\\sectionautorefname", "snippet": "\\sectionautorefname", "meta": "hyperref-cmd", "score": 0.0019832324299155183}, {"caption": "\\sectionautorefname{}", "snippet": "\\sectionautorefname{$1}", "meta": "hyperref-cmd", "score": 0.0019832324299155183}, {"caption": "\\LaTeXe", "snippet": "\\LaTeXe", "meta": "hyperref-cmd", "score": 0.007928096378157487}, {"caption": "\\LaTeXe{}", "snippet": "\\LaTeXe{$1}", "meta": "hyperref-cmd", "score": 0.007928096378157487}, {"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "hyperref-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "hyperref-cmd", "score": 0.0003680857021151614}, {"caption": "\\hypertarget{}{}", "snippet": "\\hypertarget{$1}{$2}", "meta": "hyperref-cmd", "score": 0.009652820108904094}, {"caption": "\\theoremautorefname", "snippet": "\\theoremautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "hyperref-cmd", "score": 0.7504160124360846}, {"caption": "\\subparagraphautorefname", "snippet": "\\subparagraphautorefname", "meta": "hyperref-cmd", "score": 0.0005446476945175932}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "hyperref-cmd", "score": 0.13586474005868793}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "hyperref-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "hyperref-cmd", "score": 0.8973590434087177}, {"caption": "\\href{}{}", "snippet": "\\href{$1}{$2}", "meta": "hyperref-cmd", "score": 0.27111130260612365}, {"caption": "\\Roman{}", "snippet": "\\Roman{$1}", "meta": "hyperref-cmd", "score": 0.0038703587462843594}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}, {"caption": "\\autoref{}", "snippet": "\\autoref{$1}", "meta": "hyperref-cmd", "score": 0.03741172773691362}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "hyperref-cmd", "score": 0.0004995635515943437}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "hyperref-cmd", "score": 7.847906405228455}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "hyperref-cmd", "score": 0.0174633138331273}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "hyperref-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "hyperref-cmd", "score": 0.006776001543888959}, {"caption": "\\partautorefname", "snippet": "\\partautorefname", "meta": "hyperref-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\Itemautorefname{}", "snippet": "\\Itemautorefname{$1}", "meta": "hyperref-cmd", "score": 6.006262128895586e-05}, {"caption": "\\halign{}", "snippet": "\\halign{$1}", "meta": "hyperref-cmd", "score": 0.00017906650306643613}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "hyperref-cmd", "score": 0.20852115286477566}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "hyperref-cmd", "score": 1.4380093454211778}, {"caption": "\\Alph{}", "snippet": "\\Alph{$1}", "meta": "hyperref-cmd", "score": 0.002233258780143355}, {"caption": "\\Alph", "snippet": "\\Alph", "meta": "hyperref-cmd", "score": 0.002233258780143355}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "hyperref-cmd", "score": 0.047007158741781095}, {"caption": "\\MP", "snippet": "\\MP", "meta": "hyperref-cmd", "score": 0.00018344383742255004}, {"caption": "\\MP{}", "snippet": "\\MP{$1}", "meta": "hyperref-cmd", "score": 0.00018344383742255004}, {"caption": "\\paragraphautorefname", "snippet": "\\paragraphautorefname", "meta": "hyperref-cmd", "score": 0.0005446476945175932}, {"caption": "\\citeN{}", "snippet": "\\citeN{$1}", "meta": "hyperref-cmd", "score": 0.0018503938529945614}, {"caption": "\\citeN", "snippet": "\\citeN", "meta": "hyperref-cmd", "score": 0.0018503938529945614}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "hyperref-cmd", "score": 0.07503475348393239}, {"caption": "\\subsectionautorefname", "snippet": "\\subsectionautorefname", "meta": "hyperref-cmd", "score": 0.0012546605780895737}, {"caption": "\\subsectionautorefname{}", "snippet": "\\subsectionautorefname{$1}", "meta": "hyperref-cmd", "score": 0.0012546605780895737}, {"caption": "\\hyperref[]{}", "snippet": "\\hyperref[$1]{$2}", "meta": "hyperref-cmd", "score": 0.004515152477030062}, {"caption": "\\arabic{}", "snippet": "\\arabic{$1}", "meta": "hyperref-cmd", "score": 0.02445837629741638}, {"caption": "\\arabic", "snippet": "\\arabic", "meta": "hyperref-cmd", "score": 0.02445837629741638}, {"caption": "\\newline", "snippet": "\\newline", "meta": "hyperref-cmd", "score": 0.3311721696201715}, {"caption": "\\hypersetup{}", "snippet": "\\hypersetup{$1}", "meta": "hyperref-cmd", "score": 0.06967310843464661}, {"caption": "\\subsubsectionautorefname", "snippet": "\\subsubsectionautorefname", "meta": "hyperref-cmd", "score": 0.0012064581899162352}, {"caption": "\\subsubsectionautorefname{}", "snippet": "\\subsubsectionautorefname{$1}", "meta": "hyperref-cmd", "score": 0.0012064581899162352}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "hyperref-cmd", "score": 0.9202908262245683}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "hyperref-cmd", "score": 0.00037306820619479756}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "hyperref-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "hyperref-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "hyperref-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "hyperref-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "hyperref-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "hyperref-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "hyperref-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "hyperref-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "hyperref-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "hyperref-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "hyperref-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "hyperref-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "hyperref-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "hyperref-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "hyperref-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hyperref-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hyperref-cmd", "score": 0.002958865219480927}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "hyperref-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hyperref-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hyperref-cmd", "score": 0.00530510025314411}], "babel": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "babel-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "babel-cmd", "score": 0.021170869458413965}], "color": [{"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "color-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "color-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "color-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "color-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "color-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "color-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "color-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "color-cmd", "score": 0.2864294797053033}], "xcolor": [{"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "xcolor-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xcolor-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xcolor-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "xcolor-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "xcolor-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "xcolor-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "xcolor-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "xcolor-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xcolor-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "xcolor-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "xcolor-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xcolor-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "xcolor-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "xcolor-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xcolor-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xcolor-cmd", "score": 0.2864294797053033}], "natbib": [{"caption": "\\citealt{}", "snippet": "\\citealt{$1}", "meta": "natbib-cmd", "score": 0.007302105441724955}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "natbib-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "natbib-cmd", "score": 0.021170869458413965}, {"caption": "\\textsuperscript{}", "snippet": "\\textsuperscript{$1}", "meta": "natbib-cmd", "score": 0.05216393882408519}, {"caption": "\\nocite{}", "snippet": "\\nocite{$1}", "meta": "natbib-cmd", "score": 0.04990693820960752}, {"caption": "\\bibname", "snippet": "\\bibname", "meta": "natbib-cmd", "score": 0.007599529252128519}, {"caption": "\\bibname{}", "snippet": "\\bibname{$1}", "meta": "natbib-cmd", "score": 0.007599529252128519}, {"caption": "\\bibpunct", "snippet": "\\bibpunct", "meta": "natbib-cmd", "score": 0.001148574749873469}, {"caption": "\\bibpunct{}{}{}{}{}{}", "snippet": "\\bibpunct{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "natbib-cmd", "score": 0.001148574749873469}, {"caption": "\\bibpunct[]{}{}{}{}{}{}", "snippet": "\\bibpunct[$1]{$2}{$3}{$4}{$5}{$6}{$7}", "meta": "natbib-cmd", "score": 0.001148574749873469}, {"caption": "\\citepalias{}", "snippet": "\\citepalias{$1}", "meta": "natbib-cmd", "score": 0.00032712684909035603}, {"caption": "\\citepalias[][]{}", "snippet": "\\citepalias[$1][$2]{$3}", "meta": "natbib-cmd", "score": 0.00032712684909035603}, {"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "natbib-cmd", "score": 0.010304996748556729}, {"caption": "\\citep{}", "snippet": "\\citep{$1}", "meta": "natbib-cmd", "score": 0.2941882834697057}, {"caption": "\\bibsection", "snippet": "\\bibsection", "meta": "natbib-cmd", "score": 0.00038872734530908233}, {"caption": "\\bibsection{}", "snippet": "\\bibsection{$1}", "meta": "natbib-cmd", "score": 0.00038872734530908233}, {"caption": "\\refname", "snippet": "\\refname", "meta": "natbib-cmd", "score": 0.006490238196722249}, {"caption": "\\refname{}", "snippet": "\\refname{$1}", "meta": "natbib-cmd", "score": 0.006490238196722249}, {"caption": "\\citealp{}", "snippet": "\\citealp{$1}", "meta": "natbib-cmd", "score": 0.005275912376595364}, {"caption": "\\citealp[]{}", "snippet": "\\citealp[$1]{$2}", "meta": "natbib-cmd", "score": 0.005275912376595364}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "natbib-cmd", "score": 2.341195220791228}, {"caption": "\\citetalias{}", "snippet": "\\citetalias{$1}", "meta": "natbib-cmd", "score": 0.001419571355756266}, {"caption": "\\bibitem{}", "snippet": "\\bibitem{$1}", "meta": "natbib-cmd", "score": 0.3689547570562042}, {"caption": "\\bibitem[]{}", "snippet": "\\bibitem[$1]{$2}", "meta": "natbib-cmd", "score": 0.3689547570562042}, {"caption": "\\citet{}", "snippet": "\\citet{$1}", "meta": "natbib-cmd", "score": 0.09046048561361801}, {"caption": "\\defcitealias{}{}", "snippet": "\\defcitealias{$1}{$2}", "meta": "natbib-cmd", "score": 0.00042021825647418025}, {"caption": "\\aftergroup", "snippet": "\\aftergroup", "meta": "natbib-cmd", "score": 0.002020423627422133}, {"caption": "\\setcitestyle{}", "snippet": "\\setcitestyle{$1}", "meta": "natbib-cmd", "score": 0.0015840652870152204}, {"caption": "\\citeyearpar{}", "snippet": "\\citeyearpar{$1}", "meta": "natbib-cmd", "score": 0.001877888310324327}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "natbib-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "natbib-cmd", "score": 0.006776001543888959}, {"caption": "\\newblock", "snippet": "\\newblock", "meta": "natbib-cmd", "score": 0.03684301726876973}, {"caption": "\\newblock{}", "snippet": "\\newblock{$1}", "meta": "natbib-cmd", "score": 0.03684301726876973}, {"caption": "\\bibnumfmt", "snippet": "\\bibnumfmt", "meta": "natbib-cmd", "score": 0.000353353600267394}, {"caption": "\\citeyear{}", "snippet": "\\citeyear{$1}", "meta": "natbib-cmd", "score": 0.01091041305836494}, {"caption": "\\citeauthor{}", "snippet": "\\citeauthor{$1}", "meta": "natbib-cmd", "score": 0.01359248786373484}], "url": [{"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "url-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "url-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "url-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "url-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "url-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "url-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "url-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "url-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "url-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "url-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "url-cmd", "score": 3.7048287721105874e-05}], "fontenc": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fontenc-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fontenc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fontenc-cmd", "score": 0.021170869458413965}], "tikz": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-cmd", "score": 0.2864294797053033}], "fancyhdr": [{"caption": "\\lhead{}", "snippet": "\\lhead{$1}", "meta": "fancyhdr-cmd", "score": 0.05268978171228714}, {"caption": "\\chaptermark", "snippet": "\\chaptermark", "meta": "fancyhdr-cmd", "score": 0.005924520024686584}, {"caption": "\\chaptermark{}", "snippet": "\\chaptermark{$1}", "meta": "fancyhdr-cmd", "score": 0.005924520024686584}, {"caption": "\\fancypagestyle{}{}", "snippet": "\\fancypagestyle{$1}{$2}", "meta": "fancyhdr-cmd", "score": 0.009430919590937878}, {"caption": "\\footrule", "snippet": "\\footrule", "meta": "fancyhdr-cmd", "score": 0.0010032754348913366}, {"caption": "\\footrule{}", "snippet": "\\footrule{$1}", "meta": "fancyhdr-cmd", "score": 0.0010032754348913366}, {"caption": "\\fancyfoot[]{}", "snippet": "\\fancyfoot[$1]{$2}", "meta": "fancyhdr-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfoot{}", "snippet": "\\fancyfoot{$1}", "meta": "fancyhdr-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfootoffset[]{}", "snippet": "\\fancyfootoffset[$1]{$2}", "meta": "fancyhdr-cmd", "score": 0.0015373246231684555}, {"caption": "\\fancyfootoffset{}", "snippet": "\\fancyfootoffset{$1}", "meta": "fancyhdr-cmd", "score": 0.0015373246231684555}, {"caption": "\\footruleskip", "snippet": "\\footruleskip", "meta": "fancyhdr-cmd", "score": 0.000830117957327721}, {"caption": "\\fancyheadoffset[]{}", "snippet": "\\fancyheadoffset[$1]{$2}", "meta": "fancyhdr-cmd", "score": 0.0016786568695309166}, {"caption": "\\fancyheadoffset{}", "snippet": "\\fancyheadoffset{$1}", "meta": "fancyhdr-cmd", "score": 0.0016786568695309166}, {"caption": "\\iffloatpage{}{}", "snippet": "\\iffloatpage{$1}{$2}", "meta": "fancyhdr-cmd", "score": 6.606286310833368e-05}, {"caption": "\\cfoot{}", "snippet": "\\cfoot{$1}", "meta": "fancyhdr-cmd", "score": 0.013411641301057813}, {"caption": "\\subsectionmark", "snippet": "\\subsectionmark", "meta": "fancyhdr-cmd", "score": 3.1153423008593836e-05}, {"caption": "\\footrulewidth", "snippet": "\\footrulewidth", "meta": "fancyhdr-cmd", "score": 0.011424740897486949}, {"caption": "\\fancyhfoffset[]{}", "snippet": "\\fancyhfoffset[$1]{$2}", "meta": "fancyhdr-cmd", "score": 3.741978601121172e-05}, {"caption": "\\rhead{}", "snippet": "\\rhead{$1}", "meta": "fancyhdr-cmd", "score": 0.022782817416731292}, {"caption": "\\fancyplain{}{}", "snippet": "\\fancyplain{$1}{$2}", "meta": "fancyhdr-cmd", "score": 0.007402339896386138}, {"caption": "\\rfoot{}", "snippet": "\\rfoot{$1}", "meta": "fancyhdr-cmd", "score": 0.013393817825547868}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fancyhdr-cmd", "score": 0.00530510025314411}, {"caption": "\\plainheadrulewidth", "snippet": "\\plainheadrulewidth", "meta": "fancyhdr-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\baselinestretch", "snippet": "\\baselinestretch", "meta": "fancyhdr-cmd", "score": 0.03225350148161425}, {"caption": "\\lfoot{}", "snippet": "\\lfoot{$1}", "meta": "fancyhdr-cmd", "score": 0.00789399846642229}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "fancyhdr-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "fancyhdr-cmd", "score": 0.006776001543888959}, {"caption": "\\fancyhf{}", "snippet": "\\fancyhf{$1}", "meta": "fancyhdr-cmd", "score": 0.02314618933449356}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "fancyhdr-cmd", "score": 0.005008938879210868}, {"caption": "\\fancyhead[]{}", "snippet": "\\fancyhead[$1]{$2}", "meta": "fancyhdr-cmd", "score": 0.039101068064744296}, {"caption": "\\fancyhead{}", "snippet": "\\fancyhead{$1}", "meta": "fancyhdr-cmd", "score": 0.039101068064744296}, {"caption": "\\nouppercase{}", "snippet": "\\nouppercase{$1}", "meta": "fancyhdr-cmd", "score": 0.006416387071584083}, {"caption": "\\nouppercase", "snippet": "\\nouppercase", "meta": "fancyhdr-cmd", "score": 0.006416387071584083}, {"caption": "\\headrule", "snippet": "\\headrule", "meta": "fancyhdr-cmd", "score": 0.0008327432627715623}, {"caption": "\\headrule{}", "snippet": "\\headrule{$1}", "meta": "fancyhdr-cmd", "score": 0.0008327432627715623}, {"caption": "\\chead{}", "snippet": "\\chead{$1}", "meta": "fancyhdr-cmd", "score": 0.00755042164734884}, {"caption": "\\headrulewidth", "snippet": "\\headrulewidth", "meta": "fancyhdr-cmd", "score": 0.02268137935335823}], "booktabs": [{"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "booktabs-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "booktabs-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "booktabs-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "booktabs-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "booktabs-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "booktabs-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "booktabs-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "booktabs-cmd", "score": 0.059857788139528495}], "amsfonts": [{"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "amsfonts-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "amsfonts-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "amsfonts-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "amsfonts-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "amsfonts-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "amsfonts-cmd", "score": 0.0006671850995492977}], "float": [{"caption": "\\listof{}{}", "snippet": "\\listof{$1}{$2}", "meta": "float-cmd", "score": 0.0009837365348002915}, {"caption": "\\floatplacement{}{}", "snippet": "\\floatplacement{$1}{$2}", "meta": "float-cmd", "score": 0.0005815474978918903}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "float-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatstyle{}", "snippet": "\\floatstyle{$1}", "meta": "float-cmd", "score": 0.0015470917047414941}, {"caption": "\\floatname{}{}", "snippet": "\\floatname{$1}{$2}", "meta": "float-cmd", "score": 0.0011934321931750752}, {"caption": "\\csname", "snippet": "\\csname", "meta": "float-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "float-cmd", "score": 1.2569477427490174}, {"caption": "\\newfloat{}{}{}", "snippet": "\\newfloat{$1}{$2}{$3}", "meta": "float-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat", "snippet": "\\newfloat", "meta": "float-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat{}", "snippet": "\\newfloat{$1}", "meta": "float-cmd", "score": 0.0012745874472536625}], "amsthm": [{"caption": "\\swapnumbers", "snippet": "\\swapnumbers", "meta": "amsthm-cmd", "score": 0.0002908376412221364}, {"caption": "\\qedhere", "snippet": "\\qedhere", "meta": "amsthm-cmd", "score": 0.0001608548097938035}, {"caption": "\\qed", "snippet": "\\qed", "meta": "amsthm-cmd", "score": 0.0014240748825867814}, {"caption": "\\qed{}", "snippet": "\\qed{$1}", "meta": "amsthm-cmd", "score": 0.0014240748825867814}, {"caption": "\\newtheoremstyle{}", "snippet": "\\newtheoremstyle{$1}", "meta": "amsthm-cmd", "score": 0.004259886909451789}, {"caption": "\\newtheoremstyle{}{}{}", "snippet": "\\newtheoremstyle{$1}{$2}{$3}", "meta": "amsthm-cmd", "score": 0.004259886909451789}, {"caption": "\\newtheoremstyle{}{}{}{}", "snippet": "\\newtheoremstyle{$1}{$2}{$3}{$4}", "meta": "amsthm-cmd", "score": 0.004259886909451789}, {"caption": "\\theoremstyle{}", "snippet": "\\theoremstyle{$1}", "meta": "amsthm-cmd", "score": 0.02533412165007986}, {"caption": "\\proofname", "snippet": "\\proofname", "meta": "amsthm-cmd", "score": 0.00021208362094925234}, {"caption": "\\pushQED{}", "snippet": "\\pushQED{$1}", "meta": "amsthm-cmd", "score": 0.00019346981338869148}, {"caption": "\\qedsymbol", "snippet": "\\qedsymbol", "meta": "amsthm-cmd", "score": 0.0022671784428571723}, {"caption": "\\qedsymbol{}", "snippet": "\\qedsymbol{$1}", "meta": "amsthm-cmd", "score": 0.0022671784428571723}, {"caption": "\\popQED", "snippet": "\\popQED", "meta": "amsthm-cmd", "score": 9.673490669434574e-05}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "amsthm-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "amsthm-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "amsthm-cmd", "score": 0.215689795055434}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amsthm-cmd", "score": 0.0063276692758974925}], "caption": [{"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "caption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "caption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionof{}{}", "snippet": "\\captionof{$1}{$2}", "meta": "caption-cmd", "score": 0.018348594199161503}, {"caption": "\\string", "snippet": "\\string", "meta": "caption-cmd", "score": 0.001042697111754002}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "caption-cmd", "score": 0.047007158741781095}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "caption-cmd", "score": 0.00530510025314411}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "caption-cmd", "score": 0.0030745841706804776}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "caption-cmd", "score": 0.422097569591803}, {"caption": "\\csname", "snippet": "\\csname", "meta": "caption-cmd", "score": 0.008565354665444157}, {"caption": "\\hspace{}", "snippet": "\\hspace{$1}", "meta": "caption-cmd", "score": 0.3147206476372336}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "caption-cmd", "score": 1.2569477427490174}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "caption-cmd", "score": 1.897791904799601}, {"caption": "\\ContinuedFloat", "snippet": "\\ContinuedFloat", "meta": "caption-cmd", "score": 5.806935368083486e-05}, {"caption": "\\noindent", "snippet": "\\noindent", "meta": "caption-cmd", "score": 0.42355747798114207}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "caption-cmd", "score": 0.00037306820619479756}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "caption-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "caption-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "caption-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "caption-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "caption-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "caption-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "caption-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "caption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "caption-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "caption-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "caption-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "caption-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "caption-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "caption-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "caption-cmd", "score": 0.021473212893597875}], "ifthen": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "ifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "ifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "ifthen-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "ifthen-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "ifthen-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "ifthen-cmd", "score": 0.0018957469739775527}], "setspace": [{"caption": "\\setstretch{}", "snippet": "\\setstretch{$1}", "meta": "setspace-cmd", "score": 0.019634763572332112}, {"caption": "\\onehalfspacing", "snippet": "\\onehalfspacing", "meta": "setspace-cmd", "score": 0.010655415521079565}, {"caption": "\\singlespacing", "snippet": "\\singlespacing", "meta": "setspace-cmd", "score": 0.008351544612280968}, {"caption": "\\doublespacing", "snippet": "\\doublespacing", "meta": "setspace-cmd", "score": 0.007835428951987135}, {"caption": "\\baselinestretch", "snippet": "\\baselinestretch", "meta": "setspace-cmd", "score": 0.03225350148161425}], "multirow": [{"caption": "\\multirow{}{}{}", "snippet": "\\multirow{$1}{$2}{$3}", "meta": "multirow-cmd", "score": 0.07525389638751734}, {"caption": "\\multirow{}[]{}{}", "snippet": "\\multirow{$1}[$2]{$3}{$4}", "meta": "multirow-cmd", "score": 0.07525389638751734}], "array": [{"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "array-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "array-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "array-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "array-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "array-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "array-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "array-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "array-cmd", "score": 0.018615449342361392}], "titlesec": [{"caption": "\\titleclass{}{}[]", "snippet": "\\titleclass{$1}{$2}[$3]", "meta": "titlesec-cmd", "score": 0.00028979763314974667}, {"caption": "\\titlelabel{}", "snippet": "\\titlelabel{$1}", "meta": "titlesec-cmd", "score": 6.40387839367932e-06}, {"caption": "\\thetitle", "snippet": "\\thetitle", "meta": "titlesec-cmd", "score": 0.0015531478302713473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "titlesec-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "titlesec-cmd", "score": 0.021170869458413965}, {"caption": "\\titleformat{}{}{}{}{}[]", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}[$6]", "meta": "titlesec-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}[]{}{}{}{}", "snippet": "\\titleformat{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "titlesec-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}", "snippet": "\\titleformat{$1}{$2}", "meta": "titlesec-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}{}{}{}", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}", "meta": "titlesec-cmd", "score": 0.03475519439740096}, {"caption": "\\titlespacing{}{}{}{}", "snippet": "\\titlespacing{$1}{$2}{$3}{$4}", "meta": "titlesec-cmd", "score": 0.023062744385192156}, {"caption": "\\markboth{}{}", "snippet": "\\markboth{$1}{$2}", "meta": "titlesec-cmd", "score": 0.038323601301945065}, {"caption": "\\markboth{}", "snippet": "\\markboth{$1}", "meta": "titlesec-cmd", "score": 0.038323601301945065}, {"caption": "\\markright{}", "snippet": "\\markright{$1}", "meta": "titlesec-cmd", "score": 0.007138622674767024}, {"caption": "\\markright{}{}", "snippet": "\\markright{$1}{$2}", "meta": "titlesec-cmd", "score": 0.007138622674767024}, {"caption": "\\filleft", "snippet": "\\filleft", "meta": "titlesec-cmd", "score": 7.959989906732799e-05}, {"caption": "\\filcenter", "snippet": "\\filcenter", "meta": "titlesec-cmd", "score": 0.0004835660211260246}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "titlesec-cmd", "score": 0.2253056071787701}, {"caption": "\\cleardoublepage", "snippet": "\\cleardoublepage", "meta": "titlesec-cmd", "score": 0.044016804142963585}, {"caption": "\\csname", "snippet": "\\csname", "meta": "titlesec-cmd", "score": 0.008565354665444157}, {"caption": "\\chaptertitlename", "snippet": "\\chaptertitlename", "meta": "titlesec-cmd", "score": 0.0016985007766926272}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "titlesec-cmd", "score": 0.3277033727934986}, {"caption": "\\filright", "snippet": "\\filright", "meta": "titlesec-cmd", "score": 7.959989906732799e-05}, {"caption": "\\titlerule", "snippet": "\\titlerule", "meta": "titlesec-cmd", "score": 0.019273712561461216}, {"caption": "\\titlerule[]{}", "snippet": "\\titlerule[$1]{$2}", "meta": "titlesec-cmd", "score": 0.019273712561461216}], "multicol": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "multicol-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "multicol-cmd", "score": 0.021170869458413965}, {"caption": "\\raggedcolumns", "snippet": "\\raggedcolumns", "meta": "multicol-cmd", "score": 0.00027461965178228156}, {"caption": "\\columnbreak", "snippet": "\\columnbreak", "meta": "multicol-cmd", "score": 0.002609610141555795}, {"caption": "\\columnseprulecolor{}", "snippet": "\\columnseprulecolor{$1}", "meta": "multicol-cmd", "score": 1.3314892207625771e-05}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "multicol-cmd", "score": 0.1789117552185788}], "listings": [{"caption": "\\vskip", "snippet": "\\vskip", "meta": "listings-cmd", "score": 0.05143052892347224}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "listings-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "listings-cmd", "score": 0.021170869458413965}, {"caption": "\\do", "snippet": "\\do", "meta": "listings-cmd", "score": 0.009278344180101056}, {"caption": "\\thelstlisting", "snippet": "\\thelstlisting", "meta": "listings-cmd", "score": 0.00012774128088872144}, {"caption": "\\lstinputlisting[]{}", "snippet": "\\lstinputlisting[$1]{$2}", "meta": "listings-cmd", "score": 0.011660477607086044}, {"caption": "\\lstinputlisting{}", "snippet": "\\lstinputlisting{$1}", "meta": "listings-cmd", "score": 0.011660477607086044}, {"caption": "\\space", "snippet": "\\space", "meta": "listings-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "listings-cmd", "score": 0.008565354665444157}, {"caption": "\\lstinline", "snippet": "\\lstinline", "meta": "listings-cmd", "score": 0.005972262850694285}, {"caption": "\\lstinline{}", "snippet": "\\lstinline{$1}", "meta": "listings-cmd", "score": 0.005972262850694285}, {"caption": "\\lstlistoflistings", "snippet": "\\lstlistoflistings", "meta": "listings-cmd", "score": 0.005279080363360602}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "listings-cmd", "score": 0.00037306820619479756}], "blindtext": [{"caption": "\\glqq", "snippet": "\\glqq", "meta": "blindtext-cmd", "score": 0.0039133256714254504}, {"caption": "\\glqq{}", "snippet": "\\glqq{$1}", "meta": "blindtext-cmd", "score": 0.0039133256714254504}, {"caption": "\\blindtext", "snippet": "\\blindtext", "meta": "blindtext-cmd", "score": 0.05782040856823667}, {"caption": "\\blindtext[]", "snippet": "\\blindtext[$1]", "meta": "blindtext-cmd", "score": 0.05782040856823667}, {"caption": "\\Blindtext", "snippet": "\\Blindtext", "meta": "blindtext-cmd", "score": 0.006384906903938044}, {"caption": "\\grqq", "snippet": "\\grqq", "meta": "blindtext-cmd", "score": 0.006659522189248266}, {"caption": "\\grqq{}", "snippet": "\\grqq{$1}", "meta": "blindtext-cmd", "score": 0.006659522189248266}, {"caption": "\\blinddocument", "snippet": "\\blinddocument", "meta": "blindtext-cmd", "score": 0.00011480988129172825}, {"caption": "\\xspace", "snippet": "\\xspace", "meta": "blindtext-cmd", "score": 0.07560370351316588}], "enumitem": [{"caption": "\\newlist{}{}{}", "snippet": "\\newlist{$1}{$2}{$3}", "meta": "enumitem-cmd", "score": 0.0007266225924074459}, {"caption": "\\setlist[]{}", "snippet": "\\setlist[$1]{$2}", "meta": "enumitem-cmd", "score": 0.010895384475728338}, {"caption": "\\setlist{}", "snippet": "\\setlist{$1}", "meta": "enumitem-cmd", "score": 0.010895384475728338}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "enumitem-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "enumitem-cmd", "score": 0.021170869458413965}, {"caption": "\\setlistdepth{}", "snippet": "\\setlistdepth{$1}", "meta": "enumitem-cmd", "score": 0.0001113322912630871}, {"caption": "\\setenumerate[]{}", "snippet": "\\setenumerate[$1]{$2}", "meta": "enumitem-cmd", "score": 7.437178301071255e-05}, {"caption": "\\setenumerate{}", "snippet": "\\setenumerate{$1}", "meta": "enumitem-cmd", "score": 7.437178301071255e-05}, {"caption": "\\renewlist{}{}{}", "snippet": "\\renewlist{$1}{$2}{$3}", "meta": "enumitem-cmd", "score": 0.0001113322912630871}, {"caption": "\\descriptionlabel{}", "snippet": "\\descriptionlabel{$1}", "meta": "enumitem-cmd", "score": 7.678089052626698e-06}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "enumitem-cmd", "score": 0.00530510025314411}, {"caption": "\\setitemize[]{}", "snippet": "\\setitemize[$1]{$2}", "meta": "enumitem-cmd", "score": 0.0019580640711971786}, {"caption": "\\csname", "snippet": "\\csname", "meta": "enumitem-cmd", "score": 0.008565354665444157}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "enumitem-cmd", "score": 0.01590723355124104}, {"caption": "\\makelabel", "snippet": "\\makelabel", "meta": "enumitem-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel{}", "snippet": "\\makelabel{$1}", "meta": "enumitem-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel[]{}", "snippet": "\\makelabel[$1]{$2}", "meta": "enumitem-cmd", "score": 5.739925426740175e-05}], "times": [{"caption": "\\rmdefault", "snippet": "\\rmdefault", "meta": "times-cmd", "score": 0.0012870877747432935}, {"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "times-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "times-cmd", "score": 0.008427383388519996}, {"caption": "\\ttdefault", "snippet": "\\ttdefault", "meta": "times-cmd", "score": 0.0011733254149332488}, {"caption": "\\ttdefault{}", "snippet": "\\ttdefault{$1}", "meta": "times-cmd", "score": 0.0011733254149332488}], "subcaption": [{"caption": "\\subref{}", "snippet": "\\subref{$1}", "meta": "subcaption-cmd", "score": 0.007192033516871399}, {"caption": "\\subcaptionbox{}{}", "snippet": "\\subcaptionbox{$1}{$2}", "meta": "subcaption-cmd", "score": 0.0008634329663023698}, {"caption": "\\newsubfloat{}", "snippet": "\\newsubfloat{$1}", "meta": "subcaption-cmd", "score": 0.000615805121082521}, {"caption": "\\subcaption{}", "snippet": "\\subcaption{$1}", "meta": "subcaption-cmd", "score": 0.006820005741581297}, {"caption": "\\subcaption[]{}", "snippet": "\\subcaption[$1]{$2}", "meta": "subcaption-cmd", "score": 0.006820005741581297}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "subcaption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "subcaption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionof{}{}", "snippet": "\\captionof{$1}{$2}", "meta": "subcaption-cmd", "score": 0.018348594199161503}, {"caption": "\\string", "snippet": "\\string", "meta": "subcaption-cmd", "score": 0.001042697111754002}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "subcaption-cmd", "score": 0.047007158741781095}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "subcaption-cmd", "score": 0.00530510025314411}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "subcaption-cmd", "score": 0.0030745841706804776}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "subcaption-cmd", "score": 0.422097569591803}, {"caption": "\\csname", "snippet": "\\csname", "meta": "subcaption-cmd", "score": 0.008565354665444157}, {"caption": "\\hspace{}", "snippet": "\\hspace{$1}", "meta": "subcaption-cmd", "score": 0.3147206476372336}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "subcaption-cmd", "score": 1.2569477427490174}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "subcaption-cmd", "score": 1.897791904799601}, {"caption": "\\ContinuedFloat", "snippet": "\\ContinuedFloat", "meta": "subcaption-cmd", "score": 5.806935368083486e-05}, {"caption": "\\noindent", "snippet": "\\noindent", "meta": "subcaption-cmd", "score": 0.42355747798114207}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "subcaption-cmd", "score": 0.00037306820619479756}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "subcaption-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "subcaption-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "subcaption-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "subcaption-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "subcaption-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "subcaption-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "subcaption-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "subcaption-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "subcaption-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "subcaption-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "subcaption-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "subcaption-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "subcaption-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "subcaption-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "subcaption-cmd", "score": 0.021473212893597875}], "bm": [{"caption": "\\bm{}", "snippet": "\\bm{$1}", "meta": "bm-cmd", "score": 0.14733018077819282}, {"caption": "\\bm", "snippet": "\\bm", "meta": "bm-cmd", "score": 0.14733018077819282}], "fontspec": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "fontspec-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "fontspec-cmd", "score": 0.2864294797053033}], "subfigure": [{"caption": "\\subref{}", "snippet": "\\subref{$1}", "meta": "subfigure-cmd", "score": 0.007192033516871399}, {"caption": "\\subfigure[]{}", "snippet": "\\subfigure[$1]{$2}", "meta": "subfigure-cmd", "score": 0.037856842641104005}], "calc": [{"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "calc-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "calc-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "calc-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "calc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "calc-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "calc-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "calc-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "calc-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "calc-cmd", "score": 0.028955796305270766}], "tabularx": [{"caption": "\\let", "snippet": "\\let", "meta": "tabularx-cmd", "score": 0.03789745970461662}, {"caption": "\\write", "snippet": "\\write", "meta": "tabularx-cmd", "score": 0.0008038857295393196}, {"caption": "\\tabularxcolumn[]{}", "snippet": "\\tabularxcolumn[$1]{$2}", "meta": "tabularx-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularxcolumn", "snippet": "\\tabularxcolumn", "meta": "tabularx-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularx{}{}", "snippet": "\\tabularx{$1}{$2}", "meta": "tabularx-cmd", "score": 0.0005861357565780464}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "tabularx-cmd", "score": 0.014532521139459619}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "tabularx-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "tabularx-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "tabularx-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "tabularx-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "tabularx-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tabularx-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "tabularx-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "tabularx-cmd", "score": 0.018615449342361392}], "algorithm": [{"caption": "\\listalgorithmname", "snippet": "\\listalgorithmname", "meta": "algorithm-cmd", "score": 0.00022490402516652368}, {"caption": "\\listofalgorithms", "snippet": "\\listofalgorithms", "meta": "algorithm-cmd", "score": 0.0012576983422794912}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algorithm-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algorithm-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algorithm-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algorithm-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algorithm-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algorithm-cmd", "score": 0.0018957469739775527}, {"caption": "\\listof{}{}", "snippet": "\\listof{$1}{$2}", "meta": "algorithm-cmd", "score": 0.0009837365348002915}, {"caption": "\\floatplacement{}{}", "snippet": "\\floatplacement{$1}{$2}", "meta": "algorithm-cmd", "score": 0.0005815474978918903}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "algorithm-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatstyle{}", "snippet": "\\floatstyle{$1}", "meta": "algorithm-cmd", "score": 0.0015470917047414941}, {"caption": "\\floatname{}{}", "snippet": "\\floatname{$1}{$2}", "meta": "algorithm-cmd", "score": 0.0011934321931750752}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algorithm-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "algorithm-cmd", "score": 1.2569477427490174}, {"caption": "\\newfloat{}{}{}", "snippet": "\\newfloat{$1}{$2}{$3}", "meta": "algorithm-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat", "snippet": "\\newfloat", "meta": "algorithm-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat{}", "snippet": "\\newfloat{$1}", "meta": "algorithm-cmd", "score": 0.0012745874472536625}], "biblatex": [{"caption": "\\textcite{}", "snippet": "\\textcite{$1}", "meta": "biblatex-cmd", "score": 0.0071363824748767206}, {"caption": "\\iffieldundef{}{}{}", "snippet": "\\iffieldundef{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\list{}{}", "snippet": "\\list{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00046570666700199663}, {"caption": "\\list{}", "snippet": "\\list{$1}", "meta": "biblatex-cmd", "score": 0.00046570666700199663}, {"caption": "\\list", "snippet": "\\list", "meta": "biblatex-cmd", "score": 0.00046570666700199663}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\printbibliography", "snippet": "\\printbibliography", "meta": "biblatex-cmd", "score": 0.028923378512954446}, {"caption": "\\printbibliography[]", "snippet": "\\printbibliography[$1]", "meta": "biblatex-cmd", "score": 0.028923378512954446}, {"caption": "\\keyword{}", "snippet": "\\keyword{$1}", "meta": "biblatex-cmd", "score": 0.0056978719547823445}, {"caption": "\\nocite{}", "snippet": "\\nocite{$1}", "meta": "biblatex-cmd", "score": 0.04990693820960752}, {"caption": "\\do", "snippet": "\\do", "meta": "biblatex-cmd", "score": 0.009278344180101056}, {"caption": "\\mkbibquote{}", "snippet": "\\mkbibquote{$1}", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\addabbrvspace", "snippet": "\\addabbrvspace", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\AtEveryBibitem{}", "snippet": "\\AtEveryBibitem{$1}", "meta": "biblatex-cmd", "score": 0.0006862523808353773}, {"caption": "\\mkbibemph{}", "snippet": "\\mkbibemph{$1}", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\DeclareFieldFormat{}{}", "snippet": "\\DeclareFieldFormat{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00028207109055618685}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "biblatex-cmd", "score": 0.2659628337907604}, {"caption": "\\enquote{}", "snippet": "\\enquote{$1}", "meta": "biblatex-cmd", "score": 0.0077432730806830915}, {"caption": "\\bibopenbracket", "snippet": "\\bibopenbracket", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\newbibmacro{}[]{}", "snippet": "\\newbibmacro{$1}[$2]{$3}", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\addbibresource{}", "snippet": "\\addbibresource{$1}", "meta": "biblatex-cmd", "score": 0.033545778388159704}, {"caption": "\\defbibheading{}{}", "snippet": "\\defbibheading{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00013423526504458629}, {"caption": "\\DeclareNameAlias{}{}", "snippet": "\\DeclareNameAlias{$1}{$2}", "meta": "biblatex-cmd", "score": 0.0003596306478652252}, {"caption": "\\bibcloseparen", "snippet": "\\bibcloseparen", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\renewbibmacro{}{}", "snippet": "\\renewbibmacro{$1}{$2}", "meta": "biblatex-cmd", "score": 9.70299207241043e-05}, {"caption": "\\bibclosebracket", "snippet": "\\bibclosebracket", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\item", "snippet": "\\item", "meta": "biblatex-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "biblatex-cmd", "score": 3.800886892251021}, {"caption": "\\parentext", "snippet": "\\parentext", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "biblatex-cmd", "score": 2.341195220791228}, {"caption": "\\addspace", "snippet": "\\addspace", "meta": "biblatex-cmd", "score": 0.0002657609533376918}, {"caption": "\\ifentrytype{}{}{}", "snippet": "\\ifentrytype{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 8.342875497183237e-05}, {"caption": "\\addslash", "snippet": "\\addslash", "meta": "biblatex-cmd", "score": 0.0002657609533376918}, {"caption": "\\DefineBibliographyStrings{}{}", "snippet": "\\DefineBibliographyStrings{$1}{$2}", "meta": "biblatex-cmd", "score": 0.001537977148659816}, {"caption": "\\section{}", "snippet": "\\section{$1}", "meta": "biblatex-cmd", "score": 3.0952612541683835}, {"caption": "\\newblockpunct", "snippet": "\\newblockpunct", "meta": "biblatex-cmd", "score": 0.0001328804766688459}, {"caption": "\\defbibfilter{}{}", "snippet": "\\defbibfilter{$1}{$2}", "meta": "biblatex-cmd", "score": 0.0005203319717980072}, {"caption": "\\parencite{}", "snippet": "\\parencite{$1}", "meta": "biblatex-cmd", "score": 0.0447747090014577}, {"caption": "\\parencite[]{}", "snippet": "\\parencite[$1]{$2}", "meta": "biblatex-cmd", "score": 0.0447747090014577}, {"caption": "\\midsentence", "snippet": "\\midsentence", "meta": "biblatex-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "biblatex-cmd", "score": 0.0004995635515943437}, {"caption": "\\DeclareSourcemap{}", "snippet": "\\DeclareSourcemap{$1}", "meta": "biblatex-cmd", "score": 0.0005203319717980072}, {"caption": "\\AtBeginBibliography{}", "snippet": "\\AtBeginBibliography{$1}", "meta": "biblatex-cmd", "score": 0.0004668773504581073}, {"caption": "\\AtEveryCite{}", "snippet": "\\AtEveryCite{$1}", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\DeclareLanguageMapping{}{}", "snippet": "\\DeclareLanguageMapping{$1}{$2}", "meta": "biblatex-cmd", "score": 0.000703956971675325}, {"caption": "\\addtocategory{}{}", "snippet": "\\addtocategory{$1}{$2}", "meta": "biblatex-cmd", "score": 0.008238589553468446}, {"caption": "\\DeclareBibliographyCategory{}", "snippet": "\\DeclareBibliographyCategory{$1}", "meta": "biblatex-cmd", "score": 0.0010298236941835557}, {"caption": "\\break", "snippet": "\\break", "meta": "biblatex-cmd", "score": 0.016352452390960115}, {"caption": "\\break{}", "snippet": "\\break{$1}", "meta": "biblatex-cmd", "score": 0.016352452390960115}, {"caption": "\\break{}{}", "snippet": "\\break{$1}{$2}", "meta": "biblatex-cmd", "score": 0.016352452390960115}, {"caption": "\\bibopenparen", "snippet": "\\bibopenparen", "meta": "biblatex-cmd", "score": 0.0005125772067631753}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}, {"caption": "\\name{}{}", "snippet": "\\name{$1}{$2}", "meta": "biblatex-cmd", "score": 0.1236289144754329}, {"caption": "\\name", "snippet": "\\name", "meta": "biblatex-cmd", "score": 0.1236289144754329}, {"caption": "\\name{}", "snippet": "\\name{$1}", "meta": "biblatex-cmd", "score": 0.1236289144754329}, {"caption": "\\ExecuteBibliographyOptions{}", "snippet": "\\ExecuteBibliographyOptions{$1}", "meta": "biblatex-cmd", "score": 4.841482597532878e-05}, {"caption": "\\usebibmacro{}{}", "snippet": "\\usebibmacro{$1}{$2}", "meta": "biblatex-cmd", "score": 9.682965195065755e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00037306820619479756}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "biblatex-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "biblatex-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "biblatex-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "biblatex-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "biblatex-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "biblatex-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "biblatex-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "biblatex-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "biblatex-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "biblatex-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "biblatex-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\do", "snippet": "\\do", "meta": "biblatex-cmd", "score": 0.009278344180101056}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "biblatex-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "biblatex-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "biblatex-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "biblatex-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "biblatex-cmd", "score": 0.0018957469739775527}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "biblatex-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "biblatex-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "biblatex-cmd", "score": 0.021170869458413965}, {"caption": "\\empty", "snippet": "\\empty", "meta": "biblatex-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "biblatex-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "biblatex-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "biblatex-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "biblatex-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "biblatex-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "biblatex-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "biblatex-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "biblatex-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "biblatex-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "biblatex-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "biblatex-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "biblatex-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "biblatex-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "biblatex-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "biblatex-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "biblatex-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "biblatex-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "biblatex-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "biblatex-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "biblatex-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-cmd", "score": 0.008565354665444157}], "microtype": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "microtype-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "microtype-cmd", "score": 0.021170869458413965}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "microtype-cmd", "score": 0.00530510025314411}, {"caption": "\\lsstyle", "snippet": "\\lsstyle", "meta": "microtype-cmd", "score": 0.0023367519914345774}, {"caption": "\\space", "snippet": "\\space", "meta": "microtype-cmd", "score": 0.023010789853665694}, {"caption": "\\DisableLigatures[]{}", "snippet": "\\DisableLigatures[$1]{$2}", "meta": "microtype-cmd", "score": 0.0009805246614299932}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "microtype-cmd", "score": 0.00037306820619479756}], "etoolbox": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "etoolbox-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "etoolbox-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "etoolbox-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "etoolbox-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "etoolbox-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "etoolbox-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "etoolbox-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "etoolbox-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "etoolbox-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "etoolbox-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "etoolbox-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "etoolbox-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "etoolbox-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "etoolbox-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "etoolbox-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "etoolbox-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "etoolbox-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "etoolbox-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "etoolbox-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "etoolbox-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "etoolbox-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "etoolbox-cmd", "score": 0.008565354665444157}], "longtable": [{"caption": "\\endhead", "snippet": "\\endhead", "meta": "longtable-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "longtable-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "longtable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "longtable-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "longtable-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "longtable-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "longtable-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "longtable-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "longtable-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "longtable-cmd", "score": 0.0313525090421608}], "mathtools": [{"caption": "\\xleftrightarrow[][]{}", "snippet": "\\xleftrightarrow[$1][$2]{$3}", "meta": "mathtools-cmd", "score": 4.015559489911509e-05}, {"caption": "\\vcentcolon", "snippet": "\\vcentcolon", "meta": "mathtools-cmd", "score": 0.00021361943526711615}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "mathtools-cmd", "score": 0.0016148076375871775}, {"caption": "\\coloneqq", "snippet": "\\coloneqq", "meta": "mathtools-cmd", "score": 0.0014407293323958122}, {"caption": "\\mathclap{}", "snippet": "\\mathclap{$1}", "meta": "mathtools-cmd", "score": 7.84378567451772e-05}, {"caption": "\\adjustlimits", "snippet": "\\adjustlimits", "meta": "mathtools-cmd", "score": 0.0005307066890271085}, {"caption": "\\MoveEqLeft", "snippet": "\\MoveEqLeft", "meta": "mathtools-cmd", "score": 5.343949980628182e-05}, {"caption": "\\mathrlap{}", "snippet": "\\mathrlap{$1}", "meta": "mathtools-cmd", "score": 0.0003112817211637952}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "mathtools-cmd", "score": 0.051980653969641216}, {"caption": "\\xhookrightarrow{}", "snippet": "\\xhookrightarrow{$1}", "meta": "mathtools-cmd", "score": 5.444260823474129e-05}, {"caption": "\\DeclarePairedDelimiter{}{}{}", "snippet": "\\DeclarePairedDelimiter{$1}{$2}{$3}", "meta": "mathtools-cmd", "score": 0.0033916678416372487}, {"caption": "\\DeclarePairedDelimiter", "snippet": "\\DeclarePairedDelimiter", "meta": "mathtools-cmd", "score": 0.0033916678416372487}, {"caption": "\\prescript{}{}{}", "snippet": "\\prescript{$1}{$2}{$3}", "meta": "mathtools-cmd", "score": 8.833369785705982e-06}, {"caption": "\\underbrace{}", "snippet": "\\underbrace{$1}", "meta": "mathtools-cmd", "score": 0.010373780436850907}, {"caption": "\\mathllap{}", "snippet": "\\mathllap{$1}", "meta": "mathtools-cmd", "score": 3.140504277052775e-05}, {"caption": "\\overbrace{}", "snippet": "\\overbrace{$1}", "meta": "mathtools-cmd", "score": 0.0006045704778718376}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "mathtools-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "mathtools-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "mathtools-cmd", "score": 0.18137737738638837}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "mathtools-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "mathtools-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "mathtools-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "mathtools-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mathtools-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mathtools-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "mathtools-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "mathtools-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "mathtools-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "mathtools-cmd", "score": 0.028955796305270766}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mathtools-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mathtools-cmd", "score": 0.021170869458413965}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "mathtools-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "mathtools-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "mathtools-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "mathtools-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "mathtools-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "mathtools-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "mathtools-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "mathtools-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "mathtools-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "mathtools-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "mathtools-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "mathtools-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "mathtools-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "mathtools-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "mathtools-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "mathtools-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "mathtools-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "mathtools-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "mathtools-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "mathtools-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "mathtools-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "mathtools-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "mathtools-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "mathtools-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "mathtools-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "mathtools-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "mathtools-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "mathtools-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "mathtools-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "mathtools-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "mathtools-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "mathtools-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "mathtools-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "mathtools-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "mathtools-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "mathtools-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "mathtools-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "mathtools-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "mathtools-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "mathtools-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "mathtools-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "mathtools-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "mathtools-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "mathtools-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "mathtools-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "mathtools-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "mathtools-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "mathtools-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "mathtools-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "mathtools-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "mathtools-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "mathtools-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "mathtools-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "mathtools-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "mathtools-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "mathtools-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "mathtools-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "mathtools-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "mathtools-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "mathtools-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "mathtools-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "mathtools-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "mathtools-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "mathtools-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "mathtools-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "mathtools-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "mathtools-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "mathtools-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "mathtools-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "mathtools-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "mathtools-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "mathtools-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "mathtools-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "mathtools-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "mathtools-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "mathtools-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "mathtools-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "mathtools-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "mathtools-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "mathtools-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "mathtools-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "mathtools-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "mathtools-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "mathtools-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "mathtools-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "mathtools-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "mathtools-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "mathtools-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "mathtools-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "mathtools-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "mathtools-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "mathtools-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "mathtools-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "mathtools-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "mathtools-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "mathtools-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "mathtools-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "mathtools-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "mathtools-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "mathtools-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "mathtools-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "mathtools-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "mathtools-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "mathtools-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "mathtools-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "mathtools-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "mathtools-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "mathtools-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "mathtools-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "mathtools-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "mathtools-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "mathtools-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "mathtools-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "mathtools-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "mathtools-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "mathtools-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "mathtools-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "mathtools-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "mathtools-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "mathtools-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "mathtools-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "mathtools-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "mathtools-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "mathtools-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "mathtools-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "mathtools-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "mathtools-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "mathtools-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "mathtools-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "mathtools-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "mathtools-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "mathtools-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "mathtools-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "mathtools-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "mathtools-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "mathtools-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "mathtools-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "mathtools-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "mathtools-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "mathtools-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "mathtools-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "mathtools-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "mathtools-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "mathtools-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "mathtools-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "mathtools-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mathtools-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "mathtools-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "mathtools-cmd", "score": 0.0063276692758974925}], "verbatim": [{"caption": "\\endverbatim", "snippet": "\\endverbatim", "meta": "verbatim-cmd", "score": 0.0022216421267780076}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "verbatim-cmd", "score": 0.0072203369120285256}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "verbatim-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "verbatim-cmd", "score": 0.021170869458413965}, {"caption": "\\par", "snippet": "\\par", "meta": "verbatim-cmd", "score": 0.413853376001159}, {"caption": "\\verbatiminput{}", "snippet": "\\verbatiminput{$1}", "meta": "verbatim-cmd", "score": 0.0024547099784948665}, {"caption": "\\verbatiminput", "snippet": "\\verbatiminput", "meta": "verbatim-cmd", "score": 0.0024547099784948665}], "wrapfig": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "wrapfig-cmd", "score": 0.00530510025314411}, {"caption": "\\par", "snippet": "\\par", "meta": "wrapfig-cmd", "score": 0.413853376001159}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "wrapfig-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "wrapfig-cmd", "score": 0.021170869458413965}, {"caption": "\\wrapfigure{}{}", "snippet": "\\wrapfigure{$1}{$2}", "meta": "wrapfig-cmd", "score": 0.0003295435821387379}], "epsfig": [{"caption": "\\epsfbox{}", "snippet": "\\epsfbox{$1}", "meta": "epsfig-cmd", "score": 0.00013712781345832882}, {"caption": "\\psfig{}", "snippet": "\\psfig{$1}", "meta": "epsfig-cmd", "score": 0.0017552046452897515}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "epsfig-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "epsfig-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "epsfig-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "epsfig-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "epsfig-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "epsfig-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "epsfig-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "epsfig-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "epsfig-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epsfig-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "epsfig-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "epsfig-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "epsfig-cmd", "score": 0.004719094298848707}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "epsfig-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epsfig-cmd", "score": 0.008565354665444157}], "cite": [{"caption": "\\citeonline{}", "snippet": "\\citeonline{$1}", "meta": "cite-cmd", "score": 0.014277840409455324}, {"caption": "\\citenum{}", "snippet": "\\citenum{$1}", "meta": "cite-cmd", "score": 0.0027420903627423383}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "cite-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "cite-cmd", "score": 0.021170869458413965}, {"caption": "\\nocite{}", "snippet": "\\nocite{$1}", "meta": "cite-cmd", "score": 0.04990693820960752}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "cite-cmd", "score": 2.341195220791228}], "lipsum": [{"caption": "\\setlipsumdefault{}", "snippet": "\\setlipsumdefault{$1}", "meta": "lipsum-cmd", "score": 0.00024112945034541791}, {"caption": "\\lipsum[]", "snippet": "\\lipsum[$1]", "meta": "lipsum-cmd", "score": 0.0300787181624191}], "algpseudocode": [{"caption": "\\algrenewcommand", "snippet": "\\algrenewcommand", "meta": "algpseudocode-cmd", "score": 0.0019861803661869416}, {"caption": "\\Statex", "snippet": "\\Statex", "meta": "algpseudocode-cmd", "score": 0.008622777195102994}, {"caption": "\\BState{}", "snippet": "\\BState{$1}", "meta": "algpseudocode-cmd", "score": 0.0008685861525307122}, {"caption": "\\BState", "snippet": "\\BState", "meta": "algpseudocode-cmd", "score": 0.0008685861525307122}, {"caption": "\\algloopdefx{}[][]{}", "snippet": "\\algloopdefx{$1}[$2][$3]{$4}", "meta": "algpseudocode-cmd", "score": 0.00025315185701145097}, {"caption": "\\algnewcommand", "snippet": "\\algnewcommand", "meta": "algpseudocode-cmd", "score": 0.0030209395012065327}, {"caption": "\\algnewcommand{}[]{}", "snippet": "\\algnewcommand{$1}[$2]{$3}", "meta": "algpseudocode-cmd", "score": 0.0030209395012065327}, {"caption": "\\Comment{}", "snippet": "\\Comment{$1}", "meta": "algpseudocode-cmd", "score": 0.005178604573219454}, {"caption": "\\algblockdefx{}{}[]", "snippet": "\\algblockdefx{$1}{$2}[$3]", "meta": "algpseudocode-cmd", "score": 0.00025315185701145097}, {"caption": "\\algrenewtext{}{}", "snippet": "\\algrenewtext{$1}{$2}", "meta": "algpseudocode-cmd", "score": 0.0024415580558825975}, {"caption": "\\algrenewtext{}[]{}", "snippet": "\\algrenewtext{$1}[$2]{$3}", "meta": "algpseudocode-cmd", "score": 0.0024415580558825975}, {"caption": "\\algblock{}{}", "snippet": "\\algblock{$1}{$2}", "meta": "algpseudocode-cmd", "score": 0.0007916858220314837}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algpseudocode-cmd", "score": 0.008565354665444157}, {"caption": "\\algdef{}[]{}{}{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "algpseudocode-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}{}[]{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}[$5]{$6}{$7}", "meta": "algpseudocode-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}[]{}", "snippet": "\\algdef{$1}[$2]{$3}[$4]{$5}", "meta": "algpseudocode-cmd", "score": 0.0003102486920966127}, {"caption": "\\algtext{}", "snippet": "\\algtext{$1}", "meta": "algpseudocode-cmd", "score": 0.0005463612015579842}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algpseudocode-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algpseudocode-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algpseudocode-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algpseudocode-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algpseudocode-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algpseudocode-cmd", "score": 0.0018957469739775527}], "textpos": [{"caption": "\\textblockorigin{}{}", "snippet": "\\textblockorigin{$1}{$2}", "meta": "textpos-cmd", "score": 0.016306266556901577}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "textpos-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "textpos-cmd", "score": 0.2864294797053033}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "textpos-cmd", "score": 0.00037306820619479756}], "subfig": [{"caption": "\\subref{}", "snippet": "\\subref{$1}", "meta": "subfig-cmd", "score": 0.007192033516871399}, {"caption": "\\protect", "snippet": "\\protect", "meta": "subfig-cmd", "score": 0.0200686676229443}, {"caption": "\\subfloat[]{}", "snippet": "\\subfloat[$1]{$2}", "meta": "subfig-cmd", "score": 0.0286920437310672}, {"caption": "\\subfloat{}", "snippet": "\\subfloat{$1}", "meta": "subfig-cmd", "score": 0.0286920437310672}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "subfig-cmd", "score": 0.00037306820619479756}], "enumerate": [{"caption": "\\csname", "snippet": "\\csname", "meta": "enumerate-cmd", "score": 0.008565354665444157}, {"caption": "\\makelabel", "snippet": "\\makelabel", "meta": "enumerate-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel{}", "snippet": "\\makelabel{$1}", "meta": "enumerate-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel[]{}", "snippet": "\\makelabel[$1]{$2}", "meta": "enumerate-cmd", "score": 5.739925426740175e-05}], "pdfpages": [{"caption": "\\csname", "snippet": "\\csname", "meta": "pdfpages-cmd", "score": 0.008565354665444157}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "pdfpages-cmd", "score": 0.07503475348393239}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pdfpages-cmd", "score": 1.4595731795525781}, {"caption": "\\includepdf[]{}", "snippet": "\\includepdf[$1]{$2}", "meta": "pdfpages-cmd", "score": 0.023931732745590156}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "pdfpages-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pdfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pdfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "pdfpages-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "pdfpages-cmd", "score": 0.028955796305270766}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pdfpages-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pdfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pdfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "pdfpages-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "pdfpages-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pdfpages-cmd", "score": 0.008565354665444157}, {"caption": "\\AddToShipoutPictureFG{}", "snippet": "\\AddToShipoutPictureFG{$1}", "meta": "pdfpages-cmd", "score": 0.000325977535138643}, {"caption": "\\AddToShipoutPictureBG{}", "snippet": "\\AddToShipoutPictureBG{$1}", "meta": "pdfpages-cmd", "score": 0.0008957666085644653}, {"caption": "\\AtPageUpperLeft{}", "snippet": "\\AtPageUpperLeft{$1}", "meta": "pdfpages-cmd", "score": 0.0003608141410278152}, {"caption": "\\LenToUnit{}", "snippet": "\\LenToUnit{$1}", "meta": "pdfpages-cmd", "score": 0.0007216282820556304}, {"caption": "\\AddToShipoutPicture{}", "snippet": "\\AddToShipoutPicture{$1}", "meta": "pdfpages-cmd", "score": 0.0017658629469099734}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "pdfpages-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "pdfpages-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "pdfpages-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "pdfpages-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "pdfpages-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "pdfpages-cmd", "score": 0.0018957469739775527}], "epstopdf": [{"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\AppendGraphicsExtensions{}", "snippet": "\\AppendGraphicsExtensions{$1}", "meta": "epstopdf-cmd", "score": 7.723677706376668e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "epstopdf-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "epstopdf-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "epstopdf-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "epstopdf-cmd", "score": 0.021170869458413965}, {"caption": "\\epstopdfsetup{}", "snippet": "\\epstopdfsetup{$1}", "meta": "epstopdf-cmd", "score": 0.0009941134326203623}, {"caption": "\\epstopdfDeclareGraphicsRule{}{}{}{}", "snippet": "\\epstopdfDeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "epstopdf-cmd", "score": 7.723677706376668e-05}, {"caption": "\\OutputFile", "snippet": "\\OutputFile", "meta": "epstopdf-cmd", "score": 7.723677706376668e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "epstopdf-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "epstopdf-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "epstopdf-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epstopdf-cmd", "score": 0.008565354665444157}], "lmodern": [{"caption": "\\rmdefault", "snippet": "\\rmdefault", "meta": "lmodern-cmd", "score": 0.0012870877747432935}, {"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "lmodern-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "lmodern-cmd", "score": 0.008427383388519996}], "pifont": [{"caption": "\\ding{}", "snippet": "\\ding{$1}", "meta": "pifont-cmd", "score": 0.009992300665793867}], "ragged2e": [{"caption": "\\justifying", "snippet": "\\justifying", "meta": "ragged2e-cmd", "score": 0.010373702256548788}, {"caption": "\\justifying{}", "snippet": "\\justifying{$1}", "meta": "ragged2e-cmd", "score": 0.010373702256548788}, {"caption": "\\RaggedRight", "snippet": "\\RaggedRight", "meta": "ragged2e-cmd", "score": 0.001021021782267457}, {"caption": "\\Centering", "snippet": "\\Centering", "meta": "ragged2e-cmd", "score": 0.00037395241488843035}, {"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "ragged2e-cmd", "score": 0.04598628699063736}], "rotating": [{"caption": "\\csname", "snippet": "\\csname", "meta": "rotating-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "rotating-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "rotating-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "rotating-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "rotating-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "rotating-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "rotating-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "rotating-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "rotating-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "rotating-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "rotating-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rotating-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "rotating-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "rotating-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "rotating-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "rotating-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "rotating-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "rotating-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "rotating-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "rotating-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "rotating-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "rotating-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "rotating-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "rotating-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "rotating-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "rotating-cmd", "score": 0.004719094298848707}], "xltxtra": [{"caption": "\\textsubscript{}", "snippet": "\\textsubscript{$1}", "meta": "xltxtra-cmd", "score": 0.058405875394131175}, {"caption": "\\textsuperscript{}", "snippet": "\\textsuperscript{$1}", "meta": "xltxtra-cmd", "score": 0.05216393882408519}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "xltxtra-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xltxtra-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "xltxtra-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xltxtra-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xltxtra-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "xltxtra-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "xltxtra-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "xltxtra-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "xltxtra-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "xltxtra-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xltxtra-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "xltxtra-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xltxtra-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "xltxtra-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xltxtra-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "xltxtra-cmd", "score": 0.004649150613625593}, {"caption": "\\XeTeX", "snippet": "\\XeTeX", "meta": "xltxtra-cmd", "score": 0.0010635559050357936}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "xltxtra-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "xltxtra-cmd", "score": 0.02873756018238537}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "xltxtra-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "xltxtra-cmd", "score": 0.2334089308452787}, {"caption": "\\XeLaTeX", "snippet": "\\XeLaTeX", "meta": "xltxtra-cmd", "score": 0.002009786035379175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xltxtra-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xltxtra-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xltxtra-cmd", "score": 0.2864294797053033}], "marvosym": [{"caption": "\\Mundus", "snippet": "\\Mundus", "meta": "marvosym-cmd", "score": 0.0006349134235582933}, {"caption": "\\Telefon", "snippet": "\\Telefon", "meta": "marvosym-cmd", "score": 0.0003618274070138519}, {"caption": "\\Letter", "snippet": "\\Letter", "meta": "marvosym-cmd", "score": 0.0012281130571092198}, {"caption": "\\Mobilefone", "snippet": "\\Mobilefone", "meta": "marvosym-cmd", "score": 0.0005432037068220953}], "dcolumn": [{"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "dcolumn-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "dcolumn-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "dcolumn-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "dcolumn-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "dcolumn-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "dcolumn-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "dcolumn-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "dcolumn-cmd", "score": 0.018615449342361392}], "xspace": [{"caption": "\\xspace", "snippet": "\\xspace", "meta": "xspace-cmd", "score": 0.07560370351316588}], "xunicode": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xunicode-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xunicode-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xunicode-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xunicode-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "xunicode-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "xunicode-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "xunicode-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "xunicode-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "xunicode-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xunicode-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "xunicode-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xunicode-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "xunicode-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "xunicode-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xunicode-cmd", "score": 0.004719094298848707}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "xunicode-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xunicode-cmd", "score": 0.008565354665444157}], "csquotes": [{"caption": "\\mkcitation", "snippet": "\\mkcitation", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\DeclareQuoteAlias{}{}", "snippet": "\\DeclareQuoteAlias{$1}{$2}", "meta": "csquotes-cmd", "score": 0.0004906235524176374}, {"caption": "\\quote{}", "snippet": "\\quote{$1}", "meta": "csquotes-cmd", "score": 0.030690393112264815}, {"caption": "\\quote", "snippet": "\\quote", "meta": "csquotes-cmd", "score": 0.030690393112264815}, {"caption": "\\setquotestyle[]{}", "snippet": "\\setquotestyle[$1]{$2}", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\blockquote{}", "snippet": "\\blockquote{$1}", "meta": "csquotes-cmd", "score": 0.00023365626458085812}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "csquotes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "csquotes-cmd", "score": 0.021170869458413965}, {"caption": "\\mkbegdispquote", "snippet": "\\mkbegdispquote", "meta": "csquotes-cmd", "score": 4.203362017075738e-05}, {"caption": "\\do", "snippet": "\\do", "meta": "csquotes-cmd", "score": 0.009278344180101056}, {"caption": "\\break", "snippet": "\\break", "meta": "csquotes-cmd", "score": 0.016352452390960115}, {"caption": "\\break{}", "snippet": "\\break{$1}", "meta": "csquotes-cmd", "score": 0.016352452390960115}, {"caption": "\\break{}{}", "snippet": "\\break{$1}{$2}", "meta": "csquotes-cmd", "score": 0.016352452390960115}, {"caption": "\\ifpunctmark{}", "snippet": "\\ifpunctmark{$1}", "meta": "csquotes-cmd", "score": 7.723677706376668e-05}, {"caption": "\\endquote", "snippet": "\\endquote", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\par", "snippet": "\\par", "meta": "csquotes-cmd", "score": 0.413853376001159}, {"caption": "\\DeclareQuoteStyle[]{}", "snippet": "\\DeclareQuoteStyle[$1]{$2}", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\SetBlockEnvironment{}", "snippet": "\\SetBlockEnvironment{$1}", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "csquotes-cmd", "score": 0.008565354665444157}, {"caption": "\\MakeOuterQuote{}", "snippet": "\\MakeOuterQuote{$1}", "meta": "csquotes-cmd", "score": 0.0019170811203505262}, {"caption": "\\enquote{}", "snippet": "\\enquote{$1}", "meta": "csquotes-cmd", "score": 0.0077432730806830915}, {"caption": "\\SetCiteCommand{}", "snippet": "\\SetCiteCommand{$1}", "meta": "csquotes-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "csquotes-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "csquotes-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "csquotes-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "csquotes-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "csquotes-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "csquotes-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "csquotes-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "csquotes-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "csquotes-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "csquotes-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "csquotes-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "csquotes-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "csquotes-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "csquotes-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "csquotes-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "csquotes-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "csquotes-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "csquotes-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "csquotes-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "csquotes-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "csquotes-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "csquotes-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "csquotes-cmd", "score": 0.00037306820619479756}], "xparse": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xparse-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xparse-cmd", "score": 0.2864294797053033}], "soul": [{"caption": "\\DeclareRobustCommand{}{}", "snippet": "\\DeclareRobustCommand{$1}{$2}", "meta": "soul-cmd", "score": 0.0010373158471650705}, {"caption": "\\DeclareRobustCommand{}[]{}", "snippet": "\\DeclareRobustCommand{$1}[$2]{$3}", "meta": "soul-cmd", "score": 0.0010373158471650705}, {"caption": "\\sethlcolor{}", "snippet": "\\sethlcolor{$1}", "meta": "soul-cmd", "score": 0.01970230898277056}, {"caption": "\\st", "snippet": "\\st", "meta": "soul-cmd", "score": 0.004652662833362787}, {"caption": "\\st{}", "snippet": "\\st{$1}", "meta": "soul-cmd", "score": 0.004652662833362787}, {"caption": "\\def", "snippet": "\\def", "meta": "soul-cmd", "score": 0.21357759092476175}, {"caption": "\\hl{}", "snippet": "\\hl{$1}", "meta": "soul-cmd", "score": 0.03421486301062431}, {"caption": "\\sodef", "snippet": "\\sodef", "meta": "soul-cmd", "score": 0.0017045357696831268}, {"caption": "\\csname", "snippet": "\\csname", "meta": "soul-cmd", "score": 0.008565354665444157}, {"caption": "\\so", "snippet": "\\so", "meta": "soul-cmd", "score": 0.004308800134587786}, {"caption": "\\so{}", "snippet": "\\so{$1}", "meta": "soul-cmd", "score": 0.004308800134587786}], "comment": [{"caption": "\\specialcomment{}{}{}", "snippet": "\\specialcomment{$1}{$2}{$3}", "meta": "comment-cmd", "score": 9.120209837787948e-05}, {"caption": "\\includecomment{}", "snippet": "\\includecomment{$1}", "meta": "comment-cmd", "score": 8.21804444236254e-05}], "algorithm2e": [{"caption": "\\FuncSty{}", "snippet": "\\FuncSty{$1}", "meta": "algorithm2e-cmd", "score": 7.576875738934807e-05}, {"caption": "\\algorithmautorefname", "snippet": "\\algorithmautorefname", "meta": "algorithm2e-cmd", "score": 2.0085955839419213e-05}, {"caption": "\\SetAlgoNoLine", "snippet": "\\SetAlgoNoLine", "meta": "algorithm2e-cmd", "score": 0.00015722499147840545}, {"caption": "\\Indp", "snippet": "\\Indp", "meta": "algorithm2e-cmd", "score": 6.068942580823901e-05}, {"caption": "\\AlCapFnt", "snippet": "\\AlCapFnt", "meta": "algorithm2e-cmd", "score": 3.0307502955739227e-05}, {"caption": "\\LinesNumbered", "snippet": "\\LinesNumbered", "meta": "algorithm2e-cmd", "score": 0.000162125616653719}, {"caption": "\\SetAlFnt{}", "snippet": "\\SetAlFnt{$1}", "meta": "algorithm2e-cmd", "score": 0.0024446198714390757}, {"caption": "\\SetKw{}{}", "snippet": "\\SetKw{$1}{$2}", "meta": "algorithm2e-cmd", "score": 9.292434841280213e-05}, {"caption": "\\RestyleAlgo{}", "snippet": "\\RestyleAlgo{$1}", "meta": "algorithm2e-cmd", "score": 0.00019243311960945823}, {"caption": "\\listofalgorithms", "snippet": "\\listofalgorithms", "meta": "algorithm2e-cmd", "score": 0.0012576983422794912}, {"caption": "\\IncMargin{}", "snippet": "\\IncMargin{$1}", "meta": "algorithm2e-cmd", "score": 0.0024294661199612063}, {"caption": "\\BlankLine", "snippet": "\\BlankLine", "meta": "algorithm2e-cmd", "score": 0.005049617303688214}, {"caption": "\\SetCommentSty{}", "snippet": "\\SetCommentSty{$1}", "meta": "algorithm2e-cmd", "score": 0.0001778112853266571}, {"caption": "\\SetAlgoNoEnd", "snippet": "\\SetAlgoNoEnd", "meta": "algorithm2e-cmd", "score": 0.00015722499147840545}, {"caption": "\\theAlgoLine{}", "snippet": "\\theAlgoLine{$1}", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\SetKwBlock{}{}{}", "snippet": "\\SetKwBlock{$1}{$2}{$3}", "meta": "algorithm2e-cmd", "score": 0.000981463850523159}, {"caption": "\\SetKwBlock{}{}", "snippet": "\\SetKwBlock{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.000981463850523159}, {"caption": "\\AlCapNameFnt", "snippet": "\\AlCapNameFnt", "meta": "algorithm2e-cmd", "score": 3.0307502955739227e-05}, {"caption": "\\SetAlgoSkip{}", "snippet": "\\SetAlgoSkip{$1}", "meta": "algorithm2e-cmd", "score": 0.00017454032258926576}, {"caption": "\\SetKwFunction{}{}", "snippet": "\\SetKwFunction{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.0015332307832994817}, {"caption": "\\nllabel{}", "snippet": "\\nllabel{$1}", "meta": "algorithm2e-cmd", "score": 0.0001844460347791443}, {"caption": "\\SetAlgoInsideSkip{}", "snippet": "\\SetAlgoInsideSkip{$1}", "meta": "algorithm2e-cmd", "score": 4.5812360816321294e-05}, {"caption": "\\DataSty{}", "snippet": "\\DataSty{$1}", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\SetKwInOut{}{}", "snippet": "\\SetKwInOut{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.0017021978326807814}, {"caption": "\\SetAlCapFnt{}", "snippet": "\\SetAlCapFnt{$1}", "meta": "algorithm2e-cmd", "score": 0.0024294661199612063}, {"caption": "\\CommentSty{}", "snippet": "\\CommentSty{$1}", "meta": "algorithm2e-cmd", "score": 0.0001111448631633176}, {"caption": "\\SetAlCapHSkip{}", "snippet": "\\SetAlCapHSkip{$1}", "meta": "algorithm2e-cmd", "score": 0.0024294661199612063}, {"caption": "\\renewcommand{}{}", "snippet": "\\renewcommand{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.3267437011085663}, {"caption": "\\renewcommand", "snippet": "\\renewcommand", "meta": "algorithm2e-cmd", "score": 0.3267437011085663}, {"caption": "\\algorithmcfname", "snippet": "\\algorithmcfname", "meta": "algorithm2e-cmd", "score": 0.0024445413067013134}, {"caption": "\\SetKwIF{}{}{}{}{}{}{}{}", "snippet": "\\SetKwIF{$1}{$2}{$3}{$4}{$5}{$6}{$7}{$8}", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\SetAlgoCaptionSeparator{}", "snippet": "\\SetAlgoCaptionSeparator{$1}", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\AlCapSty{}", "snippet": "\\AlCapSty{$1}", "meta": "algorithm2e-cmd", "score": 3.0307502955739227e-05}, {"caption": "\\ArgSty{}", "snippet": "\\ArgSty{$1}", "meta": "algorithm2e-cmd", "score": 3.0307502955739227e-05}, {"caption": "\\AlCapNameSty{}", "snippet": "\\AlCapNameSty{$1}", "meta": "algorithm2e-cmd", "score": 3.0307502955739227e-05}, {"caption": "\\SetKwData{}{}", "snippet": "\\SetKwData{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.00235652682860263}, {"caption": "\\listalgorithmcfname", "snippet": "\\listalgorithmcfname", "meta": "algorithm2e-cmd", "score": 1.5075186740106946e-05}, {"caption": "\\Indm", "snippet": "\\Indm", "meta": "algorithm2e-cmd", "score": 6.068942580823901e-05}, {"caption": "\\SetAlCapNameFnt{}", "snippet": "\\SetAlCapNameFnt{$1}", "meta": "algorithm2e-cmd", "score": 0.0024294661199612063}, {"caption": "\\DontPrintSemicolon", "snippet": "\\DontPrintSemicolon", "meta": "algorithm2e-cmd", "score": 0.001062087490197768}, {"caption": "\\SetAlgoLined", "snippet": "\\SetAlgoLined", "meta": "algorithm2e-cmd", "score": 0.0017151361342403852}, {"caption": "\\SetAlCapSkip{}", "snippet": "\\SetAlCapSkip{$1}", "meta": "algorithm2e-cmd", "score": 0.0006213942502400296}, {"caption": "\\LinesNotNumbered", "snippet": "\\LinesNotNumbered", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\SetKwProg{}{}{}{}", "snippet": "\\SetKwProg{$1}{$2}{$3}{$4}", "meta": "algorithm2e-cmd", "score": 0.0008518783278391971}, {"caption": "\\SetAlgoVlined", "snippet": "\\SetAlgoVlined", "meta": "algorithm2e-cmd", "score": 1.5153751477869614e-05}, {"caption": "\\SetKwRepeat{}{}{}", "snippet": "\\SetKwRepeat{$1}{$2}{$3}", "meta": "algorithm2e-cmd", "score": 6.110202388233705e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algorithm2e-cmd", "score": 0.008565354665444157}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "algorithm2e-cmd", "score": 0.422097569591803}, {"caption": "\\SetKwFor{}{}{}{}", "snippet": "\\SetKwFor{$1}{$2}{$3}{$4}", "meta": "algorithm2e-cmd", "score": 0.00010699539949594301}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algorithm2e-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algorithm2e-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algorithm2e-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algorithm2e-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algorithm2e-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algorithm2e-cmd", "score": 0.0018957469739775527}, {"caption": "\\xspace", "snippet": "\\xspace", "meta": "algorithm2e-cmd", "score": 0.07560370351316588}], "tocbibind": [{"caption": "\\contentsname", "snippet": "\\contentsname", "meta": "tocbibind-cmd", "score": 0.010205180337548728}, {"caption": "\\contentsname{}", "snippet": "\\contentsname{$1}", "meta": "tocbibind-cmd", "score": 0.010205180337548728}, {"caption": "\\tocchapter", "snippet": "\\tocchapter", "meta": "tocbibind-cmd", "score": 0.00016023188758771694}, {"caption": "\\indexname", "snippet": "\\indexname", "meta": "tocbibind-cmd", "score": 0.0007544109314450072}, {"caption": "\\listoffigures", "snippet": "\\listoffigures", "meta": "tocbibind-cmd", "score": 0.03447318897846567}, {"caption": "\\tocfile{}{}", "snippet": "\\tocfile{$1}{$2}", "meta": "tocbibind-cmd", "score": 0.00016023188758771694}, {"caption": "\\tocbibname", "snippet": "\\tocbibname", "meta": "tocbibind-cmd", "score": 0.0020762574479507175}, {"caption": "\\settocbibname{}", "snippet": "\\settocbibname{$1}", "meta": "tocbibind-cmd", "score": 0.00010668677119599426}, {"caption": "\\listoftables", "snippet": "\\listoftables", "meta": "tocbibind-cmd", "score": 0.02104656820469027}, {"caption": "\\tableofcontents", "snippet": "\\tableofcontents", "meta": "tocbibind-cmd", "score": 0.13360595130994957}, {"caption": "\\listfigurename", "snippet": "\\listfigurename", "meta": "tocbibind-cmd", "score": 0.0034407237779350256}], "pgfplots": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplots-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfplots-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfplots-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfplots-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfplots-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfplots-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfplots-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfplots-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplots-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfplots-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfplots-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfplots-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfplots-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfplots-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfplots-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfplots-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfplots-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfplots-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplots-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfplots-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfplots-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfplots-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfplots-cmd", "score": 0.2864294797053033}], "lastpage": [{"caption": "\\string", "snippet": "\\string", "meta": "lastpage-cmd", "score": 0.001042697111754002}], "graphics": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "graphics-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "graphics-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "graphics-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "graphics-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "graphics-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "graphics-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "graphics-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "graphics-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "graphics-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphics-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "graphics-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "graphics-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "graphics-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "graphics-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "graphics-cmd", "score": 0.004649150613625593}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphics-cmd", "score": 0.008565354665444157}], "algorithmic": [{"caption": "\\REPEAT", "snippet": "\\REPEAT", "meta": "algorithmic-cmd", "score": 0.0004816110638193742}, {"caption": "\\ENDIF", "snippet": "\\ENDIF", "meta": "algorithmic-cmd", "score": 0.003585213685098552}, {"caption": "\\algorithmicwhile", "snippet": "\\algorithmicwhile", "meta": "algorithmic-cmd", "score": 0.0005769483780443573}, {"caption": "\\algorithmicwhile{}", "snippet": "\\algorithmicwhile{$1}", "meta": "algorithmic-cmd", "score": 0.0005769483780443573}, {"caption": "\\FOR{}", "snippet": "\\FOR{$1}", "meta": "algorithmic-cmd", "score": 0.004074774218819945}, {"caption": "\\algorithmicif", "snippet": "\\algorithmicif", "meta": "algorithmic-cmd", "score": 0.00039654130753044966}, {"caption": "\\algorithmicif{}", "snippet": "\\algorithmicif{$1}", "meta": "algorithmic-cmd", "score": 0.00039654130753044966}, {"caption": "\\ENDFOR", "snippet": "\\ENDFOR", "meta": "algorithmic-cmd", "score": 0.004428141530092572}, {"caption": "\\UNTIL", "snippet": "\\UNTIL", "meta": "algorithmic-cmd", "score": 0.0004816110638193742}, {"caption": "\\UNTIL{}", "snippet": "\\UNTIL{$1}", "meta": "algorithmic-cmd", "score": 0.0004816110638193742}, {"caption": "\\IF{}", "snippet": "\\IF{$1}", "meta": "algorithmic-cmd", "score": 0.0036985887706967417}, {"caption": "\\ENSURE", "snippet": "\\ENSURE", "meta": "algorithmic-cmd", "score": 0.0013188761425395954}, {"caption": "\\algorithmiccomment", "snippet": "\\algorithmiccomment", "meta": "algorithmic-cmd", "score": 0.00021737766481978388}, {"caption": "\\ENDWHILE", "snippet": "\\ENDWHILE", "meta": "algorithmic-cmd", "score": 0.00047037943460091465}, {"caption": "\\algorithmicend", "snippet": "\\algorithmicend", "meta": "algorithmic-cmd", "score": 0.0011128218085672747}, {"caption": "\\algorithmicend{}", "snippet": "\\algorithmicend{$1}", "meta": "algorithmic-cmd", "score": 0.0011128218085672747}, {"caption": "\\algorithmicrequire", "snippet": "\\algorithmicrequire", "meta": "algorithmic-cmd", "score": 0.004751598472180266}, {"caption": "\\algorithmicdo", "snippet": "\\algorithmicdo", "meta": "algorithmic-cmd", "score": 0.0005655570358533174}, {"caption": "\\algorithmicdo{}", "snippet": "\\algorithmicdo{$1}", "meta": "algorithmic-cmd", "score": 0.0005655570358533174}, {"caption": "\\algorithmicfor", "snippet": "\\algorithmicfor", "meta": "algorithmic-cmd", "score": 0.0005681785898943757}, {"caption": "\\algorithmicfor{}", "snippet": "\\algorithmicfor{$1}", "meta": "algorithmic-cmd", "score": 0.0005681785898943757}, {"caption": "\\RETURN", "snippet": "\\RETURN", "meta": "algorithmic-cmd", "score": 0.0013054907995767408}, {"caption": "\\algorithmicand", "snippet": "\\algorithmicand", "meta": "algorithmic-cmd", "score": 5.326674280259771e-05}, {"caption": "\\algsetup{}", "snippet": "\\algsetup{$1}", "meta": "algorithmic-cmd", "score": 0.00012872796177294446}, {"caption": "\\algorithmicreturn{}", "snippet": "\\algorithmicreturn{$1}", "meta": "algorithmic-cmd", "score": 0.00022490402516652368}, {"caption": "\\algorithmicreturn", "snippet": "\\algorithmicreturn", "meta": "algorithmic-cmd", "score": 0.00022490402516652368}, {"caption": "\\algorithmicforall{}", "snippet": "\\algorithmicforall{$1}", "meta": "algorithmic-cmd", "score": 0.00022490402516652368}, {"caption": "\\algorithmicforall", "snippet": "\\algorithmicforall", "meta": "algorithmic-cmd", "score": 0.00022490402516652368}, {"caption": "\\COMMENT", "snippet": "\\COMMENT", "meta": "algorithmic-cmd", "score": 0.00025669572555354604}, {"caption": "\\COMMENT{}", "snippet": "\\COMMENT{$1}", "meta": "algorithmic-cmd", "score": 0.00025669572555354604}, {"caption": "\\REQUIRE", "snippet": "\\REQUIRE", "meta": "algorithmic-cmd", "score": 0.001870681168192269}, {"caption": "\\algorithmicor", "snippet": "\\algorithmicor", "meta": "algorithmic-cmd", "score": 5.326674280259771e-05}, {"caption": "\\ELSE", "snippet": "\\ELSE", "meta": "algorithmic-cmd", "score": 0.0007599864146830139}, {"caption": "\\STATE", "snippet": "\\STATE", "meta": "algorithmic-cmd", "score": 0.0266684860947573}, {"caption": "\\WHILE{}", "snippet": "\\WHILE{$1}", "meta": "algorithmic-cmd", "score": 0.00047037943460091465}, {"caption": "\\ELSIF{}", "snippet": "\\ELSIF{$1}", "meta": "algorithmic-cmd", "score": 0.0001991613148371481}, {"caption": "\\FALSE", "snippet": "\\FALSE", "meta": "algorithmic-cmd", "score": 3.34222699937868e-05}, {"caption": "\\AND", "snippet": "\\AND", "meta": "algorithmic-cmd", "score": 6.401730289932545e-05}, {"caption": "\\algorithmicensure", "snippet": "\\algorithmicensure", "meta": "algorithmic-cmd", "score": 0.003439482525198322}, {"caption": "\\OR", "snippet": "\\OR", "meta": "algorithmic-cmd", "score": 6.401730289932545e-05}, {"caption": "\\algorithmicrepeat", "snippet": "\\algorithmicrepeat", "meta": "algorithmic-cmd", "score": 5.326674280259771e-05}, {"caption": "\\TRUE", "snippet": "\\TRUE", "meta": "algorithmic-cmd", "score": 0.0001336890799751472}, {"caption": "\\FORALL{}", "snippet": "\\FORALL{$1}", "meta": "algorithmic-cmd", "score": 0.0003533673112726266}, {"caption": "\\algorithmicthen{}", "snippet": "\\algorithmicthen{$1}", "meta": "algorithmic-cmd", "score": 0.00032476571672371697}, {"caption": "\\algorithmicthen", "snippet": "\\algorithmicthen", "meta": "algorithmic-cmd", "score": 0.00032476571672371697}, {"caption": "\\algorithmicuntil", "snippet": "\\algorithmicuntil", "meta": "algorithmic-cmd", "score": 5.326674280259771e-05}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algorithmic-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algorithmic-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algorithmic-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algorithmic-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algorithmic-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algorithmic-cmd", "score": 0.0018957469739775527}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "algorithmic-cmd", "score": 0.00037306820619479756}], "lineno": [{"caption": "\\pagewiselinenumbers", "snippet": "\\pagewiselinenumbers", "meta": "lineno-cmd", "score": 0.00016870831850106035}, {"caption": "\\linenomath", "snippet": "\\linenomath", "meta": "lineno-cmd", "score": 1.4517338420208715e-05}, {"caption": "\\linenumberfont{}", "snippet": "\\linenumberfont{$1}", "meta": "lineno-cmd", "score": 0.0001811784338695797}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "lineno-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "lineno-cmd", "score": 0.021170869458413965}, {"caption": "\\endlinenomath", "snippet": "\\endlinenomath", "meta": "lineno-cmd", "score": 1.4517338420208715e-05}, {"caption": "\\nolinenumbers", "snippet": "\\nolinenumbers", "meta": "lineno-cmd", "score": 0.0009805246614299932}, {"caption": "\\path", "snippet": "\\path", "meta": "lineno-cmd", "score": 0.028200474217322108}, {"caption": "\\path[]", "snippet": "\\path[$1]", "meta": "lineno-cmd", "score": 0.028200474217322108}, {"caption": "\\path{}", "snippet": "\\path{$1}", "meta": "lineno-cmd", "score": 0.028200474217322108}, {"caption": "\\filedate{}", "snippet": "\\filedate{$1}", "meta": "lineno-cmd", "score": 0.000578146635331119}, {"caption": "\\filedate", "snippet": "\\filedate", "meta": "lineno-cmd", "score": 0.000578146635331119}, {"caption": "\\linenumbers", "snippet": "\\linenumbers", "meta": "lineno-cmd", "score": 0.004687680659497865}, {"caption": "\\modulolinenumbers[]", "snippet": "\\modulolinenumbers[$1]", "meta": "lineno-cmd", "score": 0.0027194991933605197}, {"caption": "\\fileversion{}", "snippet": "\\fileversion{$1}", "meta": "lineno-cmd", "score": 0.000578146635331119}, {"caption": "\\fileversion", "snippet": "\\fileversion", "meta": "lineno-cmd", "score": 0.000578146635331119}, {"caption": "\\csname", "snippet": "\\csname", "meta": "lineno-cmd", "score": 0.008565354665444157}], "mathptmx": [{"caption": "\\rmdefault", "snippet": "\\rmdefault", "meta": "mathptmx-cmd", "score": 0.0012870877747432935}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "mathptmx-cmd", "score": 0.04318078602869565}, {"caption": "\\Big", "snippet": "\\Big", "meta": "mathptmx-cmd", "score": 0.050370758781422345}, {"caption": "\\big", "snippet": "\\big", "meta": "mathptmx-cmd", "score": 0.05613164277964739}], "todonotes": [{"caption": "\\missingfigure[]{}", "snippet": "\\missingfigure[$1]{$2}", "meta": "todonotes-cmd", "score": 0.001558719179721163}, {"caption": "\\missingfigure", "snippet": "\\missingfigure", "meta": "todonotes-cmd", "score": 0.001558719179721163}, {"caption": "\\todototoc", "snippet": "\\todototoc", "meta": "todonotes-cmd", "score": 0.000325977535138643}, {"caption": "\\todo{}", "snippet": "\\todo{$1}", "meta": "todonotes-cmd", "score": 0.04115074278362878}, {"caption": "\\todo[]{}", "snippet": "\\todo[$1]{$2}", "meta": "todonotes-cmd", "score": 0.04115074278362878}, {"caption": "\\todo", "snippet": "\\todo", "meta": "todonotes-cmd", "score": 0.04115074278362878}, {"caption": "\\listoftodos", "snippet": "\\listoftodos", "meta": "todonotes-cmd", "score": 0.0005325975940754609}, {"caption": "\\listoftodos[]", "snippet": "\\listoftodos[$1]", "meta": "todonotes-cmd", "score": 0.0005325975940754609}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "todonotes-cmd", "score": 0.0174633138331273}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "todonotes-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "todonotes-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "todonotes-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "todonotes-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "todonotes-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "todonotes-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "todonotes-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "todonotes-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "todonotes-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "todonotes-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "todonotes-cmd", "score": 0.004649150613625593}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "todonotes-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "todonotes-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "todonotes-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "todonotes-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "todonotes-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "todonotes-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "todonotes-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "todonotes-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "todonotes-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "todonotes-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "todonotes-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "todonotes-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "todonotes-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "todonotes-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "todonotes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "todonotes-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "todonotes-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "todonotes-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "todonotes-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "todonotes-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "todonotes-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "todonotes-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "todonotes-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "todonotes-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "todonotes-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "todonotes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "todonotes-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "todonotes-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "todonotes-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "todonotes-cmd", "score": 0.2864294797053033}], "ulem": [{"caption": "\\sout{}", "snippet": "\\sout{$1}", "meta": "ulem-cmd", "score": 0.0010443313503631364}, {"caption": "\\sout", "snippet": "\\sout", "meta": "ulem-cmd", "score": 0.0010443313503631364}, {"caption": "\\MakeRobust", "snippet": "\\MakeRobust", "meta": "ulem-cmd", "score": 3.140504277052775e-05}, {"caption": "\\hss", "snippet": "\\hss", "meta": "ulem-cmd", "score": 0.0020627882815078768}, {"caption": "\\uline{}", "snippet": "\\uline{$1}", "meta": "ulem-cmd", "score": 0.005956273219192909}, {"caption": "\\uline", "snippet": "\\uline", "meta": "ulem-cmd", "score": 0.005956273219192909}, {"caption": "\\markoverwith{}", "snippet": "\\markoverwith{$1}", "meta": "ulem-cmd", "score": 0.0004888431085285657}, {"caption": "\\iff", "snippet": "\\iff", "meta": "ulem-cmd", "score": 0.004209937150980285}, {"caption": "\\hfill", "snippet": "\\hfill", "meta": "ulem-cmd", "score": 0.2058248088519886}, {"caption": "\\ULon", "snippet": "\\ULon", "meta": "ulem-cmd", "score": 0.0004888431085285657}, {"caption": "\\normalem", "snippet": "\\normalem", "meta": "ulem-cmd", "score": 0.00015564484081028078}, {"caption": "\\useunder{}{}{}", "snippet": "\\useunder{$1}{$2}{$3}", "meta": "ulem-cmd", "score": 0.0013185833851097916}, {"caption": "\\hfil", "snippet": "\\hfil", "meta": "ulem-cmd", "score": 0.006880789969115855}, {"caption": "\\sout{}", "snippet": "\\sout{$1}", "meta": "ulem-cmd", "score": 0.0010443313503631364}, {"caption": "\\sout", "snippet": "\\sout", "meta": "ulem-cmd", "score": 0.0010443313503631364}, {"caption": "\\MakeRobust", "snippet": "\\MakeRobust", "meta": "ulem-cmd", "score": 3.140504277052775e-05}, {"caption": "\\hss", "snippet": "\\hss", "meta": "ulem-cmd", "score": 0.0020627882815078768}, {"caption": "\\uline{}", "snippet": "\\uline{$1}", "meta": "ulem-cmd", "score": 0.005956273219192909}, {"caption": "\\uline", "snippet": "\\uline", "meta": "ulem-cmd", "score": 0.005956273219192909}, {"caption": "\\markoverwith{}", "snippet": "\\markoverwith{$1}", "meta": "ulem-cmd", "score": 0.0004888431085285657}, {"caption": "\\iff", "snippet": "\\iff", "meta": "ulem-cmd", "score": 0.004209937150980285}, {"caption": "\\hfill", "snippet": "\\hfill", "meta": "ulem-cmd", "score": 0.2058248088519886}, {"caption": "\\ULon", "snippet": "\\ULon", "meta": "ulem-cmd", "score": 0.0004888431085285657}, {"caption": "\\normalem", "snippet": "\\normalem", "meta": "ulem-cmd", "score": 0.00015564484081028078}, {"caption": "\\useunder{}{}{}", "snippet": "\\useunder{$1}{$2}{$3}", "meta": "ulem-cmd", "score": 0.0013185833851097916}, {"caption": "\\hfil", "snippet": "\\hfil", "meta": "ulem-cmd", "score": 0.006880789969115855}], "gensymb": [{"caption": "\\degree", "snippet": "\\degree", "meta": "gensymb-cmd", "score": 0.044752043138360405}, {"caption": "\\ohm", "snippet": "\\ohm", "meta": "gensymb-cmd", "score": 0.0038146685721293138}, {"caption": "\\micro", "snippet": "\\micro", "meta": "gensymb-cmd", "score": 0.011051971930487929}, {"caption": "\\celsius", "snippet": "\\celsius", "meta": "gensymb-cmd", "score": 0.0010806983851157788}], "siunitx": [{"caption": "\\DeclareSIUnit{}{}", "snippet": "\\DeclareSIUnit{$1}{$2}", "meta": "siunitx-cmd", "score": 0.00017911905960739648}, {"caption": "\\DeclareSIUnit", "snippet": "\\DeclareSIUnit", "meta": "siunitx-cmd", "score": 0.00017911905960739648}, {"caption": "\\si{}", "snippet": "\\si{$1}", "meta": "siunitx-cmd", "score": 0.015042996547458706}, {"caption": "\\num{}", "snippet": "\\num{$1}", "meta": "siunitx-cmd", "score": 0.0005077454796577224}, {"caption": "\\num[]{}", "snippet": "\\num[$1]{$2}", "meta": "siunitx-cmd", "score": 0.0005077454796577224}, {"caption": "\\ang{}", "snippet": "\\ang{$1}", "meta": "siunitx-cmd", "score": 0.00026216419341458844}, {"caption": "\\SIrange{}{}{}", "snippet": "\\SIrange{$1}{$2}{$3}", "meta": "siunitx-cmd", "score": 0.0004920776847142836}, {"caption": "\\SIrange[]{}{}{}", "snippet": "\\SIrange[$1]{$2}{$3}{$4}", "meta": "siunitx-cmd", "score": 0.0004920776847142836}, {"caption": "\\SIlist{}{}", "snippet": "\\SIlist{$1}{$2}", "meta": "siunitx-cmd", "score": 2.5005836362206937e-05}, {"caption": "\\SI{}{}", "snippet": "\\SI{$1}{$2}", "meta": "siunitx-cmd", "score": 0.04233098901537305}, {"caption": "\\sisetup{}", "snippet": "\\sisetup{$1}", "meta": "siunitx-cmd", "score": 0.0011875061630332172}, {"caption": "\\do", "snippet": "\\do", "meta": "siunitx-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "siunitx-cmd", "score": 0.0063276692758974925}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "siunitx-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "siunitx-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "siunitx-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "siunitx-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "siunitx-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "siunitx-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "siunitx-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "siunitx-cmd", "score": 0.018615449342361392}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "siunitx-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "siunitx-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "siunitx-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "siunitx-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "siunitx-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "siunitx-cmd", "score": 0.2864294797053033}], "adjustbox": [{"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "adjustbox-cmd", "score": 0.354445763583904}, {"caption": "\\adjustbox{}{}", "snippet": "\\adjustbox{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.002008185536556013}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "adjustbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "adjustbox-cmd", "score": 0.021170869458413965}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "adjustbox-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "adjustbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "adjustbox-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "adjustbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "adjustbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "adjustbox-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "adjustbox-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "adjustbox-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "adjustbox-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "adjustbox-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "adjustbox-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "adjustbox-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "adjustbox-cmd", "score": 0.004649150613625593}], "moderncvcompatibility": [{"caption": "\\cvitem{}{}", "snippet": "\\cvitem{$1}{$2}", "meta": "moderncvcompatibility-cmd", "score": 0.19605476980016281}, {"caption": "\\cvlanguage{}{}{}", "snippet": "\\cvlanguage{$1}{$2}{$3}", "meta": "moderncvcompatibility-cmd", "score": 0.00832363305853651}, {"caption": "\\moderncvtheme[]{}", "snippet": "\\moderncvtheme[$1]{$2}", "meta": "moderncvcompatibility-cmd", "score": 0.002355125248305291}, {"caption": "\\moderncvtheme{}", "snippet": "\\moderncvtheme{$1}", "meta": "moderncvcompatibility-cmd", "score": 0.002355125248305291}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "moderncvcompatibility-cmd", "score": 0.7504160124360846}, {"caption": "\\phone[]{}", "snippet": "\\phone[$1]{$2}", "meta": "moderncvcompatibility-cmd", "score": 0.09602264063533228}, {"caption": "\\moderncvstyle{}", "snippet": "\\moderncvstyle{$1}", "meta": "moderncvcompatibility-cmd", "score": 0.09378844125415692}, {"caption": "\\firstname{}", "snippet": "\\firstname{$1}", "meta": "moderncvcompatibility-cmd", "score": 0.0070031590875754435}, {"caption": "\\cvline{}{}", "snippet": "\\cvline{$1}{$2}", "meta": "moderncvcompatibility-cmd", "score": 0.007378490468121007}, {"caption": "\\mobile{}", "snippet": "\\mobile{$1}", "meta": "moderncvcompatibility-cmd", "score": 0.022907406369946367}, {"caption": "\\familyname{}", "snippet": "\\familyname{$1}", "meta": "moderncvcompatibility-cmd", "score": 0.0070031590875754435}, {"caption": "\\section{}", "snippet": "\\section{$1}", "meta": "moderncvcompatibility-cmd", "score": 3.0952612541683835}], "helvet": [{"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "helvet-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "helvet-cmd", "score": 0.008427383388519996}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "helvet-cmd", "score": 0.00037306820619479756}], "placeins": [{"caption": "\\FloatBarrier", "snippet": "\\FloatBarrier", "meta": "placeins-cmd", "score": 0.015841933780270347}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "placeins-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "placeins-cmd", "score": 0.021170869458413965}], "colortbl": [{"caption": "\\rowcolor{}", "snippet": "\\rowcolor{$1}", "meta": "colortbl-cmd", "score": 0.05564476491638024}, {"caption": "\\rowcolor[]{}", "snippet": "\\rowcolor[$1]{$2}", "meta": "colortbl-cmd", "score": 0.05564476491638024}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "colortbl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "colortbl-cmd", "score": 0.021170869458413965}, {"caption": "\\arrayrulecolor{}", "snippet": "\\arrayrulecolor{$1}", "meta": "colortbl-cmd", "score": 0.008538501902241319}, {"caption": "\\arrayrulecolor[]{}", "snippet": "\\arrayrulecolor[$1]{$2}", "meta": "colortbl-cmd", "score": 0.008538501902241319}, {"caption": "\\hline", "snippet": "\\hline", "meta": "colortbl-cmd", "score": 1.3209538327406387}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "colortbl-cmd", "score": 0.5473606021405326}, {"caption": "\\cellcolor[]{}", "snippet": "\\cellcolor[$1]{$2}", "meta": "colortbl-cmd", "score": 0.11068275858524645}, {"caption": "\\cellcolor{}", "snippet": "\\cellcolor{$1}", "meta": "colortbl-cmd", "score": 0.11068275858524645}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "colortbl-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "colortbl-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "colortbl-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "colortbl-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "colortbl-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "colortbl-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "colortbl-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "colortbl-cmd", "score": 0.018615449342361392}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "colortbl-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "colortbl-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "colortbl-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "colortbl-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "colortbl-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "colortbl-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "colortbl-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "colortbl-cmd", "score": 0.2864294797053033}], "appendix": [{"caption": "\\appendixpagename", "snippet": "\\appendixpagename", "meta": "appendix-cmd", "score": 0.0005082989114039268}, {"caption": "\\appendixpagename{}", "snippet": "\\appendixpagename{$1}", "meta": "appendix-cmd", "score": 0.0005082989114039268}, {"caption": "\\thechapter", "snippet": "\\thechapter", "meta": "appendix-cmd", "score": 0.011821300392639589}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "appendix-cmd", "score": 0.005008938879210868}, {"caption": "\\thesubsection", "snippet": "\\thesubsection", "meta": "appendix-cmd", "score": 0.004364729212023423}, {"caption": "\\appendixname", "snippet": "\\appendixname", "meta": "appendix-cmd", "score": 0.006491295958752496}, {"caption": "\\appendixname{}", "snippet": "\\appendixname{$1}", "meta": "appendix-cmd", "score": 0.006491295958752496}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "appendix-cmd", "score": 0.07503475348393239}, {"caption": "\\thesection", "snippet": "\\thesection", "meta": "appendix-cmd", "score": 0.011068945893347528}, {"caption": "\\thesection{}", "snippet": "\\thesection{$1}", "meta": "appendix-cmd", "score": 0.011068945893347528}, {"caption": "\\appendixpage", "snippet": "\\appendixpage", "meta": "appendix-cmd", "score": 0.0003193786370376004}, {"caption": "\\appendixpage{}", "snippet": "\\appendixpage{$1}", "meta": "appendix-cmd", "score": 0.0003193786370376004}, {"caption": "\\appendixtocname", "snippet": "\\appendixtocname", "meta": "appendix-cmd", "score": 0.0005082989114039268}, {"caption": "\\appendixtocname{}", "snippet": "\\appendixtocname{$1}", "meta": "appendix-cmd", "score": 0.0005082989114039268}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "appendix-cmd", "score": 0.0174633138331273}], "supertabular": [{"caption": "\\tabletail{}", "snippet": "\\tabletail{$1}", "meta": "supertabular-cmd", "score": 0.00284734590996941}, {"caption": "\\tablehead{}", "snippet": "\\tablehead{$1}", "meta": "supertabular-cmd", "score": 0.002940437317353234}, {"caption": "\\tablelasttail{}", "snippet": "\\tablelasttail{$1}", "meta": "supertabular-cmd", "score": 0.00284734590996941}, {"caption": "\\tablefirsthead{}", "snippet": "\\tablefirsthead{$1}", "meta": "supertabular-cmd", "score": 0.00284734590996941}], "makeidx": [{"caption": "\\printindex", "snippet": "\\printindex", "meta": "makeidx-cmd", "score": 0.004417016910870522}], "framed": [{"caption": "\\fbox{}", "snippet": "\\fbox{$1}", "meta": "framed-cmd", "score": 0.020865450075016792}], "layaureo": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "layaureo-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "layaureo-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "layaureo-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "layaureo-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "layaureo-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "layaureo-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "layaureo-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "layaureo-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "layaureo-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "layaureo-cmd", "score": 0.028955796305270766}, {"caption": "\\savegeometry{}", "snippet": "\\savegeometry{$1}", "meta": "layaureo-cmd", "score": 6.461638865465447e-05}, {"caption": "\\loadgeometry{}", "snippet": "\\loadgeometry{$1}", "meta": "layaureo-cmd", "score": 6.461638865465447e-05}, {"caption": "\\newgeometry{}", "snippet": "\\newgeometry{$1}", "meta": "layaureo-cmd", "score": 0.0025977479207639352}, {"caption": "\\geometry{}", "snippet": "\\geometry{$1}", "meta": "layaureo-cmd", "score": 0.046218420429973615}, {"caption": "\\csname", "snippet": "\\csname", "meta": "layaureo-cmd", "score": 0.008565354665444157}, {"caption": "\\restoregeometry", "snippet": "\\restoregeometry", "meta": "layaureo-cmd", "score": 0.0007546303842143648}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "layaureo-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "layaureo-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "layaureo-cmd", "score": 0.002958865219480927}], "keyval": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "keyval-cmd", "score": 0.00037306820619479756}], "physics": [{"caption": "\\sinh", "snippet": "\\sinh", "meta": "physics-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "physics-cmd", "score": 0.0006435164702005918}, {"caption": "\\curl{}", "snippet": "\\curl{$1}", "meta": "physics-cmd", "score": 0.001039136354388696}, {"caption": "\\curl", "snippet": "\\curl", "meta": "physics-cmd", "score": 0.001039136354388696}, {"caption": "\\dd", "snippet": "\\dd", "meta": "physics-cmd", "score": 0.0049652819784537965}, {"caption": "\\expval{}", "snippet": "\\expval{$1}", "meta": "physics-cmd", "score": 0.0006729185293892782}, {"caption": "\\exp", "snippet": "\\exp", "meta": "physics-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "physics-cmd", "score": 0.02404262443651467}, {"caption": "\\mqty", "snippet": "\\mqty", "meta": "physics-cmd", "score": 0.0002048562866401335}, {"caption": "\\order{}", "snippet": "\\order{$1}", "meta": "physics-cmd", "score": 0.00019980403788140113}, {"caption": "\\order", "snippet": "\\order", "meta": "physics-cmd", "score": 0.00019980403788140113}, {"caption": "\\abs{}", "snippet": "\\abs{$1}", "meta": "physics-cmd", "score": 0.016268920166928613}, {"caption": "\\cos", "snippet": "\\cos", "meta": "physics-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "physics-cmd", "score": 0.050370402546134785}, {"caption": "\\dv{}{}", "snippet": "\\dv{$1}{$2}", "meta": "physics-cmd", "score": 0.005139463745615663}, {"caption": "\\dv[]{}{}", "snippet": "\\dv[$1]{$2}{$3}", "meta": "physics-cmd", "score": 0.005139463745615663}, {"caption": "\\eval{}", "snippet": "\\eval{$1}", "meta": "physics-cmd", "score": 0.00021313621676565867}, {"caption": "\\eval", "snippet": "\\eval", "meta": "physics-cmd", "score": 0.00021313621676565867}, {"caption": "\\eval[]{}", "snippet": "\\eval[$1]{$2}", "meta": "physics-cmd", "score": 0.00021313621676565867}, {"caption": "\\tan", "snippet": "\\tan", "meta": "physics-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "physics-cmd", "score": 0.005640718203101287}, {"caption": "\\ket{}", "snippet": "\\ket{$1}", "meta": "physics-cmd", "score": 0.0326276280979336}, {"caption": "\\mel{}{}{}", "snippet": "\\mel{$1}{$2}{$3}", "meta": "physics-cmd", "score": 0.001123156900573353}, {"caption": "\\ip", "snippet": "\\ip", "meta": "physics-cmd", "score": 0.0008534664860896849}, {"caption": "\\ip{}{}", "snippet": "\\ip{$1}{$2}", "meta": "physics-cmd", "score": 0.0008534664860896849}, {"caption": "\\ip[]{}", "snippet": "\\ip[$1]{$2}", "meta": "physics-cmd", "score": 0.0008534664860896849}, {"caption": "\\Im", "snippet": "\\Im", "meta": "physics-cmd", "score": 0.0013451768070134808}, {"caption": "\\Im{}", "snippet": "\\Im{$1}", "meta": "physics-cmd", "score": 0.0013451768070134808}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "physics-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "physics-cmd", "score": 0.0008896391580266903}, {"caption": "\\comm{}{}", "snippet": "\\comm{$1}{$2}", "meta": "physics-cmd", "score": 0.0012026610554672049}, {"caption": "\\qty", "snippet": "\\qty", "meta": "physics-cmd", "score": 0.0017737618641299655}, {"caption": "\\qty{}", "snippet": "\\qty{$1}", "meta": "physics-cmd", "score": 0.0017737618641299655}, {"caption": "\\Tr", "snippet": "\\Tr", "meta": "physics-cmd", "score": 0.004615158124783136}, {"caption": "\\Tr{}", "snippet": "\\Tr{$1}", "meta": "physics-cmd", "score": 0.004615158124783136}, {"caption": "\\bra{}", "snippet": "\\bra{$1}", "meta": "physics-cmd", "score": 0.005609763332417241}, {"caption": "\\poissonbracket{}{}", "snippet": "\\poissonbracket{$1}{$2}", "meta": "physics-cmd", "score": 2.2761809626681494e-05}, {"caption": "\\pmat{}", "snippet": "\\pmat{$1}", "meta": "physics-cmd", "score": 0.00010356789132354732}, {"caption": "\\norm{}", "snippet": "\\norm{$1}", "meta": "physics-cmd", "score": 0.006576610603906938}, {"caption": "\\cot", "snippet": "\\cot", "meta": "physics-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "physics-cmd", "score": 0.0003640644365701238}, {"caption": "\\cross", "snippet": "\\cross", "meta": "physics-cmd", "score": 0.0005412940211650938}, {"caption": "\\log", "snippet": "\\log", "meta": "physics-cmd", "score": 0.048131780413380156}, {"caption": "\\dmat{}", "snippet": "\\dmat{$1}", "meta": "physics-cmd", "score": 2.2761809626681494e-05}, {"caption": "\\Re", "snippet": "\\Re", "meta": "physics-cmd", "score": 0.0031525922563281736}, {"caption": "\\Re{}", "snippet": "\\Re{$1}", "meta": "physics-cmd", "score": 0.0031525922563281736}, {"caption": "\\qq{}", "snippet": "\\qq{$1}", "meta": "physics-cmd", "score": 8.241282620919185e-05}, {"caption": "\\qq", "snippet": "\\qq", "meta": "physics-cmd", "score": 8.241282620919185e-05}, {"caption": "\\vb{}", "snippet": "\\vb{$1}", "meta": "physics-cmd", "score": 0.007377410801695042}, {"caption": "\\pdv{}{}", "snippet": "\\pdv{$1}{$2}", "meta": "physics-cmd", "score": 0.0014087913646471247}, {"caption": "\\pdv{}{}{}", "snippet": "\\pdv{$1}{$2}{$3}", "meta": "physics-cmd", "score": 0.0014087913646471247}, {"caption": "\\braket{}{}", "snippet": "\\braket{$1}{$2}", "meta": "physics-cmd", "score": 0.004421747491186916}, {"caption": "\\braket{}", "snippet": "\\braket{$1}", "meta": "physics-cmd", "score": 0.004421747491186916}, {"caption": "\\div", "snippet": "\\div", "meta": "physics-cmd", "score": 0.002403050103349905}, {"caption": "\\div{}", "snippet": "\\div{$1}", "meta": "physics-cmd", "score": 0.002403050103349905}, {"caption": "\\sin", "snippet": "\\sin", "meta": "physics-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "physics-cmd", "score": 0.040463088537699636}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "physics-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "physics-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "physics-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "physics-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "physics-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "physics-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "physics-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "physics-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "physics-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "physics-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "physics-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "physics-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "physics-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "physics-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "physics-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "physics-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "physics-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "physics-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "physics-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "physics-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "physics-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "physics-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "physics-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "physics-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "physics-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "physics-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "physics-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "physics-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "physics-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "physics-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "physics-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "physics-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "physics-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "physics-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "physics-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "physics-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "physics-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "physics-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "physics-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "physics-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "physics-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "physics-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "physics-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "physics-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "physics-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "physics-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "physics-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "physics-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "physics-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "physics-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "physics-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "physics-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "physics-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "physics-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "physics-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "physics-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "physics-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "physics-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "physics-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "physics-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "physics-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "physics-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "physics-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "physics-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "physics-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "physics-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "physics-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "physics-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "physics-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "physics-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "physics-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "physics-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "physics-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "physics-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "physics-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "physics-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "physics-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "physics-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "physics-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "physics-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "physics-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "physics-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "physics-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "physics-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "physics-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "physics-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "physics-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "physics-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "physics-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "physics-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "physics-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "physics-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "physics-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "physics-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "physics-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "physics-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "physics-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "physics-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "physics-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "physics-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "physics-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "physics-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "physics-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "physics-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "physics-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "physics-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "physics-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "physics-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "physics-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "physics-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "physics-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "physics-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "physics-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "physics-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "physics-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "physics-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "physics-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "physics-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "physics-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "physics-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "physics-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "physics-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "physics-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "physics-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "physics-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "physics-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "physics-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "physics-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "physics-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "physics-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "physics-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "physics-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "physics-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "physics-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "physics-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "physics-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "physics-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "physics-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "physics-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "physics-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "physics-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "physics-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "physics-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "physics-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "physics-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "physics-cmd", "score": 0.0004286136584068833}, {"caption": "\\do", "snippet": "\\do", "meta": "physics-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "physics-cmd", "score": 0.0063276692758974925}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "physics-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "physics-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "physics-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "physics-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "physics-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "physics-cmd", "score": 0.2864294797053033}], "authblk": [{"caption": "\\Authfont{}", "snippet": "\\Authfont{$1}", "meta": "authblk-cmd", "score": 0.00019538157043798684}, {"caption": "\\thanks{}", "snippet": "\\thanks{$1}", "meta": "authblk-cmd", "score": 0.08382259880654083}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "authblk-cmd", "score": 0.7504160124360846}, {"caption": "\\rlap{}", "snippet": "\\rlap{$1}", "meta": "authblk-cmd", "score": 0.01269300721396509}, {"caption": "\\Authands{}", "snippet": "\\Authands{$1}", "meta": "authblk-cmd", "score": 0.00043932814970131613}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "authblk-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "authblk-cmd", "score": 0.8973590434087177}, {"caption": "\\textsuperscript{}", "snippet": "\\textsuperscript{$1}", "meta": "authblk-cmd", "score": 0.05216393882408519}, {"caption": "\\Affilfont{}", "snippet": "\\Affilfont{$1}", "meta": "authblk-cmd", "score": 0.0004505484831792931}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "authblk-cmd", "score": 0.2253056071787701}, {"caption": "\\affil[]{}", "snippet": "\\affil[$1]{$2}", "meta": "authblk-cmd", "score": 0.014174618039587864}, {"caption": "\\affil{}", "snippet": "\\affil{$1}", "meta": "authblk-cmd", "score": 0.014174618039587864}], "tabu": [{"caption": "\\extrarowheight", "snippet": "\\extrarowheight", "meta": "tabu-cmd", "score": 0.003735645243417412}, {"caption": "\\extrarowheight{}", "snippet": "\\extrarowheight{$1}", "meta": "tabu-cmd", "score": 0.003735645243417412}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "tabu-cmd", "score": 0.5473606021405326}, {"caption": "\\do", "snippet": "\\do", "meta": "tabu-cmd", "score": 0.009278344180101056}, {"caption": "\\hfill", "snippet": "\\hfill", "meta": "tabu-cmd", "score": 0.2058248088519886}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "tabu-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "tabu-cmd", "score": 0.022224283488673075}, {"caption": "\\tabulinesep", "snippet": "\\tabulinesep", "meta": "tabu-cmd", "score": 0.0008256968285249214}, {"caption": "\\hskip", "snippet": "\\hskip", "meta": "tabu-cmd", "score": 0.04339822811565144}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "tabu-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "tabu-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "tabu-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "tabu-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "tabu-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tabu-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "tabu-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "tabu-cmd", "score": 0.018615449342361392}, {"caption": "\\par", "snippet": "\\par", "meta": "tabu-cmd", "score": 0.413853376001159}], "CJKutf8": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "CJKutf8-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "CJKutf8-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "CJKutf8-cmd", "score": 0.021170869458413965}, {"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "CJKutf8-cmd", "score": 0.04598628699063736}, {"caption": "\\inputencoding{}", "snippet": "\\inputencoding{$1}", "meta": "CJKutf8-cmd", "score": 0.0002447047447770061}], "sectsty": [{"caption": "\\chapterfont{}", "snippet": "\\chapterfont{$1}", "meta": "sectsty-cmd", "score": 0.0001572081344977262}, {"caption": "\\raggedright", "snippet": "\\raggedright", "meta": "sectsty-cmd", "score": 0.05314494127699766}, {"caption": "\\sectionfont{}", "snippet": "\\sectionfont{$1}", "meta": "sectsty-cmd", "score": 0.003867941482301249}, {"caption": "\\paragraph{}", "snippet": "\\paragraph{$1}", "meta": "sectsty-cmd", "score": 0.152074250347974}, {"caption": "\\allsectionsfont{}", "snippet": "\\allsectionsfont{$1}", "meta": "sectsty-cmd", "score": 0.0011367198619746117}, {"caption": "\\subsection{}", "snippet": "\\subsection{$1}", "meta": "sectsty-cmd", "score": 1.3890912739512353}, {"caption": "\\subsectionfont{}", "snippet": "\\subsectionfont{$1}", "meta": "sectsty-cmd", "score": 0.002811633808315226}, {"caption": "\\interlinepenalty", "snippet": "\\interlinepenalty", "meta": "sectsty-cmd", "score": 0.00032069955588347133}, {"caption": "\\subsubsectionfont{}", "snippet": "\\subsubsectionfont{$1}", "meta": "sectsty-cmd", "score": 0.0011363939259266408}, {"caption": "\\underline{}", "snippet": "\\underline{$1}", "meta": "sectsty-cmd", "score": 0.14748550887002482}, {"caption": "\\subsubsection{}", "snippet": "\\subsubsection{$1}", "meta": "sectsty-cmd", "score": 0.3727781330132016}, {"caption": "\\section{}", "snippet": "\\section{$1}", "meta": "sectsty-cmd", "score": 3.0952612541683835}], "lscape": [{"caption": "\\csname", "snippet": "\\csname", "meta": "lscape-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "lscape-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "lscape-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "lscape-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "lscape-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "lscape-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "lscape-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "lscape-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "lscape-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "lscape-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "lscape-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "lscape-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "lscape-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "lscape-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "lscape-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "lscape-cmd", "score": 0.004649150613625593}], "hyphenat": [{"caption": "\\hyp{}", "snippet": "\\hyp{$1}", "meta": "hyphenat-cmd", "score": 0.0013359874951570454}], "tocloft": [{"caption": "\\cftsecleader", "snippet": "\\cftsecleader", "meta": "tocloft-cmd", "score": 0.0011340882025681251}, {"caption": "\\cftloftitlefont", "snippet": "\\cftloftitlefont", "meta": "tocloft-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\cftchappresnum{}", "snippet": "\\cftchappresnum{$1}", "meta": "tocloft-cmd", "score": 2.8671864736205568e-05}, {"caption": "\\cftchappresnum", "snippet": "\\cftchappresnum", "meta": "tocloft-cmd", "score": 2.8671864736205568e-05}, {"caption": "\\listoftables", "snippet": "\\listoftables", "meta": "tocloft-cmd", "score": 0.02104656820469027}, {"caption": "\\cftsecfont{}", "snippet": "\\cftsecfont{$1}", "meta": "tocloft-cmd", "score": 5.630015640183448e-05}, {"caption": "\\cftchapfont{}", "snippet": "\\cftchapfont{$1}", "meta": "tocloft-cmd", "score": 6.253521408609416e-05}, {"caption": "\\cftchapfont", "snippet": "\\cftchapfont", "meta": "tocloft-cmd", "score": 6.253521408609416e-05}, {"caption": "\\cftsubsecleader", "snippet": "\\cftsubsecleader", "meta": "tocloft-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\cftchapleader", "snippet": "\\cftchapleader", "meta": "tocloft-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\tocloftpagestyle{}", "snippet": "\\tocloftpagestyle{$1}", "meta": "tocloft-cmd", "score": 8.392451158032374e-05}, {"caption": "\\cfttoctitlefont", "snippet": "\\cfttoctitlefont", "meta": "tocloft-cmd", "score": 6.877027177035383e-05}, {"caption": "\\cftdot", "snippet": "\\cftdot", "meta": "tocloft-cmd", "score": 1.6201749367686227e-05}, {"caption": "\\cftsecdotsep", "snippet": "\\cftsecdotsep", "meta": "tocloft-cmd", "score": 0.0029383990986223767}, {"caption": "\\cftafterloftitle", "snippet": "\\cftafterloftitle", "meta": "tocloft-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\listoffigures", "snippet": "\\listoffigures", "meta": "tocloft-cmd", "score": 0.03447318897846567}, {"caption": "\\cftdotfill{}", "snippet": "\\cftdotfill{$1}", "meta": "tocloft-cmd", "score": 0.006027562229085753}, {"caption": "\\tableofcontents", "snippet": "\\tableofcontents", "meta": "tocloft-cmd", "score": 0.13360595130994957}, {"caption": "\\cftdotsep", "snippet": "\\cftdotsep", "meta": "tocloft-cmd", "score": 0.003089163130463376}, {"caption": "\\numberline{}", "snippet": "\\numberline{$1}", "meta": "tocloft-cmd", "score": 0.007461440567272885}, {"caption": "\\cftlottitlefont", "snippet": "\\cftlottitlefont", "meta": "tocloft-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\cftchappagefont{}", "snippet": "\\cftchappagefont{$1}", "meta": "tocloft-cmd", "score": 5.630015640183448e-05}, {"caption": "\\cftsetindents{}{}{}", "snippet": "\\cftsetindents{$1}{$2}{$3}", "meta": "tocloft-cmd", "score": 0.00043647269161217853}, {"caption": "\\cftsecpagefont{}", "snippet": "\\cftsecpagefont{$1}", "meta": "tocloft-cmd", "score": 5.630015640183448e-05}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "tocloft-cmd", "score": 0.0174633138331273}, {"caption": "\\cftaftertoctitle", "snippet": "\\cftaftertoctitle", "meta": "tocloft-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\cftafterlottitle", "snippet": "\\cftafterlottitle", "meta": "tocloft-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\newlistof{}{}{}", "snippet": "\\newlistof{$1}{$2}{$3}", "meta": "tocloft-cmd", "score": 0.0005381264966408724}], "glossaries": [{"caption": "\\glslongpluralkey", "snippet": "\\glslongpluralkey", "meta": "glossaries-cmd", "score": 1.4538687447297259e-05}, {"caption": "\\Glspl{}", "snippet": "\\Glspl{$1}", "meta": "glossaries-cmd", "score": 0.0025291265119320736}, {"caption": "\\glossarysection", "snippet": "\\glossarysection", "meta": "glossaries-cmd", "score": 9.579755294730752e-05}, {"caption": "\\printglossaries", "snippet": "\\printglossaries", "meta": "glossaries-cmd", "score": 0.0010106582768889887}, {"caption": "\\Gls{}", "snippet": "\\Gls{$1}", "meta": "glossaries-cmd", "score": 0.003696678698317109}, {"caption": "\\setglossarystyle{}", "snippet": "\\setglossarystyle{$1}", "meta": "glossaries-cmd", "score": 0.0003758893277679221}, {"caption": "\\printglossary", "snippet": "\\printglossary", "meta": "glossaries-cmd", "score": 0.009139682306158714}, {"caption": "\\printglossary[]", "snippet": "\\printglossary[$1]", "meta": "glossaries-cmd", "score": 0.009139682306158714}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-cmd", "score": 0.009278344180101056}, {"caption": "\\setglossarysection{}", "snippet": "\\setglossarysection{$1}", "meta": "glossaries-cmd", "score": 3.6081414102781514e-05}, {"caption": "\\glsresetall", "snippet": "\\glsresetall", "meta": "glossaries-cmd", "score": 0.0006123462672467326}, {"caption": "\\the", "snippet": "\\the", "meta": "glossaries-cmd", "score": 0.007238960303946444}, {"caption": "\\acrshort{}", "snippet": "\\acrshort{$1}", "meta": "glossaries-cmd", "score": 0.009936841864059727}, {"caption": "\\printnoidxglossary[]", "snippet": "\\printnoidxglossary[$1]", "meta": "glossaries-cmd", "score": 0.00021912375285685037}, {"caption": "\\newglossary{}{}", "snippet": "\\newglossary{$1}{$2}", "meta": "glossaries-cmd", "score": 1.4547244650032571e-05}, {"caption": "\\gls{}", "snippet": "\\gls{$1}", "meta": "glossaries-cmd", "score": 0.06939353309055077}, {"caption": "\\printnoidxglossaries", "snippet": "\\printnoidxglossaries", "meta": "glossaries-cmd", "score": 5.6789564226023136e-05}, {"caption": "\\printindex", "snippet": "\\printindex", "meta": "glossaries-cmd", "score": 0.004417016910870522}, {"caption": "\\defglsentryfmt[]{}", "snippet": "\\defglsentryfmt[$1]{$2}", "meta": "glossaries-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\glspostdescription", "snippet": "\\glspostdescription", "meta": "glossaries-cmd", "score": 0.0006337376579591112}, {"caption": "\\number", "snippet": "\\number", "meta": "glossaries-cmd", "score": 0.000968714260809983}, {"caption": "\\glsaddall", "snippet": "\\glsaddall", "meta": "glossaries-cmd", "score": 0.0008363820557740373}, {"caption": "\\glsaddall[]", "snippet": "\\glsaddall[$1]", "meta": "glossaries-cmd", "score": 0.0008363820557740373}, {"caption": "\\makeglossaries", "snippet": "\\makeglossaries", "meta": "glossaries-cmd", "score": 0.0056737600836936995}, {"caption": "\\glossaryname", "snippet": "\\glossaryname", "meta": "glossaries-cmd", "score": 0.0006174536302752427}, {"caption": "\\newglossaryentry{}{}", "snippet": "\\newglossaryentry{$1}{$2}", "meta": "glossaries-cmd", "score": 0.018524394136900962}, {"caption": "\\glslabel", "snippet": "\\glslabel", "meta": "glossaries-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\glsadd{}", "snippet": "\\glsadd{$1}", "meta": "glossaries-cmd", "score": 3.0150373480213892e-05}, {"caption": "\\makenoidxglossaries", "snippet": "\\makenoidxglossaries", "meta": "glossaries-cmd", "score": 0.0001382210125680805}, {"caption": "\\glsgenentryfmt", "snippet": "\\glsgenentryfmt", "meta": "glossaries-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\acronymtype", "snippet": "\\acronymtype", "meta": "glossaries-cmd", "score": 0.002000834271117562}, {"caption": "\\acrfull{}", "snippet": "\\acrfull{$1}", "meta": "glossaries-cmd", "score": 0.0032622587277765067}, {"caption": "\\newacronym{}{}{}", "snippet": "\\newacronym{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 0.03193935544723102}, {"caption": "\\glspl{}", "snippet": "\\glspl{$1}", "meta": "glossaries-cmd", "score": 0.0034025897522047717}, {"caption": "\\ifglsused{}{}{}", "snippet": "\\ifglsused{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\acrlong{}", "snippet": "\\acrlong{$1}", "meta": "glossaries-cmd", "score": 0.002517821598213752}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "glossaries-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "glossaries-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "glossaries-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "glossaries-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "glossaries-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "glossaries-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "glossaries-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "glossaries-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "glossaries-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "glossaries-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "glossaries-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "glossaries-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "glossaries-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "glossaries-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "glossaries-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "glossaries-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "glossaries-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "glossaries-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "glossaries-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "glossaries-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "glossaries-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "glossaries-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "glossaries-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "glossaries-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "glossaries-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "glossaries-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "glossaries-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "glossaries-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "glossaries-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "glossaries-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "glossaries-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "glossaries-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "glossaries-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "glossaries-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "glossaries-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "glossaries-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "glossaries-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "glossaries-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "glossaries-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "glossaries-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "glossaries-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "glossaries-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "glossaries-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "glossaries-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "glossaries-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "glossaries-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "glossaries-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "glossaries-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "glossaries-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "glossaries-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "glossaries-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "glossaries-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "glossaries-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "glossaries-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "glossaries-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "glossaries-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "glossaries-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "glossaries-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "glossaries-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "glossaries-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "glossaries-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "glossaries-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "glossaries-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "glossaries-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "glossaries-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "glossaries-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "glossaries-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "glossaries-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "glossaries-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "glossaries-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "glossaries-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "glossaries-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "glossaries-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "glossaries-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "glossaries-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "glossaries-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "glossaries-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "glossaries-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "glossaries-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "glossaries-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "glossaries-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "glossaries-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "glossaries-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "glossaries-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "glossaries-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "glossaries-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "glossaries-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "glossaries-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "glossaries-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "glossaries-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "glossaries-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "glossaries-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "glossaries-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "glossaries-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "glossaries-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "glossaries-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "glossaries-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "glossaries-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "glossaries-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "glossaries-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "glossaries-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "glossaries-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "glossaries-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "glossaries-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "glossaries-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "glossaries-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "glossaries-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "glossaries-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "glossaries-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "glossaries-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "glossaries-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "glossaries-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "glossaries-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "glossaries-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "glossaries-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "glossaries-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "glossaries-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "glossaries-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "glossaries-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "glossaries-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "glossaries-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "glossaries-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "glossaries-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "glossaries-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "glossaries-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "glossaries-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "glossaries-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "glossaries-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "glossaries-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "glossaries-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "glossaries-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "glossaries-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "glossaries-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "glossaries-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "glossaries-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "glossaries-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "glossaries-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "glossaries-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "glossaries-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "glossaries-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "glossaries-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "glossaries-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "glossaries-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "glossaries-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "glossaries-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "glossaries-cmd", "score": 0.008565354665444157}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "glossaries-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "glossaries-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "glossaries-cmd", "score": 0.18137737738638837}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "glossaries-cmd", "score": 2.341195220791228}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "glossaries-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "glossaries-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "glossaries-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "glossaries-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "glossaries-cmd", "score": 0.0018957469739775527}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "glossaries-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "glossaries-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "glossaries-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "glossaries-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "glossaries-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "glossaries-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "glossaries-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "glossaries-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "glossaries-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "glossaries-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "glossaries-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "glossaries-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "glossaries-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "glossaries-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "glossaries-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "glossaries-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "glossaries-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "glossaries-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "glossaries-cmd", "score": 0.0063276692758974925}], "cleveref": [{"caption": "\\crefdefaultlabelformat{}", "snippet": "\\crefdefaultlabelformat{$1}", "meta": "cleveref-cmd", "score": 8.401009062000455e-06}, {"caption": "\\crefname{}{}{}", "snippet": "\\crefname{$1}{$2}{$3}", "meta": "cleveref-cmd", "score": 0.0016963440482621792}, {"caption": "\\crefrangeformat{}{}", "snippet": "\\crefrangeformat{$1}{$2}", "meta": "cleveref-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "cleveref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "cleveref-cmd", "score": 0.021170869458413965}, {"caption": "\\crefmultiformat{}{}", "snippet": "\\crefmultiformat{$1}{$2}", "meta": "cleveref-cmd", "score": 0.00021116765384691477}, {"caption": "\\crefformat{}{}", "snippet": "\\crefformat{$1}{$2}", "meta": "cleveref-cmd", "score": 0.0006776840671975755}, {"caption": "\\Cref{}", "snippet": "\\Cref{$1}", "meta": "cleveref-cmd", "score": 0.0016649686371949341}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "cleveref-cmd", "score": 0.002140559856649122}, {"caption": "\\cref{}", "snippet": "\\cref{$1}", "meta": "cleveref-cmd", "score": 0.0159491058092361}, {"caption": "\\crefrangeconjunction", "snippet": "\\crefrangeconjunction", "meta": "cleveref-cmd", "score": 3.2405622997778076e-06}, {"caption": "\\csname", "snippet": "\\csname", "meta": "cleveref-cmd", "score": 0.008565354665444157}, {"caption": "\\creflabelformat{}{}", "snippet": "\\creflabelformat{$1}{$2}", "meta": "cleveref-cmd", "score": 0.000997031755478214}, {"caption": "\\Crefname{}{}{}", "snippet": "\\Crefname{$1}{$2}{$3}", "meta": "cleveref-cmd", "score": 0.000239288793927364}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "cleveref-cmd", "score": 1.897791904799601}, {"caption": "\\labelcref{}", "snippet": "\\labelcref{$1}", "meta": "cleveref-cmd", "score": 6.720807249600364e-05}, {"caption": "\\creflastconjunction", "snippet": "\\creflastconjunction", "meta": "cleveref-cmd", "score": 3.2405622997778076e-06}], "eso-pic": [{"caption": "\\AddToShipoutPictureFG{}", "snippet": "\\AddToShipoutPictureFG{$1}", "meta": "eso-pic-cmd", "score": 0.000325977535138643}, {"caption": "\\AddToShipoutPictureBG{}", "snippet": "\\AddToShipoutPictureBG{$1}", "meta": "eso-pic-cmd", "score": 0.0008957666085644653}, {"caption": "\\AtPageUpperLeft{}", "snippet": "\\AtPageUpperLeft{$1}", "meta": "eso-pic-cmd", "score": 0.0003608141410278152}, {"caption": "\\LenToUnit{}", "snippet": "\\LenToUnit{$1}", "meta": "eso-pic-cmd", "score": 0.0007216282820556304}, {"caption": "\\AddToShipoutPicture{}", "snippet": "\\AddToShipoutPicture{$1}", "meta": "eso-pic-cmd", "score": 0.0017658629469099734}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "eso-pic-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "eso-pic-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "eso-pic-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "eso-pic-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "eso-pic-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "eso-pic-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "eso-pic-cmd", "score": 0.008565354665444157}], "mhchem": [{"caption": "\\ce{}", "snippet": "\\ce{$1}", "meta": "mhchem-cmd", "score": 0.04246600383063094}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mhchem-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mhchem-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "mhchem-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "mhchem-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "mhchem-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "mhchem-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "mhchem-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mhchem-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "mhchem-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mhchem-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "mhchem-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "mhchem-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "mhchem-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "mhchem-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "mhchem-cmd", "score": 0.004649150613625593}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "mhchem-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "mhchem-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "mhchem-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "mhchem-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "mhchem-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "mhchem-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "mhchem-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "mhchem-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "mhchem-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "mhchem-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "mhchem-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "mhchem-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "mhchem-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "mhchem-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "mhchem-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "mhchem-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "mhchem-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "mhchem-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "mhchem-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "mhchem-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "mhchem-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "mhchem-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "mhchem-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "mhchem-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "mhchem-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "mhchem-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "mhchem-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "mhchem-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "mhchem-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "mhchem-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "mhchem-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "mhchem-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "mhchem-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "mhchem-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "mhchem-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "mhchem-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "mhchem-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "mhchem-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "mhchem-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "mhchem-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "mhchem-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "mhchem-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "mhchem-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "mhchem-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "mhchem-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "mhchem-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "mhchem-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "mhchem-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "mhchem-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "mhchem-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "mhchem-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "mhchem-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "mhchem-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "mhchem-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "mhchem-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "mhchem-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "mhchem-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "mhchem-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "mhchem-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "mhchem-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "mhchem-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "mhchem-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "mhchem-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "mhchem-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "mhchem-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "mhchem-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "mhchem-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "mhchem-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "mhchem-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "mhchem-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "mhchem-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "mhchem-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "mhchem-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "mhchem-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "mhchem-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "mhchem-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "mhchem-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "mhchem-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "mhchem-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "mhchem-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "mhchem-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "mhchem-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "mhchem-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "mhchem-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "mhchem-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "mhchem-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "mhchem-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "mhchem-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "mhchem-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "mhchem-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "mhchem-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "mhchem-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "mhchem-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "mhchem-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "mhchem-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "mhchem-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "mhchem-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "mhchem-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "mhchem-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "mhchem-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "mhchem-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "mhchem-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "mhchem-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "mhchem-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "mhchem-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "mhchem-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "mhchem-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "mhchem-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "mhchem-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "mhchem-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "mhchem-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "mhchem-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "mhchem-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "mhchem-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "mhchem-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "mhchem-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "mhchem-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "mhchem-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "mhchem-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "mhchem-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "mhchem-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "mhchem-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "mhchem-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "mhchem-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "mhchem-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "mhchem-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "mhchem-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "mhchem-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "mhchem-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "mhchem-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "mhchem-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "mhchem-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "mhchem-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "mhchem-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "mhchem-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "mhchem-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "mhchem-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "mhchem-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "mhchem-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "mhchem-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "mhchem-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "mhchem-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "mhchem-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "mhchem-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "mhchem-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "mhchem-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mhchem-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "mhchem-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "mhchem-cmd", "score": 0.2864294797053033}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "mhchem-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "mhchem-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "mhchem-cmd", "score": 0.18137737738638837}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "mhchem-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "mhchem-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "mhchem-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mhchem-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mhchem-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "mhchem-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "mhchem-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "mhchem-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "mhchem-cmd", "score": 0.028955796305270766}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mhchem-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "mhchem-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "mhchem-cmd", "score": 0.0063276692758974925}], "amscd": [{"caption": "\\tag{}", "snippet": "\\tag{$1}", "meta": "amscd-cmd", "score": 0.00784357461002059}, {"caption": "\\do", "snippet": "\\do", "meta": "amscd-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amscd-cmd", "score": 0.0063276692758974925}], "unicode-math": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "unicode-math-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "unicode-math-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "unicode-math-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "unicode-math-cmd", "score": 0.2864294797053033}], "ifxetex": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "ifxetex-cmd", "score": 0.00021116765384691477}], "newtxmath": [{"caption": "\\int", "snippet": "\\int", "meta": "newtxmath-cmd", "score": 0.11946660537765894}, {"caption": "\\sqrt{}", "snippet": "\\sqrt{$1}", "meta": "newtxmath-cmd", "score": 0.20240160977404634}, {"caption": "\\prod", "snippet": "\\prod", "meta": "newtxmath-cmd", "score": 0.02549889375975901}, {"caption": "\\hbar", "snippet": "\\hbar", "meta": "newtxmath-cmd", "score": 0.024733493787737763}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "newtxmath-cmd", "score": 0.006473769486518971}, {"caption": "\\surd", "snippet": "\\surd", "meta": "newtxmath-cmd", "score": 0.002159694087964359}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "newtxmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\sum", "snippet": "\\sum", "meta": "newtxmath-cmd", "score": 0.42607994509619934}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "newtxmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "newtxmath-cmd", "score": 0.015507614799858266}, {"caption": "\\vdots", "snippet": "\\vdots", "meta": "newtxmath-cmd", "score": 0.03669355896719803}, {"caption": "\\ddots", "snippet": "\\ddots", "meta": "newtxmath-cmd", "score": 0.010831382784078964}, {"caption": "\\csname", "snippet": "\\csname", "meta": "newtxmath-cmd", "score": 0.008565354665444157}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "newtxmath-cmd", "score": 0.04318078602869565}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "newtxmath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "newtxmath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "newtxmath-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "newtxmath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "newtxmath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "newtxmath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "newtxmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "newtxmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "newtxmath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "newtxmath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "newtxmath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "newtxmath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "newtxmath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "newtxmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "newtxmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "newtxmath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "newtxmath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "newtxmath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "newtxmath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "newtxmath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "newtxmath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "newtxmath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "newtxmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "newtxmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "newtxmath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "newtxmath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "newtxmath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "newtxmath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "newtxmath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "newtxmath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "newtxmath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "newtxmath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "newtxmath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "newtxmath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "newtxmath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "newtxmath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "newtxmath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "newtxmath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "newtxmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "newtxmath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "newtxmath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "newtxmath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "newtxmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "newtxmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "newtxmath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "newtxmath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "newtxmath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "newtxmath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "newtxmath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "newtxmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "newtxmath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "newtxmath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "newtxmath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "newtxmath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "newtxmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "newtxmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "newtxmath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "newtxmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "newtxmath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "newtxmath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "newtxmath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "newtxmath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "newtxmath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "newtxmath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "newtxmath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "newtxmath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "newtxmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "newtxmath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "newtxmath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "newtxmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "newtxmath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "newtxmath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "newtxmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "newtxmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "newtxmath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "newtxmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "newtxmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "newtxmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "newtxmath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "newtxmath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "newtxmath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "newtxmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "newtxmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "newtxmath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "newtxmath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "newtxmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "newtxmath-cmd", "score": 0.00021116765384691477}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "newtxmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "newtxmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "newtxmath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "newtxmath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "newtxmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "newtxmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "newtxmath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "newtxmath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "newtxmath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "newtxmath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "newtxmath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "newtxmath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "newtxmath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "newtxmath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "newtxmath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "newtxmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "newtxmath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "newtxmath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "newtxmath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "newtxmath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "newtxmath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "newtxmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "newtxmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "newtxmath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "newtxmath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "newtxmath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "newtxmath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "newtxmath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "newtxmath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "newtxmath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "newtxmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "newtxmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "newtxmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "newtxmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "newtxmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "newtxmath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "newtxmath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "newtxmath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "newtxmath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "newtxmath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "newtxmath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "newtxmath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "newtxmath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "newtxmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "newtxmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "newtxmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "newtxmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "newtxmath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "newtxmath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "newtxmath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "newtxmath-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "newtxmath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "newtxmath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "newtxmath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "newtxmath-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "newtxmath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "newtxmath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "newtxmath-cmd", "score": 0.0063276692758974925}], "pdflscape": [{"caption": "\\csname", "snippet": "\\csname", "meta": "pdflscape-cmd", "score": 0.008565354665444157}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "pdflscape-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pdflscape-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pdflscape-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pdflscape-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pdflscape-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pdflscape-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pdflscape-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pdflscape-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pdflscape-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pdflscape-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pdflscape-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pdflscape-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pdflscape-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pdflscape-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pdflscape-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pdflscape-cmd", "score": 0.004649150613625593}], "apacite": [{"caption": "\\citep{}", "snippet": "\\citep{$1}", "meta": "apacite-cmd", "score": 0.2941882834697057}, {"caption": "\\citet{}", "snippet": "\\citet{$1}", "meta": "apacite-cmd", "score": 0.09046048561361801}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "apacite-cmd", "score": 0.13586474005868793}, {"caption": "\\BPGS", "snippet": "\\BPGS", "meta": "apacite-cmd", "score": 0.00023651453263545777}, {"caption": "\\shortcite{}", "snippet": "\\shortcite{$1}", "meta": "apacite-cmd", "score": 0.010082057767216608}, {"caption": "\\shortciteA{}", "snippet": "\\shortciteA{$1}", "meta": "apacite-cmd", "score": 0.0011019769466422762}, {"caption": "\\nocite{}", "snippet": "\\nocite{$1}", "meta": "apacite-cmd", "score": 0.04990693820960752}, {"caption": "\\refname", "snippet": "\\refname", "meta": "apacite-cmd", "score": 0.006490238196722249}, {"caption": "\\refname{}", "snippet": "\\refname{$1}", "meta": "apacite-cmd", "score": 0.006490238196722249}, {"caption": "\\citeA{}", "snippet": "\\citeA{$1}", "meta": "apacite-cmd", "score": 0.008470555729707068}, {"caption": "\\citeyear{}", "snippet": "\\citeyear{$1}", "meta": "apacite-cmd", "score": 0.01091041305836494}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "apacite-cmd", "score": 2.341195220791228}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "apacite-cmd", "score": 0.2659628337907604}, {"caption": "\\BPG", "snippet": "\\BPG", "meta": "apacite-cmd", "score": 0.00023651453263545777}, {"caption": "\\citeNP{}", "snippet": "\\citeNP{$1}", "meta": "apacite-cmd", "score": 0.0003168688289795556}, {"caption": "\\citeauthor{}", "snippet": "\\citeauthor{$1}", "meta": "apacite-cmd", "score": 0.01359248786373484}], "mathpazo": [{"caption": "\\big", "snippet": "\\big", "meta": "mathpazo-cmd", "score": 0.05613164277964739}, {"caption": "\\mathbb{}", "snippet": "\\mathbb{$1}", "meta": "mathpazo-cmd", "score": 0.33740449739178857}, {"caption": "\\Big", "snippet": "\\Big", "meta": "mathpazo-cmd", "score": 0.050370758781422345}], "footmisc": [{"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "footmisc-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "footmisc-cmd", "score": 0.0003680857021151614}, {"caption": "\\protect", "snippet": "\\protect", "meta": "footmisc-cmd", "score": 0.0200686676229443}, {"caption": "\\multfootsep", "snippet": "\\multfootsep", "meta": "footmisc-cmd", "score": 0.00010171098214158578}, {"caption": "\\footnotelayout", "snippet": "\\footnotelayout", "meta": "footmisc-cmd", "score": 0.0004535003423927585}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "footmisc-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "footmisc-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "footmisc-cmd", "score": 0.021473212893597875}, {"caption": "\\thefootnote", "snippet": "\\thefootnote", "meta": "footmisc-cmd", "score": 0.007676927812687567}, {"caption": "\\thefootnote{}", "snippet": "\\thefootnote{$1}", "meta": "footmisc-cmd", "score": 0.007676927812687567}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "footmisc-cmd", "score": 0.1789117552185788}], "fixltx2e": [{"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "fixltx2e-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "fixltx2e-cmd", "score": 0.354445763583904}, {"caption": "\\textsubscript{}", "snippet": "\\textsubscript{$1}", "meta": "fixltx2e-cmd", "score": 0.058405875394131175}, {"caption": "\\em", "snippet": "\\em", "meta": "fixltx2e-cmd", "score": 0.10357353994640862}], "sidecap": [{"caption": "\\csname", "snippet": "\\csname", "meta": "sidecap-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "sidecap-cmd", "score": 1.2569477427490174}, {"caption": "\\sidecaptionvpos{}{}", "snippet": "\\sidecaptionvpos{$1}{$2}", "meta": "sidecap-cmd", "score": 0.0006587927449241846}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "sidecap-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "sidecap-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "sidecap-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "sidecap-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "sidecap-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "sidecap-cmd", "score": 0.0018957469739775527}], "nomencl": [{"caption": "\\nomenclature[]{}{}", "snippet": "\\nomenclature[$1]{$2}{$3}", "meta": "nomencl-cmd", "score": 0.016053526743355948}, {"caption": "\\nomenclature{}{}", "snippet": "\\nomenclature{$1}{$2}", "meta": "nomencl-cmd", "score": 0.016053526743355948}, {"caption": "\\nomlabel", "snippet": "\\nomlabel", "meta": "nomencl-cmd", "score": 6.353668036093916e-05}, {"caption": "\\printnomenclature", "snippet": "\\printnomenclature", "meta": "nomencl-cmd", "score": 0.0014526113324237952}, {"caption": "\\printnomenclature[]", "snippet": "\\printnomenclature[$1]", "meta": "nomencl-cmd", "score": 0.0014526113324237952}, {"caption": "\\makenomenclature", "snippet": "\\makenomenclature", "meta": "nomencl-cmd", "score": 0.002310610204652063}, {"caption": "\\nomgroup", "snippet": "\\nomgroup", "meta": "nomencl-cmd", "score": 0.0005549290951493257}, {"caption": "\\nomgroup[]{}", "snippet": "\\nomgroup[$1]{$2}", "meta": "nomencl-cmd", "score": 0.0005549290951493257}, {"caption": "\\nomname", "snippet": "\\nomname", "meta": "nomencl-cmd", "score": 0.0015092617929470952}, {"caption": "\\nompreamble", "snippet": "\\nompreamble", "meta": "nomencl-cmd", "score": 2.4350510995473236e-05}, {"caption": "\\nomentryend", "snippet": "\\nomentryend", "meta": "nomencl-cmd", "score": 0.000137692304514793}], "afterpage": [{"caption": "\\afterpage{}", "snippet": "\\afterpage{$1}", "meta": "afterpage-cmd", "score": 0.0018578070791608345}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "afterpage-cmd", "score": 0.1789117552185788}], "titling": [{"caption": "\\thanks{}", "snippet": "\\thanks{$1}", "meta": "titling-cmd", "score": 0.08382259880654083}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "titling-cmd", "score": 0.7504160124360846}, {"caption": "\\posttitle{}", "snippet": "\\posttitle{$1}", "meta": "titling-cmd", "score": 0.002507149245154055}, {"caption": "\\postdate{}", "snippet": "\\postdate{$1}", "meta": "titling-cmd", "score": 0.002139478682489868}, {"caption": "\\predate{}", "snippet": "\\predate{$1}", "meta": "titling-cmd", "score": 0.002139478682489868}, {"caption": "\\preauthor{}", "snippet": "\\preauthor{$1}", "meta": "titling-cmd", "score": 0.0023736543205198435}, {"caption": "\\postauthor{}", "snippet": "\\postauthor{$1}", "meta": "titling-cmd", "score": 0.0023736543205198435}, {"caption": "\\pretitle{}", "snippet": "\\pretitle{$1}", "meta": "titling-cmd", "score": 0.002507149245154055}], "wasysym": [{"caption": "\\checked", "snippet": "\\checked", "meta": "wasysym-cmd", "score": 0.0027792832228568255}, {"caption": "\\int", "snippet": "\\int", "meta": "wasysym-cmd", "score": 0.11946660537765894}, {"caption": "\\diameter", "snippet": "\\diameter", "meta": "wasysym-cmd", "score": 0.0001645367385856751}, {"caption": "\\CIRCLE", "snippet": "\\CIRCLE", "meta": "wasysym-cmd", "score": 0.000250667024953401}], "eurosym": [{"caption": "\\EUR{}", "snippet": "\\EUR{$1}", "meta": "eurosym-cmd", "score": 3.661595357097087e-05}], "caption2": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "caption2-cmd", "score": 0.00037306820619479756}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "caption2-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "caption2-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "caption2-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "caption2-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "caption2-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "caption2-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "caption2-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "caption2-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "caption2-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "caption2-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "caption2-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "caption2-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "caption2-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "caption2-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "caption2-cmd", "score": 0.021473212893597875}], "amsbsy": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "amsbsy-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "amsbsy-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "amsbsy-cmd", "score": 0.18137737738638837}, {"caption": "\\do", "snippet": "\\do", "meta": "amsbsy-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amsbsy-cmd", "score": 0.0063276692758974925}], "CJK": [{"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "CJK-cmd", "score": 0.04598628699063736}], "makecell": [{"caption": "\\diaghead{}{}{}", "snippet": "\\diaghead{$1}{$2}{$3}", "meta": "makecell-cmd", "score": 2.0417817976377812e-05}, {"caption": "\\makecell{}", "snippet": "\\makecell{$1}", "meta": "makecell-cmd", "score": 0.005023670619810683}, {"caption": "\\makecell[]{}", "snippet": "\\makecell[$1]{$2}", "meta": "makecell-cmd", "score": 0.005023670619810683}, {"caption": "\\height", "snippet": "\\height", "meta": "makecell-cmd", "score": 0.0045883162478394055}, {"caption": "\\height{}", "snippet": "\\height{$1}", "meta": "makecell-cmd", "score": 0.0045883162478394055}, {"caption": "\\setcellgapes{}", "snippet": "\\setcellgapes{$1}", "meta": "makecell-cmd", "score": 0.0004960838428758984}, {"caption": "\\thead{}", "snippet": "\\thead{$1}", "meta": "makecell-cmd", "score": 0.0023087638254186797}, {"caption": "\\Gape[]", "snippet": "\\Gape[$1]", "meta": "makecell-cmd", "score": 0.000469300371741866}, {"caption": "\\theadgape{}", "snippet": "\\theadgape{$1}", "meta": "makecell-cmd", "score": 0.000234650185870933}, {"caption": "\\theadalign", "snippet": "\\theadalign", "meta": "makecell-cmd", "score": 0.0006746935448099005}, {"caption": "\\theadalign{}", "snippet": "\\theadalign{$1}", "meta": "makecell-cmd", "score": 0.0006746935448099005}, {"caption": "\\theadset{}", "snippet": "\\theadset{$1}", "meta": "makecell-cmd", "score": 0.0004400433589389675}, {"caption": "\\Xhline{}", "snippet": "\\Xhline{$1}", "meta": "makecell-cmd", "score": 0.0024175651338281096}, {"caption": "\\theadfont{}", "snippet": "\\theadfont{$1}", "meta": "makecell-cmd", "score": 0.0007935193556772338}, {"caption": "\\theadfont", "snippet": "\\theadfont", "meta": "makecell-cmd", "score": 0.0007935193556772338}, {"caption": "\\cellgape{}", "snippet": "\\cellgape{$1}", "meta": "makecell-cmd", "score": 0.000234650185870933}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "makecell-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "makecell-cmd", "score": 0.022224283488673075}, {"caption": "\\makegapedcells", "snippet": "\\makegapedcells", "meta": "makecell-cmd", "score": 0.000431467454221244}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "makecell-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "makecell-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "makecell-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "makecell-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "makecell-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "makecell-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "makecell-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "makecell-cmd", "score": 0.018615449342361392}], "xeCJK": [{"caption": "\\setCJKmonofont{}", "snippet": "\\setCJKmonofont{$1}", "meta": "xeCJK-cmd", "score": 0.0057178353252375245}, {"caption": "\\setCJKmainfont{}", "snippet": "\\setCJKmainfont{$1}", "meta": "xeCJK-cmd", "score": 0.006622926778590894}, {"caption": "\\setCJKmainfont[]{}", "snippet": "\\setCJKmainfont[$1]{$2}", "meta": "xeCJK-cmd", "score": 0.006622926778590894}, {"caption": "\\setCJKsansfont{}", "snippet": "\\setCJKsansfont{$1}", "meta": "xeCJK-cmd", "score": 0.0057178353252375245}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xeCJK-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xeCJK-cmd", "score": 0.2864294797053033}], "threeparttable": [{"caption": "\\csname", "snippet": "\\csname", "meta": "threeparttable-cmd", "score": 0.008565354665444157}, {"caption": "\\item", "snippet": "\\item", "meta": "threeparttable-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "threeparttable-cmd", "score": 3.800886892251021}], "dirtytalk": [{"caption": "\\say{}", "snippet": "\\say{$1}", "meta": "dirtytalk-cmd", "score": 0.010246289746417045}, {"caption": "\\empty", "snippet": "\\empty", "meta": "dirtytalk-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "dirtytalk-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "dirtytalk-cmd", "score": 0.008565354665444157}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "dirtytalk-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "dirtytalk-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "dirtytalk-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "dirtytalk-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "dirtytalk-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "dirtytalk-cmd", "score": 0.0018957469739775527}, {"caption": "\\empty", "snippet": "\\empty", "meta": "dirtytalk-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "dirtytalk-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "dirtytalk-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "dirtytalk-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "dirtytalk-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "dirtytalk-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "dirtytalk-cmd", "score": 0.021170869458413965}], "balance": [{"caption": "\\balance", "snippet": "\\balance", "meta": "balance-cmd", "score": 0.003629066156300264}, {"caption": "\\balance{}", "snippet": "\\balance{$1}", "meta": "balance-cmd", "score": 0.003629066156300264}], "minted": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\usemintedstyle{}", "snippet": "\\usemintedstyle{$1}", "meta": "minted-cmd", "score": 0.00184279823796158}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\inputminted[]{}{}", "snippet": "\\inputminted[$1]{$2}{$3}", "meta": "minted-cmd", "score": 0.0016501519191680601}, {"caption": "\\inputminted{}{}", "snippet": "\\inputminted{$1}{$2}", "meta": "minted-cmd", "score": 0.0016501519191680601}, {"caption": "\\setminted[]{}", "snippet": "\\setminted[$1]{$2}", "meta": "minted-cmd", "score": 0.0004017914210172805}, {"caption": "\\setminted{}", "snippet": "\\setminted{$1}", "meta": "minted-cmd", "score": 0.0004017914210172805}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "minted-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "minted-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "minted-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "minted-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "minted-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "minted-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\listof{}{}", "snippet": "\\listof{$1}{$2}", "meta": "minted-cmd", "score": 0.0009837365348002915}, {"caption": "\\floatplacement{}{}", "snippet": "\\floatplacement{$1}{$2}", "meta": "minted-cmd", "score": 0.0005815474978918903}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "minted-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatstyle{}", "snippet": "\\floatstyle{$1}", "meta": "minted-cmd", "score": 0.0015470917047414941}, {"caption": "\\floatname{}{}", "snippet": "\\floatname{$1}{$2}", "meta": "minted-cmd", "score": 0.0011934321931750752}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "minted-cmd", "score": 1.2569477427490174}, {"caption": "\\newfloat{}{}{}", "snippet": "\\newfloat{$1}{$2}{$3}", "meta": "minted-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat", "snippet": "\\newfloat", "meta": "minted-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat{}", "snippet": "\\newfloat{$1}", "meta": "minted-cmd", "score": 0.0012745874472536625}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "minted-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "minted-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "minted-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "minted-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "minted-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "minted-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "minted-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "minted-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "minted-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "minted-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "minted-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "minted-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "minted-cmd", "score": 0.0018957469739775527}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\fbox{}", "snippet": "\\fbox{$1}", "meta": "minted-cmd", "score": 0.020865450075016792}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "minted-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\pagewiselinenumbers", "snippet": "\\pagewiselinenumbers", "meta": "minted-cmd", "score": 0.00016870831850106035}, {"caption": "\\linenomath", "snippet": "\\linenomath", "meta": "minted-cmd", "score": 1.4517338420208715e-05}, {"caption": "\\linenumberfont{}", "snippet": "\\linenumberfont{$1}", "meta": "minted-cmd", "score": 0.0001811784338695797}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\endlinenomath", "snippet": "\\endlinenomath", "meta": "minted-cmd", "score": 1.4517338420208715e-05}, {"caption": "\\nolinenumbers", "snippet": "\\nolinenumbers", "meta": "minted-cmd", "score": 0.0009805246614299932}, {"caption": "\\path", "snippet": "\\path", "meta": "minted-cmd", "score": 0.028200474217322108}, {"caption": "\\path[]", "snippet": "\\path[$1]", "meta": "minted-cmd", "score": 0.028200474217322108}, {"caption": "\\path{}", "snippet": "\\path{$1}", "meta": "minted-cmd", "score": 0.028200474217322108}, {"caption": "\\filedate{}", "snippet": "\\filedate{$1}", "meta": "minted-cmd", "score": 0.000578146635331119}, {"caption": "\\filedate", "snippet": "\\filedate", "meta": "minted-cmd", "score": 0.000578146635331119}, {"caption": "\\linenumbers", "snippet": "\\linenumbers", "meta": "minted-cmd", "score": 0.004687680659497865}, {"caption": "\\modulolinenumbers[]", "snippet": "\\modulolinenumbers[$1]", "meta": "minted-cmd", "score": 0.0027194991933605197}, {"caption": "\\fileversion{}", "snippet": "\\fileversion{$1}", "meta": "minted-cmd", "score": 0.000578146635331119}, {"caption": "\\fileversion", "snippet": "\\fileversion", "meta": "minted-cmd", "score": 0.000578146635331119}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "minted-cmd", "score": 0.021170869458413965}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "minted-cmd", "score": 0.002140559856649122}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "minted-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\fvset{}", "snippet": "\\fvset{$1}", "meta": "minted-cmd", "score": 0.00015476887282479622}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "minted-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "minted-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "minted-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "minted-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "minted-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "minted-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "minted-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "minted-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "minted-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "minted-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "minted-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "minted-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "minted-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "minted-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "minted-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "minted-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "minted-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "minted-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "minted-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "minted-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "minted-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "minted-cmd", "score": 0.008565354665444157}], "xifthen": [{"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "xifthen-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "xifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "xifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "xifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "xifthen-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "xifthen-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "xifthen-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "xifthen-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "xifthen-cmd", "score": 0.0018957469739775527}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "xifthen-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "xifthen-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "xifthen-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xifthen-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xifthen-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "xifthen-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "xifthen-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "xifthen-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "xifthen-cmd", "score": 0.028955796305270766}], "relsize": [{"caption": "\\mathlarger{}", "snippet": "\\mathlarger{$1}", "meta": "relsize-cmd", "score": 0.0031475241540308316}, {"caption": "\\smaller", "snippet": "\\smaller", "meta": "relsize-cmd", "score": 0.001271007880944704}], "epsf": [{"caption": "\\epsfbox{}", "snippet": "\\epsfbox{$1}", "meta": "epsf-cmd", "score": 0.00013712781345832882}], "datetime": [{"caption": "\\shortmonthname[]", "snippet": "\\shortmonthname[$1]", "meta": "datetime-cmd", "score": 0.00018524143860552933}, {"caption": "\\THEYEAR", "snippet": "\\THEYEAR", "meta": "datetime-cmd", "score": 8.638115929876123e-05}, {"caption": "\\currenttime", "snippet": "\\currenttime", "meta": "datetime-cmd", "score": 0.0002884868472087627}, {"caption": "\\monthname", "snippet": "\\monthname", "meta": "datetime-cmd", "score": 8.847106423071211e-05}, {"caption": "\\monthname[]", "snippet": "\\monthname[$1]", "meta": "datetime-cmd", "score": 8.847106423071211e-05}, {"caption": "\\today", "snippet": "\\today", "meta": "datetime-cmd", "score": 0.10733849317324783}, {"caption": "\\THEMONTH", "snippet": "\\THEMONTH", "meta": "datetime-cmd", "score": 8.638115929876123e-05}, {"caption": "\\yyyymmdddate", "snippet": "\\yyyymmdddate", "meta": "datetime-cmd", "score": 0.0002568405365040184}, {"caption": "\\pdfdate", "snippet": "\\pdfdate", "meta": "datetime-cmd", "score": 9.673490669434574e-05}, {"caption": "\\dateseparator", "snippet": "\\dateseparator", "meta": "datetime-cmd", "score": 0.00010966778823652713}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datetime-cmd", "score": 0.008565354665444157}, {"caption": "\\THEDAY", "snippet": "\\THEDAY", "meta": "datetime-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\usdate", "snippet": "\\usdate", "meta": "datetime-cmd", "score": 0.00020980148911330757}, {"caption": "\\newdateformat{}{}", "snippet": "\\newdateformat{$1}{$2}", "meta": "datetime-cmd", "score": 8.638115929876123e-05}, {"caption": "\\settimeformat{}", "snippet": "\\settimeformat{$1}", "meta": "datetime-cmd", "score": 0.00010966778823652713}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datetime-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "datetime-cmd", "score": 0.00037306820619479756}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "datetime-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "datetime-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "datetime-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "datetime-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "datetime-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "datetime-cmd", "score": 0.0018957469739775527}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "datetime-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datetime-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "datetime-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "datetime-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "datetime-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "datetime-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "datetime-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "datetime-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "datetime-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "datetime-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "datetime-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "datetime-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "datetime-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "datetime-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "datetime-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "datetime-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "datetime-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "datetime-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "datetime-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "datetime-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "datetime-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "datetime-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "datetime-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datetime-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "datetime-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "datetime-cmd", "score": 0.0063276692758974925}], "fontawesome": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "fontawesome-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "fontawesome-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "fontawesome-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "fontawesome-cmd", "score": 0.2864294797053033}], "forest": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "forest-cmd", "score": 0.00530510025314411}, {"caption": "\\bracketset{}", "snippet": "\\bracketset{$1}", "meta": "forest-cmd", "score": 0.00014301574866674164}, {"caption": "\\forestset{}", "snippet": "\\forestset{$1}", "meta": "forest-cmd", "score": 0.0020596473883671114}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "forest-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "forest-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "forest-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "forest-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "forest-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "forest-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "forest-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "forest-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "forest-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "forest-cmd", "score": 0.004649150613625593}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "forest-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "forest-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "forest-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "forest-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "forest-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "forest-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "forest-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "forest-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "forest-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "forest-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "forest-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "forest-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "forest-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "forest-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "forest-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "forest-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "forest-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "forest-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "forest-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "forest-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "forest-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "forest-cmd", "score": 0.2864294797053033}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "forest-cmd", "score": 0.004719094298848707}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "forest-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "forest-cmd", "score": 0.00031058155311734754}, {"caption": "\\csname", "snippet": "\\csname", "meta": "forest-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "forest-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "forest-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "forest-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "forest-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "forest-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "forest-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "forest-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "forest-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "forest-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "forest-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "forest-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "forest-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "forest-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "forest-cmd", "score": 0.2864294797053033}], "pgf": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgf-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgf-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgf-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgf-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgf-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgf-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgf-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgf-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgf-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgf-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgf-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgf-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgf-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgf-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgf-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgf-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgf-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgf-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgf-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgf-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgf-cmd", "score": 0.2864294797053033}], "pstricks": [{"caption": "\\green", "snippet": "\\green", "meta": "pstricks-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pstricks-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pstricks-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pstricks-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pstricks-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pstricks-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pstricks-cmd", "score": 0.006520475264573554}], "fancybox": [{"caption": "\\shadowbox{}", "snippet": "\\shadowbox{$1}", "meta": "fancybox-cmd", "score": 0.00107667147399019}, {"caption": "\\doublebox", "snippet": "\\doublebox", "meta": "fancybox-cmd", "score": 0.00015142240898356106}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "fancybox-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\thisfancypage{}{}", "snippet": "\\thisfancypage{$1}{$2}", "meta": "fancybox-cmd", "score": 0.00015142240898356106}, {"caption": "\\TheSbox", "snippet": "\\TheSbox", "meta": "fancybox-cmd", "score": 4.5350034239275855e-05}], "braket": [{"caption": "\\ket{}", "snippet": "\\ket{$1}", "meta": "braket-cmd", "score": 0.0326276280979336}, {"caption": "\\braket{}{}", "snippet": "\\braket{$1}{$2}", "meta": "braket-cmd", "score": 0.004421747491186916}, {"caption": "\\braket{}", "snippet": "\\braket{$1}", "meta": "braket-cmd", "score": 0.004421747491186916}, {"caption": "\\ketbra{}{}", "snippet": "\\ketbra{$1}{$2}", "meta": "braket-cmd", "score": 0.0006317858348936015}, {"caption": "\\ketbra", "snippet": "\\ketbra", "meta": "braket-cmd", "score": 0.0006317858348936015}, {"caption": "\\bra{}", "snippet": "\\bra{$1}", "meta": "braket-cmd", "score": 0.005609763332417241}, {"caption": "\\csname", "snippet": "\\csname", "meta": "braket-cmd", "score": 0.008565354665444157}], "import": [{"caption": "\\import{}{}", "snippet": "\\import{$1}{$2}", "meta": "import-cmd", "score": 0.1265354812350108}], "abntex2cite": [{"caption": "\\citeonline{}", "snippet": "\\citeonline{$1}", "meta": "abntex2cite-cmd", "score": 0.014277840409455324}, {"caption": "\\bibitem{}", "snippet": "\\bibitem{$1}", "meta": "abntex2cite-cmd", "score": 0.3689547570562042}, {"caption": "\\bibitem[]{}", "snippet": "\\bibitem[$1]{$2}", "meta": "abntex2cite-cmd", "score": 0.3689547570562042}, {"caption": "\\bibliographystyle{}", "snippet": "\\bibliographystyle{$1}", "meta": "abntex2cite-cmd", "score": 0.25122317941387773}, {"caption": "\\citeyear{}", "snippet": "\\citeyear{$1}", "meta": "abntex2cite-cmd", "score": 0.01091041305836494}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "abntex2cite-cmd", "score": 2.341195220791228}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "abntex2cite-cmd", "score": 0.2659628337907604}, {"caption": "\\setstretch{}", "snippet": "\\setstretch{$1}", "meta": "abntex2cite-cmd", "score": 0.019634763572332112}, {"caption": "\\onehalfspacing", "snippet": "\\onehalfspacing", "meta": "abntex2cite-cmd", "score": 0.010655415521079565}, {"caption": "\\singlespacing", "snippet": "\\singlespacing", "meta": "abntex2cite-cmd", "score": 0.008351544612280968}, {"caption": "\\doublespacing", "snippet": "\\doublespacing", "meta": "abntex2cite-cmd", "score": 0.007835428951987135}, {"caption": "\\baselinestretch", "snippet": "\\baselinestretch", "meta": "abntex2cite-cmd", "score": 0.03225350148161425}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "abntex2cite-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "abntex2cite-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "abntex2cite-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "abntex2cite-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "abntex2cite-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "abntex2cite-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "abntex2cite-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "abntex2cite-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "abntex2cite-cmd", "score": 0.028955796305270766}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "abntex2cite-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "abntex2cite-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "abntex2cite-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "abntex2cite-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "abntex2cite-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "abntex2cite-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "abntex2cite-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "abntex2cite-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "abntex2cite-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "abntex2cite-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "abntex2cite-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "abntex2cite-cmd", "score": 0.00021116765384691477}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "abntex2cite-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "abntex2cite-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "abntex2cite-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "abntex2cite-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "abntex2cite-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "abntex2cite-cmd", "score": 0.0018957469739775527}], "isodate": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "isodate-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "isodate-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "isodate-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "isodate-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "isodate-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "isodate-cmd", "score": 0.0018957469739775527}], "tcolorbox": [{"caption": "\\tcbset{}", "snippet": "\\tcbset{$1}", "meta": "tcolorbox-cmd", "score": 0.00012246447222402193}, {"caption": "\\tcbuselibrary{}", "snippet": "\\tcbuselibrary{$1}", "meta": "tcolorbox-cmd", "score": 4.347671035621014e-05}, {"caption": "\\newtcolorbox[]{}[][]{}", "snippet": "\\newtcolorbox[$1]{$2}[$3][$4]{$5}", "meta": "tcolorbox-cmd", "score": 7.216282820556303e-05}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "tcolorbox-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "tcolorbox-cmd", "score": 0.022224283488673075}, {"caption": "\\newtcbox{}[][]{}", "snippet": "\\newtcbox{$1}[$2][$3]{$4}", "meta": "tcolorbox-cmd", "score": 3.558785984219631e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tcolorbox-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\endverbatim", "snippet": "\\endverbatim", "meta": "tcolorbox-cmd", "score": 0.0022216421267780076}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "tcolorbox-cmd", "score": 0.0072203369120285256}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\par", "snippet": "\\par", "meta": "tcolorbox-cmd", "score": 0.413853376001159}, {"caption": "\\verbatiminput{}", "snippet": "\\verbatiminput{$1}", "meta": "tcolorbox-cmd", "score": 0.0024547099784948665}, {"caption": "\\verbatiminput", "snippet": "\\verbatiminput", "meta": "tcolorbox-cmd", "score": 0.0024547099784948665}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tcolorbox-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tcolorbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tcolorbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tcolorbox-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tcolorbox-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tcolorbox-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tcolorbox-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tcolorbox-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tcolorbox-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tcolorbox-cmd", "score": 0.004649150613625593}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "tcolorbox-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "tcolorbox-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "tcolorbox-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "tcolorbox-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "tcolorbox-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "tcolorbox-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "tcolorbox-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "tcolorbox-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "tcolorbox-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "tcolorbox-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "tcolorbox-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tcolorbox-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "tcolorbox-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "tcolorbox-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "tcolorbox-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tcolorbox-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tcolorbox-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tcolorbox-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tcolorbox-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tcolorbox-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tcolorbox-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tcolorbox-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tcolorbox-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tcolorbox-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tcolorbox-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tcolorbox-cmd", "score": 0.2864294797053033}], "vmargin": [{"caption": "\\setmargins{}", "snippet": "\\setmargins{$1}", "meta": "vmargin-cmd", "score": 3.138510306083217e-05}, {"caption": "\\setmarginsrb{}{}{}{}{}{}{}{}", "snippet": "\\setmarginsrb{$1}{$2}{$3}{$4}{$5}{$6}{$7}{$8}", "meta": "vmargin-cmd", "score": 0.0004759508676929243}, {"caption": "\\setpapersize{}", "snippet": "\\setpapersize{$1}", "meta": "vmargin-cmd", "score": 3.138510306083217e-05}], "mdframed": [{"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\newmdenv[]{}", "snippet": "\\newmdenv[$1]{$2}", "meta": "mdframed-cmd", "score": 0.0008776774843208122}, {"caption": "\\surroundwithmdframed[]{}", "snippet": "\\surroundwithmdframed[$1]{$2}", "meta": "mdframed-cmd", "score": 5.535446508489438e-05}, {"caption": "\\newmdtheoremenv{}{}", "snippet": "\\newmdtheoremenv{$1}{$2}", "meta": "mdframed-cmd", "score": 3.558785984219631e-05}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mdframed-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mdframed-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "mdframed-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "mdframed-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "mdframed-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "mdframed-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "mdframed-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "mdframed-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "mdframed-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "mdframed-cmd", "score": 0.2864294797053033}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mdframed-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mdframed-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "mdframed-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "mdframed-cmd", "score": 0.2864294797053033}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "mdframed-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "mdframed-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mdframed-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mdframed-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mdframed-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "mdframed-cmd", "score": 0.002958865219480927}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "mdframed-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "mdframed-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "mdframed-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "mdframed-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "mdframed-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "mdframed-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "mdframed-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "mdframed-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "mdframed-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "mdframed-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "mdframed-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "mdframed-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "mdframed-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mdframed-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "mdframed-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "mdframed-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "mdframed-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "mdframed-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mdframed-cmd", "score": 0.008565354665444157}], "cancel": [{"caption": "\\cancel{}", "snippet": "\\cancel{$1}", "meta": "cancel-cmd", "score": 0.00017782514657538044}, {"caption": "\\cancelto{}{}", "snippet": "\\cancelto{$1}{$2}", "meta": "cancel-cmd", "score": 7.809089624140706e-05}], "textcase": [{"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "textcase-cmd", "score": 2.341195220791228}], "libertine": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "libertine-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "libertine-cmd", "score": 0.008565354665444157}], "flushend": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "flushend-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "flushend-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "flushend-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "flushend-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "flushend-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "flushend-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "flushend-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "flushend-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "flushend-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "flushend-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "flushend-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "flushend-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "flushend-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "flushend-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "flushend-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "flushend-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "flushend-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "flushend-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "flushend-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "flushend-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "flushend-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "flushend-cmd", "score": 0.008565354665444157}], "psfrag": [{"caption": "\\csname", "snippet": "\\csname", "meta": "psfrag-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "psfrag-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "psfrag-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "psfrag-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "psfrag-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "psfrag-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "psfrag-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "psfrag-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "psfrag-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "psfrag-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "psfrag-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "psfrag-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "psfrag-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "psfrag-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "psfrag-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "psfrag-cmd", "score": 0.004649150613625593}], "tablefootnote": [{"caption": "\\tablefootnote{}", "snippet": "\\tablefootnote{$1}", "meta": "tablefootnote-cmd", "score": 0.00017554048326570823}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "tablefootnote-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "tablefootnote-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "tablefootnote-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tablefootnote-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tablefootnote-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "tablefootnote-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "tablefootnote-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "tablefootnote-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "tablefootnote-cmd", "score": 0.028955796305270766}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tablefootnote-cmd", "score": 0.008565354665444157}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tablefootnote-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tablefootnote-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tablefootnote-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tablefootnote-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tablefootnote-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "tablefootnote-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "tablefootnote-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tablefootnote-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "tablefootnote-cmd", "score": 0.0018957469739775527}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tablefootnote-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tablefootnote-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tablefootnote-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tablefootnote-cmd", "score": 0.021170869458413965}], "amstext": [{"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "amstext-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "amstext-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "amstext-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "amstext-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "amstext-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amstext-cmd", "score": 0.0063276692758974925}], "units": [{"caption": "\\unitfrac{}{}", "snippet": "\\unitfrac{$1}{$2}", "meta": "units-cmd", "score": 0.0009264866770139672}, {"caption": "\\unitfrac[]{}{}", "snippet": "\\unitfrac[$1]{$2}{$3}", "meta": "units-cmd", "score": 0.0009264866770139672}, {"caption": "\\unit[]{}", "snippet": "\\unit[$1]{$2}", "meta": "units-cmd", "score": 0.028299796173135428}, {"caption": "\\unit{}", "snippet": "\\unit{$1}", "meta": "units-cmd", "score": 0.028299796173135428}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "units-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "units-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "units-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "units-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "units-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "units-cmd", "score": 0.0018957469739775527}, {"caption": "\\nicefrac{}{}", "snippet": "\\nicefrac{$1}{$2}", "meta": "units-cmd", "score": 0.0018011350423659288}], "scrextend": [{"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "scrextend-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "scrextend-cmd", "score": 0.0003680857021151614}, {"caption": "\\scriptsize", "snippet": "\\scriptsize", "meta": "scrextend-cmd", "score": 0.05550618634921613}, {"caption": "\\scriptsize{}", "snippet": "\\scriptsize{$1}", "meta": "scrextend-cmd", "score": 0.05550618634921613}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "scrextend-cmd", "score": 0.7504160124360846}, {"caption": "\\Large", "snippet": "\\Large", "meta": "scrextend-cmd", "score": 0.1987771081149759}, {"caption": "\\Large{}", "snippet": "\\Large{$1}", "meta": "scrextend-cmd", "score": 0.1987771081149759}, {"caption": "\\and", "snippet": "\\and", "meta": "scrextend-cmd", "score": 0.09847866956528724}, {"caption": "\\LARGE", "snippet": "\\LARGE", "meta": "scrextend-cmd", "score": 0.05947642043953873}, {"caption": "\\LARGE{}", "snippet": "\\LARGE{$1}", "meta": "scrextend-cmd", "score": 0.05947642043953873}, {"caption": "\\subtitle{}", "snippet": "\\subtitle{$1}", "meta": "scrextend-cmd", "score": 0.01803265454797817}, {"caption": "\\large", "snippet": "\\large", "meta": "scrextend-cmd", "score": 0.20377416734108866}, {"caption": "\\large{}", "snippet": "\\large{$1}", "meta": "scrextend-cmd", "score": 0.20377416734108866}, {"caption": "\\Huge", "snippet": "\\Huge", "meta": "scrextend-cmd", "score": 0.04725806985998919}, {"caption": "\\footnotesize", "snippet": "\\footnotesize", "meta": "scrextend-cmd", "score": 0.2038592081252624}, {"caption": "\\footnotesize{}", "snippet": "\\footnotesize{$1}", "meta": "scrextend-cmd", "score": 0.2038592081252624}, {"caption": "\\small", "snippet": "\\small", "meta": "scrextend-cmd", "score": 0.2447632045426295}, {"caption": "\\small{}", "snippet": "\\small{$1}", "meta": "scrextend-cmd", "score": 0.2447632045426295}, {"caption": "\\huge", "snippet": "\\huge", "meta": "scrextend-cmd", "score": 0.04229832859754922}, {"caption": "\\huge{}", "snippet": "\\huge{$1}", "meta": "scrextend-cmd", "score": 0.04229832859754922}, {"caption": "\\cleardoublepage", "snippet": "\\cleardoublepage", "meta": "scrextend-cmd", "score": 0.044016804142963585}, {"caption": "\\tiny{}", "snippet": "\\tiny{$1}", "meta": "scrextend-cmd", "score": 0.047727606910742924}, {"caption": "\\tiny", "snippet": "\\tiny", "meta": "scrextend-cmd", "score": 0.047727606910742924}, {"caption": "\\deffootnote[]{}{}{}", "snippet": "\\deffootnote[$1]{$2}{$3}{$4}", "meta": "scrextend-cmd", "score": 2.545393270896533e-05}, {"caption": "\\thefootnote", "snippet": "\\thefootnote", "meta": "scrextend-cmd", "score": 0.007676927812687567}, {"caption": "\\thefootnote{}", "snippet": "\\thefootnote{$1}", "meta": "scrextend-cmd", "score": 0.007676927812687567}, {"caption": "\\normalsize", "snippet": "\\normalsize", "meta": "scrextend-cmd", "score": 0.14261697855738878}, {"caption": "\\normalsize{}", "snippet": "\\normalsize{$1}", "meta": "scrextend-cmd", "score": 0.14261697855738878}, {"caption": "\\titlefont", "snippet": "\\titlefont", "meta": "scrextend-cmd", "score": 0.0005278519180709353}, {"caption": "\\thefootnotemark", "snippet": "\\thefootnotemark", "meta": "scrextend-cmd", "score": 2.545393270896533e-05}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "scrextend-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "scrextend-cmd", "score": 0.1789117552185788}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "scrextend-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "scrextend-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "scrextend-cmd", "score": 0.000396664302361659}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scrextend-cmd", "score": 0.00037306820619479756}], "mwe": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mwe-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mwe-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "mwe-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "mwe-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "mwe-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "mwe-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "mwe-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mwe-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "mwe-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mwe-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "mwe-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "mwe-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "mwe-cmd", "score": 0.004719094298848707}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "mwe-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mwe-cmd", "score": 0.008565354665444157}], "beamerposter": [{"caption": "\\scriptsize", "snippet": "\\scriptsize", "meta": "beamerposter-cmd", "score": 0.05550618634921613}, {"caption": "\\scriptsize{}", "snippet": "\\scriptsize{$1}", "meta": "beamerposter-cmd", "score": 0.05550618634921613}, {"caption": "\\Large", "snippet": "\\Large", "meta": "beamerposter-cmd", "score": 0.1987771081149759}, {"caption": "\\Large{}", "snippet": "\\Large{$1}", "meta": "beamerposter-cmd", "score": 0.1987771081149759}, {"caption": "\\footnotesize", "snippet": "\\footnotesize", "meta": "beamerposter-cmd", "score": 0.2038592081252624}, {"caption": "\\footnotesize{}", "snippet": "\\footnotesize{$1}", "meta": "beamerposter-cmd", "score": 0.2038592081252624}, {"caption": "\\LARGE", "snippet": "\\LARGE", "meta": "beamerposter-cmd", "score": 0.05947642043953873}, {"caption": "\\LARGE{}", "snippet": "\\LARGE{$1}", "meta": "beamerposter-cmd", "score": 0.05947642043953873}, {"caption": "\\large", "snippet": "\\large", "meta": "beamerposter-cmd", "score": 0.20377416734108866}, {"caption": "\\large{}", "snippet": "\\large{$1}", "meta": "beamerposter-cmd", "score": 0.20377416734108866}, {"caption": "\\VeryHuge", "snippet": "\\VeryHuge", "meta": "beamerposter-cmd", "score": 0.000892251826639951}, {"caption": "\\small", "snippet": "\\small", "meta": "beamerposter-cmd", "score": 0.2447632045426295}, {"caption": "\\small{}", "snippet": "\\small{$1}", "meta": "beamerposter-cmd", "score": 0.2447632045426295}, {"caption": "\\VERYHuge", "snippet": "\\VERYHuge", "meta": "beamerposter-cmd", "score": 0.0011668714784222325}, {"caption": "\\veryHuge", "snippet": "\\veryHuge", "meta": "beamerposter-cmd", "score": 0.000892251826639951}, {"caption": "\\normalsize", "snippet": "\\normalsize", "meta": "beamerposter-cmd", "score": 0.14261697855738878}, {"caption": "\\normalsize{}", "snippet": "\\normalsize{$1}", "meta": "beamerposter-cmd", "score": 0.14261697855738878}, {"caption": "\\tiny{}", "snippet": "\\tiny{$1}", "meta": "beamerposter-cmd", "score": 0.047727606910742924}, {"caption": "\\tiny", "snippet": "\\tiny", "meta": "beamerposter-cmd", "score": 0.047727606910742924}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "beamerposter-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "beamerposter-cmd", "score": 0.021170869458413965}], "footnote": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "footnote-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "footnote-cmd", "score": 0.021170869458413965}, {"caption": "\\makesavenoteenv{}", "snippet": "\\makesavenoteenv{$1}", "meta": "footnote-cmd", "score": 0.0018587414325895479}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "footnote-cmd", "score": 0.2253056071787701}, {"caption": "\\csname", "snippet": "\\csname", "meta": "footnote-cmd", "score": 0.008565354665444157}, {"caption": "\\parbox{}{}", "snippet": "\\parbox{$1}{$2}", "meta": "footnote-cmd", "score": 0.04800611019618169}], "invoice": [{"caption": "\\Fee{}{}{}", "snippet": "\\Fee{$1}{$2}{$3}", "meta": "invoice-cmd", "score": 0.003295435821387378}, {"caption": "\\ProjectTitle{}", "snippet": "\\ProjectTitle{$1}", "meta": "invoice-cmd", "score": 0.003295435821387378}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "invoice-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "invoice-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "invoice-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "invoice-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "invoice-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "invoice-cmd", "score": 0.0018957469739775527}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "invoice-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "invoice-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "invoice-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "invoice-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "invoice-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "invoice-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "invoice-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "invoice-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "invoice-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "invoice-cmd", "score": 0.0313525090421608}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "invoice-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "invoice-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "invoice-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "invoice-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "invoice-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "invoice-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "invoice-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "invoice-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "invoice-cmd", "score": 0.028955796305270766}], "tikzpeople": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpeople-cmd", "score": 0.008565354665444157}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "tikzpeople-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "tikzpeople-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "tikzpeople-cmd", "score": 0.028955796305270766}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikzpeople-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikzpeople-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikzpeople-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpeople-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikzpeople-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpeople-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikzpeople-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikzpeople-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzpeople-cmd", "score": 0.004719094298848707}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "tikzpeople-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "tikzpeople-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "tikzpeople-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "tikzpeople-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "tikzpeople-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "tikzpeople-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "tikzpeople-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "tikzpeople-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "tikzpeople-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "tikzpeople-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "tikzpeople-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpeople-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "tikzpeople-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "tikzpeople-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "tikzpeople-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpeople-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikzpeople-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzpeople-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikzpeople-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpeople-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikzpeople-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpeople-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikzpeople-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikzpeople-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikzpeople-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikzpeople-cmd", "score": 0.2864294797053033}], "titletoc": [{"caption": "\\thecontentspage", "snippet": "\\thecontentspage", "meta": "titletoc-cmd", "score": 0.0008054115902675176}, {"caption": "\\startcontents", "snippet": "\\startcontents", "meta": "titletoc-cmd", "score": 0.00026847053008917257}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "titletoc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "titletoc-cmd", "score": 0.021170869458413965}, {"caption": "\\printcontents{}{}{}", "snippet": "\\printcontents{$1}{$2}{$3}", "meta": "titletoc-cmd", "score": 0.00013423526504458629}, {"caption": "\\titlecontents{}[]", "snippet": "\\titlecontents{$1}[$2]", "meta": "titletoc-cmd", "score": 0.0017036290423289926}, {"caption": "\\titlecontents{}[]{}{}{}{}[]", "snippet": "\\titlecontents{$1}[$2]{$3}{$4}{$5}{$6}[$7]", "meta": "titletoc-cmd", "score": 0.0017036290423289926}, {"caption": "\\titlecontents{}[]{}{}{}{}", "snippet": "\\titlecontents{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "titletoc-cmd", "score": 0.0017036290423289926}, {"caption": "\\numberline{}", "snippet": "\\numberline{$1}", "meta": "titletoc-cmd", "score": 0.007461440567272885}, {"caption": "\\dottedcontents{}[]{}{}{}", "snippet": "\\dottedcontents{$1}[$2]{$3}{$4}{$5}", "meta": "titletoc-cmd", "score": 4.743909531747666e-05}, {"caption": "\\filcenter", "snippet": "\\filcenter", "meta": "titletoc-cmd", "score": 0.0004835660211260246}, {"caption": "\\thecontentslabel", "snippet": "\\thecontentslabel", "meta": "titletoc-cmd", "score": 0.0010521864830662522}, {"caption": "\\contentsuse{}{}", "snippet": "\\contentsuse{$1}{$2}", "meta": "titletoc-cmd", "score": 6.110202388233705e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "titletoc-cmd", "score": 0.008565354665444157}, {"caption": "\\contentspage", "snippet": "\\contentspage", "meta": "titletoc-cmd", "score": 0.0004955116569277163}, {"caption": "\\contentslabel[]{}", "snippet": "\\contentslabel[$1]{$2}", "meta": "titletoc-cmd", "score": 0.0011055859582683105}, {"caption": "\\contentslabel{}", "snippet": "\\contentslabel{$1}", "meta": "titletoc-cmd", "score": 0.0011055859582683105}, {"caption": "\\contentsmargin{}", "snippet": "\\contentsmargin{$1}", "meta": "titletoc-cmd", "score": 0.00013423526504458629}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "titletoc-cmd", "score": 0.3277033727934986}, {"caption": "\\titlerule", "snippet": "\\titlerule", "meta": "titletoc-cmd", "score": 0.019273712561461216}, {"caption": "\\titlerule[]{}", "snippet": "\\titlerule[$1]{$2}", "meta": "titletoc-cmd", "score": 0.019273712561461216}], "dblfloatfix": [{"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "dblfloatfix-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "dblfloatfix-cmd", "score": 0.354445763583904}, {"caption": "\\textsubscript{}", "snippet": "\\textsubscript{$1}", "meta": "dblfloatfix-cmd", "score": 0.058405875394131175}, {"caption": "\\em", "snippet": "\\em", "meta": "dblfloatfix-cmd", "score": 0.10357353994640862}], "pgfplotstable": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplotstable-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "pgfplotstable-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "pgfplotstable-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "pgfplotstable-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "pgfplotstable-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplotstable-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "pgfplotstable-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.018615449342361392}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfplotstable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfplotstable-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfplotstable-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfplotstable-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfplotstable-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfplotstable-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfplotstable-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplotstable-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfplotstable-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfplotstable-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfplotstable-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfplotstable-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfplotstable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfplotstable-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfplotstable-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfplotstable-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfplotstable-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfplotstable-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfplotstable-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfplotstable-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfplotstable-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfplotstable-cmd", "score": 0.2864294797053033}], "acronym": [{"caption": "\\acp{}", "snippet": "\\acp{$1}", "meta": "acronym-cmd", "score": 0.0005185177930914685}, {"caption": "\\acsfont{}", "snippet": "\\acsfont{$1}", "meta": "acronym-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\aclabelfont", "snippet": "\\aclabelfont", "meta": "acronym-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\acro{}{}", "snippet": "\\acro{$1}{$2}", "meta": "acronym-cmd", "score": 0.023587207425038587}, {"caption": "\\acl{}", "snippet": "\\acl{$1}", "meta": "acronym-cmd", "score": 0.0008131607751426444}, {"caption": "\\acf{}", "snippet": "\\acf{$1}", "meta": "acronym-cmd", "score": 0.0006845634165950408}, {"caption": "\\acrodef{}[]{}", "snippet": "\\acrodef{$1}[$2]{$3}", "meta": "acronym-cmd", "score": 0.0002902047200830372}, {"caption": "\\acs{}", "snippet": "\\acs{$1}", "meta": "acronym-cmd", "score": 0.002351209826598939}, {"caption": "\\acfp{}", "snippet": "\\acfp{$1}", "meta": "acronym-cmd", "score": 2.2013599341265054e-05}, {"caption": "\\ac{}", "snippet": "\\ac{$1}", "meta": "acronym-cmd", "score": 0.04714113215364704}, {"caption": "\\let", "snippet": "\\let", "meta": "acronym-cmd", "score": 0.03789745970461662}], "nicefrac": [{"caption": "\\nicefrac{}{}", "snippet": "\\nicefrac{$1}{$2}", "meta": "nicefrac-cmd", "score": 0.0018011350423659288}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "nicefrac-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "nicefrac-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "nicefrac-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "nicefrac-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "nicefrac-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "nicefrac-cmd", "score": 0.0018957469739775527}], "smartdiagram": [{"caption": "\\usesmartdiagramlibrary{}", "snippet": "\\usesmartdiagramlibrary{$1}", "meta": "smartdiagram-cmd", "score": 7.216282820556303e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "smartdiagram-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "smartdiagram-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "smartdiagram-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "smartdiagram-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "smartdiagram-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "smartdiagram-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "smartdiagram-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "smartdiagram-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "smartdiagram-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "smartdiagram-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "smartdiagram-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "smartdiagram-cmd", "score": 0.004719094298848707}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "smartdiagram-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "smartdiagram-cmd", "score": 0.2864294797053033}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "smartdiagram-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "smartdiagram-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "smartdiagram-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "smartdiagram-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "smartdiagram-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "smartdiagram-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "smartdiagram-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "smartdiagram-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "smartdiagram-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "smartdiagram-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "smartdiagram-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "smartdiagram-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "smartdiagram-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "smartdiagram-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "smartdiagram-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "smartdiagram-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "smartdiagram-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "smartdiagram-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "smartdiagram-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "smartdiagram-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "smartdiagram-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "smartdiagram-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "smartdiagram-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "smartdiagram-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "smartdiagram-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "smartdiagram-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "smartdiagram-cmd", "score": 0.2864294797053033}], "qtree": [{"caption": "\\qroof{}", "snippet": "\\qroof{$1}", "meta": "qtree-cmd", "score": 0.00012663929287995903}, {"caption": "\\Tree[]", "snippet": "\\Tree[$1]", "meta": "qtree-cmd", "score": 0.0008894716589418522}, {"caption": "\\Tree", "snippet": "\\Tree", "meta": "qtree-cmd", "score": 0.0008894716589418522}], "backref": [{"caption": "\\backrefpagesname", "snippet": "\\backrefpagesname", "meta": "backref-cmd", "score": 0.0022756001200686213}, {"caption": "\\backref", "snippet": "\\backref", "meta": "backref-cmd", "score": 0.0025820187198826706}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "backref-cmd", "score": 0.1789117552185788}, {"caption": "\\global", "snippet": "\\global", "meta": "backref-cmd", "score": 0.006609629561859019}, {"caption": "\\csname", "snippet": "\\csname", "meta": "backref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "backref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "backref-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "backref-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "backref-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "backref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "backref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "backref-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "backref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "backref-cmd", "score": 0.021170869458413965}, {"caption": "\\empty", "snippet": "\\empty", "meta": "backref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "backref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "backref-cmd", "score": 0.008565354665444157}, {"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "backref-cmd", "score": 0.010304996748556729}, {"caption": "\\index{}", "snippet": "\\index{$1}", "meta": "backref-cmd", "score": 0.013774721817648336}, {"caption": "\\empty", "snippet": "\\empty", "meta": "backref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "backref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "backref-cmd", "score": 0.008565354665444157}], "epigraph": [{"caption": "\\epigraphflush{}", "snippet": "\\epigraphflush{$1}", "meta": "epigraph-cmd", "score": 1.8073688234300064e-05}, {"caption": "\\epigraphsize{}", "snippet": "\\epigraphsize{$1}", "meta": "epigraph-cmd", "score": 6.820709322498027e-05}, {"caption": "\\epigraphsize", "snippet": "\\epigraphsize", "meta": "epigraph-cmd", "score": 6.820709322498027e-05}, {"caption": "\\epigraph{}{}", "snippet": "\\epigraph{$1}{$2}", "meta": "epigraph-cmd", "score": 0.0031428856022970054}], "chngcntr": [{"caption": "\\counterwithin{}{}", "snippet": "\\counterwithin{$1}{$2}", "meta": "chngcntr-cmd", "score": 0.001287401394784382}, {"caption": "\\counterwithout{}{}", "snippet": "\\counterwithout{$1}{$2}", "meta": "chngcntr-cmd", "score": 0.0026127666246546326}], "empheq": [{"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "empheq-cmd", "score": 0.20852115286477566}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "empheq-cmd", "score": 1.897791904799601}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "empheq-cmd", "score": 0.051980653969641216}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "empheq-cmd", "score": 0.06345266254167037}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "empheq-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "empheq-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "empheq-cmd", "score": 0.18137737738638837}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "empheq-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "empheq-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "empheq-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "empheq-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "empheq-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "empheq-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "empheq-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "empheq-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "empheq-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "empheq-cmd", "score": 0.028955796305270766}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "empheq-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "empheq-cmd", "score": 0.021170869458413965}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "empheq-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "empheq-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "empheq-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "empheq-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "empheq-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "empheq-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "empheq-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "empheq-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "empheq-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "empheq-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "empheq-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "empheq-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "empheq-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "empheq-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "empheq-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "empheq-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "empheq-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "empheq-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "empheq-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "empheq-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "empheq-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "empheq-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "empheq-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "empheq-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "empheq-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "empheq-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "empheq-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "empheq-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "empheq-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "empheq-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "empheq-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "empheq-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "empheq-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "empheq-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "empheq-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "empheq-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "empheq-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "empheq-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "empheq-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "empheq-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "empheq-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "empheq-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "empheq-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "empheq-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "empheq-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "empheq-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "empheq-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "empheq-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "empheq-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "empheq-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "empheq-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "empheq-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "empheq-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "empheq-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "empheq-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "empheq-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "empheq-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "empheq-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "empheq-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "empheq-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "empheq-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "empheq-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "empheq-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "empheq-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "empheq-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "empheq-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "empheq-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "empheq-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "empheq-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "empheq-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "empheq-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "empheq-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "empheq-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "empheq-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "empheq-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "empheq-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "empheq-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "empheq-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "empheq-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "empheq-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "empheq-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "empheq-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "empheq-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "empheq-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "empheq-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "empheq-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "empheq-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "empheq-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "empheq-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "empheq-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "empheq-cmd", "score": 0.0058847868741168765}, {"caption": "\\xleftrightarrow[][]{}", "snippet": "\\xleftrightarrow[$1][$2]{$3}", "meta": "empheq-cmd", "score": 4.015559489911509e-05}, {"caption": "\\vcentcolon", "snippet": "\\vcentcolon", "meta": "empheq-cmd", "score": 0.00021361943526711615}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "empheq-cmd", "score": 0.0016148076375871775}, {"caption": "\\coloneqq", "snippet": "\\coloneqq", "meta": "empheq-cmd", "score": 0.0014407293323958122}, {"caption": "\\mathclap{}", "snippet": "\\mathclap{$1}", "meta": "empheq-cmd", "score": 7.84378567451772e-05}, {"caption": "\\adjustlimits", "snippet": "\\adjustlimits", "meta": "empheq-cmd", "score": 0.0005307066890271085}, {"caption": "\\MoveEqLeft", "snippet": "\\MoveEqLeft", "meta": "empheq-cmd", "score": 5.343949980628182e-05}, {"caption": "\\mathrlap{}", "snippet": "\\mathrlap{$1}", "meta": "empheq-cmd", "score": 0.0003112817211637952}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "empheq-cmd", "score": 0.051980653969641216}, {"caption": "\\xhookrightarrow{}", "snippet": "\\xhookrightarrow{$1}", "meta": "empheq-cmd", "score": 5.444260823474129e-05}, {"caption": "\\DeclarePairedDelimiter{}{}{}", "snippet": "\\DeclarePairedDelimiter{$1}{$2}{$3}", "meta": "empheq-cmd", "score": 0.0033916678416372487}, {"caption": "\\DeclarePairedDelimiter", "snippet": "\\DeclarePairedDelimiter", "meta": "empheq-cmd", "score": 0.0033916678416372487}, {"caption": "\\prescript{}{}{}", "snippet": "\\prescript{$1}{$2}{$3}", "meta": "empheq-cmd", "score": 8.833369785705982e-06}, {"caption": "\\underbrace{}", "snippet": "\\underbrace{$1}", "meta": "empheq-cmd", "score": 0.010373780436850907}, {"caption": "\\mathllap{}", "snippet": "\\mathllap{$1}", "meta": "empheq-cmd", "score": 3.140504277052775e-05}, {"caption": "\\overbrace{}", "snippet": "\\overbrace{$1}", "meta": "empheq-cmd", "score": 0.0006045704778718376}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "empheq-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "empheq-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "empheq-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "empheq-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "empheq-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "empheq-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "empheq-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "empheq-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "empheq-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "empheq-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "empheq-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "empheq-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "empheq-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "empheq-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "empheq-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "empheq-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "empheq-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "empheq-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "empheq-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "empheq-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "empheq-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "empheq-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "empheq-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "empheq-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "empheq-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "empheq-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "empheq-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "empheq-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "empheq-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "empheq-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "empheq-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "empheq-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "empheq-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "empheq-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "empheq-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "empheq-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "empheq-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "empheq-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "empheq-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "empheq-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "empheq-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "empheq-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "empheq-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "empheq-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "empheq-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "empheq-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "empheq-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "empheq-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "empheq-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "empheq-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "empheq-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "empheq-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "empheq-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "empheq-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "empheq-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "empheq-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "empheq-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "empheq-cmd", "score": 0.0063276692758974925}], "mathexam": [{"caption": "\\ExamInstrBox{}", "snippet": "\\ExamInstrBox{$1}", "meta": "mathexam-cmd", "score": 0.00035308240943436196}, {"caption": "\\ExamName{}", "snippet": "\\ExamName{$1}", "meta": "mathexam-cmd", "score": 0.00165391233892938}, {"caption": "\\ExamNameLine", "snippet": "\\ExamNameLine", "meta": "mathexam-cmd", "score": 0.00165391233892938}, {"caption": "\\ExamClass{}", "snippet": "\\ExamClass{$1}", "meta": "mathexam-cmd", "score": 0.00165391233892938}, {"caption": "\\ExamHead{}", "snippet": "\\ExamHead{$1}", "meta": "mathexam-cmd", "score": 0.00165391233892938}, {"caption": "\\answer{}", "snippet": "\\answer{$1}", "meta": "mathexam-cmd", "score": 0.0034436236729672894}, {"caption": "\\answer", "snippet": "\\answer", "meta": "mathexam-cmd", "score": 0.0034436236729672894}, {"caption": "\\lhead{}", "snippet": "\\lhead{$1}", "meta": "mathexam-cmd", "score": 0.05268978171228714}, {"caption": "\\chaptermark", "snippet": "\\chaptermark", "meta": "mathexam-cmd", "score": 0.005924520024686584}, {"caption": "\\chaptermark{}", "snippet": "\\chaptermark{$1}", "meta": "mathexam-cmd", "score": 0.005924520024686584}, {"caption": "\\fancypagestyle{}{}", "snippet": "\\fancypagestyle{$1}{$2}", "meta": "mathexam-cmd", "score": 0.009430919590937878}, {"caption": "\\footrule", "snippet": "\\footrule", "meta": "mathexam-cmd", "score": 0.0010032754348913366}, {"caption": "\\footrule{}", "snippet": "\\footrule{$1}", "meta": "mathexam-cmd", "score": 0.0010032754348913366}, {"caption": "\\fancyfoot[]{}", "snippet": "\\fancyfoot[$1]{$2}", "meta": "mathexam-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfoot{}", "snippet": "\\fancyfoot{$1}", "meta": "mathexam-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfootoffset[]{}", "snippet": "\\fancyfootoffset[$1]{$2}", "meta": "mathexam-cmd", "score": 0.0015373246231684555}, {"caption": "\\fancyfootoffset{}", "snippet": "\\fancyfootoffset{$1}", "meta": "mathexam-cmd", "score": 0.0015373246231684555}, {"caption": "\\footruleskip", "snippet": "\\footruleskip", "meta": "mathexam-cmd", "score": 0.000830117957327721}, {"caption": "\\fancyheadoffset[]{}", "snippet": "\\fancyheadoffset[$1]{$2}", "meta": "mathexam-cmd", "score": 0.0016786568695309166}, {"caption": "\\fancyheadoffset{}", "snippet": "\\fancyheadoffset{$1}", "meta": "mathexam-cmd", "score": 0.0016786568695309166}, {"caption": "\\iffloatpage{}{}", "snippet": "\\iffloatpage{$1}{$2}", "meta": "mathexam-cmd", "score": 6.606286310833368e-05}, {"caption": "\\cfoot{}", "snippet": "\\cfoot{$1}", "meta": "mathexam-cmd", "score": 0.013411641301057813}, {"caption": "\\subsectionmark", "snippet": "\\subsectionmark", "meta": "mathexam-cmd", "score": 3.1153423008593836e-05}, {"caption": "\\footrulewidth", "snippet": "\\footrulewidth", "meta": "mathexam-cmd", "score": 0.011424740897486949}, {"caption": "\\fancyhfoffset[]{}", "snippet": "\\fancyhfoffset[$1]{$2}", "meta": "mathexam-cmd", "score": 3.741978601121172e-05}, {"caption": "\\rhead{}", "snippet": "\\rhead{$1}", "meta": "mathexam-cmd", "score": 0.022782817416731292}, {"caption": "\\fancyplain{}{}", "snippet": "\\fancyplain{$1}{$2}", "meta": "mathexam-cmd", "score": 0.007402339896386138}, {"caption": "\\rfoot{}", "snippet": "\\rfoot{$1}", "meta": "mathexam-cmd", "score": 0.013393817825547868}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mathexam-cmd", "score": 0.00530510025314411}, {"caption": "\\plainheadrulewidth", "snippet": "\\plainheadrulewidth", "meta": "mathexam-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\baselinestretch", "snippet": "\\baselinestretch", "meta": "mathexam-cmd", "score": 0.03225350148161425}, {"caption": "\\lfoot{}", "snippet": "\\lfoot{$1}", "meta": "mathexam-cmd", "score": 0.00789399846642229}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "mathexam-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "mathexam-cmd", "score": 0.006776001543888959}, {"caption": "\\fancyhf{}", "snippet": "\\fancyhf{$1}", "meta": "mathexam-cmd", "score": 0.02314618933449356}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "mathexam-cmd", "score": 0.005008938879210868}, {"caption": "\\fancyhead[]{}", "snippet": "\\fancyhead[$1]{$2}", "meta": "mathexam-cmd", "score": 0.039101068064744296}, {"caption": "\\fancyhead{}", "snippet": "\\fancyhead{$1}", "meta": "mathexam-cmd", "score": 0.039101068064744296}, {"caption": "\\nouppercase{}", "snippet": "\\nouppercase{$1}", "meta": "mathexam-cmd", "score": 0.006416387071584083}, {"caption": "\\nouppercase", "snippet": "\\nouppercase", "meta": "mathexam-cmd", "score": 0.006416387071584083}, {"caption": "\\headrule", "snippet": "\\headrule", "meta": "mathexam-cmd", "score": 0.0008327432627715623}, {"caption": "\\headrule{}", "snippet": "\\headrule{$1}", "meta": "mathexam-cmd", "score": 0.0008327432627715623}, {"caption": "\\chead{}", "snippet": "\\chead{$1}", "meta": "mathexam-cmd", "score": 0.00755042164734884}, {"caption": "\\headrulewidth", "snippet": "\\headrulewidth", "meta": "mathexam-cmd", "score": 0.02268137935335823}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "mathexam-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "mathexam-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "mathexam-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "mathexam-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "mathexam-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "mathexam-cmd", "score": 0.0018957469739775527}, {"caption": "\\string", "snippet": "\\string", "meta": "mathexam-cmd", "score": 0.001042697111754002}], "floatrow": [{"caption": "\\floatfoot{}", "snippet": "\\floatfoot{$1}", "meta": "floatrow-cmd", "score": 0.0015365464531749851}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "floatrow-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatsetup[]{}", "snippet": "\\floatsetup[$1]{$2}", "meta": "floatrow-cmd", "score": 0.0005456136119914056}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "floatrow-cmd", "score": 0.00037306820619479756}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "floatrow-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "floatrow-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "floatrow-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "floatrow-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "floatrow-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "floatrow-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "floatrow-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "floatrow-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "floatrow-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "floatrow-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "floatrow-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "floatrow-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "floatrow-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "floatrow-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "floatrow-cmd", "score": 0.021473212893597875}], "scrpage2": [{"caption": "\\automark[]{}", "snippet": "\\automark[$1]{$2}", "meta": "scrpage2-cmd", "score": 0.0006703031783997437}, {"caption": "\\automark{}", "snippet": "\\automark{$1}", "meta": "scrpage2-cmd", "score": 0.0006703031783997437}, {"caption": "\\ofoot{}", "snippet": "\\ofoot{$1}", "meta": "scrpage2-cmd", "score": 0.000605620621498142}, {"caption": "\\ofoot[]{}", "snippet": "\\ofoot[$1]{$2}", "meta": "scrpage2-cmd", "score": 0.000605620621498142}, {"caption": "\\ohead{}", "snippet": "\\ohead{$1}", "meta": "scrpage2-cmd", "score": 0.004845161937670253}, {"caption": "\\ohead[]{}", "snippet": "\\ohead[$1]{$2}", "meta": "scrpage2-cmd", "score": 0.004845161937670253}, {"caption": "\\headfont", "snippet": "\\headfont", "meta": "scrpage2-cmd", "score": 0.0011116915941419892}, {"caption": "\\setheadsepline{}", "snippet": "\\setheadsepline{$1}", "meta": "scrpage2-cmd", "score": 0.00023538827295624133}, {"caption": "\\clearscrheadings", "snippet": "\\clearscrheadings", "meta": "scrpage2-cmd", "score": 0.0003679125016983611}, {"caption": "\\clearscrheadfoot", "snippet": "\\clearscrheadfoot", "meta": "scrpage2-cmd", "score": 0.000558377093879783}, {"caption": "\\pagemark", "snippet": "\\pagemark", "meta": "scrpage2-cmd", "score": 0.0017520841736604843}, {"caption": "\\chead{}", "snippet": "\\chead{$1}", "meta": "scrpage2-cmd", "score": 0.00755042164734884}, {"caption": "\\clearscrplain", "snippet": "\\clearscrplain", "meta": "scrpage2-cmd", "score": 0.00013252422874211978}, {"caption": "\\ifoot{}", "snippet": "\\ifoot{$1}", "meta": "scrpage2-cmd", "score": 0.0003620142864171218}, {"caption": "\\ifoot[]{}", "snippet": "\\ifoot[$1]{$2}", "meta": "scrpage2-cmd", "score": 0.0003620142864171218}, {"caption": "\\ihead{}", "snippet": "\\ihead{$1}", "meta": "scrpage2-cmd", "score": 0.0004507603139230655}, {"caption": "\\ihead[]{}", "snippet": "\\ihead[$1]{$2}", "meta": "scrpage2-cmd", "score": 0.0004507603139230655}, {"caption": "\\cfoot{}", "snippet": "\\cfoot{$1}", "meta": "scrpage2-cmd", "score": 0.013411641301057813}], "pbox": [{"caption": "\\pbox{}{}", "snippet": "\\pbox{$1}{$2}", "meta": "pbox-cmd", "score": 0.0010883030320478486}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "pbox-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "pbox-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "pbox-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "pbox-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "pbox-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "pbox-cmd", "score": 0.0018957469739775527}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "pbox-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "pbox-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "pbox-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pbox-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "pbox-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "pbox-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "pbox-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "pbox-cmd", "score": 0.028955796305270766}], "esint": [{"caption": "\\int", "snippet": "\\int", "meta": "esint-cmd", "score": 0.11946660537765894}, {"caption": "\\iint", "snippet": "\\iint", "meta": "esint-cmd", "score": 0.003916494384710151}, {"caption": "\\varoiint", "snippet": "\\varoiint", "meta": "esint-cmd", "score": 0.0001069175284516453}, {"caption": "\\iiint", "snippet": "\\iiint", "meta": "esint-cmd", "score": 0.0010383179918633135}, {"caption": "\\oint", "snippet": "\\oint", "meta": "esint-cmd", "score": 0.0028650540724050534}, {"caption": "\\oiint", "snippet": "\\oiint", "meta": "esint-cmd", "score": 7.127835230109687e-05}], "algorithmicx": [{"caption": "\\algrenewcommand", "snippet": "\\algrenewcommand", "meta": "algorithmicx-cmd", "score": 0.0019861803661869416}, {"caption": "\\Statex", "snippet": "\\Statex", "meta": "algorithmicx-cmd", "score": 0.008622777195102994}, {"caption": "\\BState{}", "snippet": "\\BState{$1}", "meta": "algorithmicx-cmd", "score": 0.0008685861525307122}, {"caption": "\\BState", "snippet": "\\BState", "meta": "algorithmicx-cmd", "score": 0.0008685861525307122}, {"caption": "\\algloopdefx{}[][]{}", "snippet": "\\algloopdefx{$1}[$2][$3]{$4}", "meta": "algorithmicx-cmd", "score": 0.00025315185701145097}, {"caption": "\\algnewcommand", "snippet": "\\algnewcommand", "meta": "algorithmicx-cmd", "score": 0.0030209395012065327}, {"caption": "\\algnewcommand{}[]{}", "snippet": "\\algnewcommand{$1}[$2]{$3}", "meta": "algorithmicx-cmd", "score": 0.0030209395012065327}, {"caption": "\\Comment{}", "snippet": "\\Comment{$1}", "meta": "algorithmicx-cmd", "score": 0.005178604573219454}, {"caption": "\\algblockdefx{}{}[]", "snippet": "\\algblockdefx{$1}{$2}[$3]", "meta": "algorithmicx-cmd", "score": 0.00025315185701145097}, {"caption": "\\algrenewtext{}{}", "snippet": "\\algrenewtext{$1}{$2}", "meta": "algorithmicx-cmd", "score": 0.0024415580558825975}, {"caption": "\\algrenewtext{}[]{}", "snippet": "\\algrenewtext{$1}[$2]{$3}", "meta": "algorithmicx-cmd", "score": 0.0024415580558825975}, {"caption": "\\algblock{}{}", "snippet": "\\algblock{$1}{$2}", "meta": "algorithmicx-cmd", "score": 0.0007916858220314837}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algorithmicx-cmd", "score": 0.008565354665444157}, {"caption": "\\algdef{}[]{}{}{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "algorithmicx-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}{}[]{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}[$5]{$6}{$7}", "meta": "algorithmicx-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}[]{}", "snippet": "\\algdef{$1}[$2]{$3}[$4]{$5}", "meta": "algorithmicx-cmd", "score": 0.0003102486920966127}, {"caption": "\\algtext{}", "snippet": "\\algtext{$1}", "meta": "algorithmicx-cmd", "score": 0.0005463612015579842}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algorithmicx-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algorithmicx-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algorithmicx-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algorithmicx-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algorithmicx-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algorithmicx-cmd", "score": 0.0018957469739775527}], "bibentry": [{"caption": "\\bibentry{}", "snippet": "\\bibentry{$1}", "meta": "bibentry-cmd", "score": 0.002786693424998083}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "bibentry-cmd", "score": 0.13586474005868793}, {"caption": "\\item", "snippet": "\\item", "meta": "bibentry-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "bibentry-cmd", "score": 3.800886892251021}, {"caption": "\\nobibliography", "snippet": "\\nobibliography", "meta": "bibentry-cmd", "score": 0.0009870472135074372}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "bibentry-cmd", "score": 0.2659628337907604}, {"caption": "\\doi{}", "snippet": "\\doi{$1}", "meta": "bibentry-cmd", "score": 0.004001210811454663}, {"caption": "\\doi", "snippet": "\\doi", "meta": "bibentry-cmd", "score": 0.004001210811454663}], "txfonts": [{"caption": "\\sqrt{}", "snippet": "\\sqrt{$1}", "meta": "txfonts-cmd", "score": 0.20240160977404634}], "ngerman": [{"caption": "\\figurename", "snippet": "\\figurename", "meta": "ngerman-cmd", "score": 0.008169568707145965}, {"caption": "\\figurename{}", "snippet": "\\figurename{$1}", "meta": "ngerman-cmd", "score": 0.008169568707145965}, {"caption": "\\indexname", "snippet": "\\indexname", "meta": "ngerman-cmd", "score": 0.0007544109314450072}, {"caption": "\\glqq", "snippet": "\\glqq", "meta": "ngerman-cmd", "score": 0.0039133256714254504}, {"caption": "\\glqq{}", "snippet": "\\glqq{$1}", "meta": "ngerman-cmd", "score": 0.0039133256714254504}, {"caption": "\\today", "snippet": "\\today", "meta": "ngerman-cmd", "score": 0.10733849317324783}, {"caption": "\\bibname", "snippet": "\\bibname", "meta": "ngerman-cmd", "score": 0.007599529252128519}, {"caption": "\\bibname{}", "snippet": "\\bibname{$1}", "meta": "ngerman-cmd", "score": 0.007599529252128519}, {"caption": "\\captionsngerman{}", "snippet": "\\captionsngerman{$1}", "meta": "ngerman-cmd", "score": 0.00010171098214158578}, {"caption": "\\grqq", "snippet": "\\grqq", "meta": "ngerman-cmd", "score": 0.006659522189248266}, {"caption": "\\grqq{}", "snippet": "\\grqq{$1}", "meta": "ngerman-cmd", "score": 0.006659522189248266}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "ngerman-cmd", "score": 0.0029238994233674776}], "eucal": [{"caption": "\\mathscr{}", "snippet": "\\mathscr{$1}", "meta": "eucal-cmd", "score": 0.025302230226027712}, {"caption": "\\mathcal{}", "snippet": "\\mathcal{$1}", "meta": "eucal-cmd", "score": 0.35084018920966636}], "ifluatex": [{"caption": "\\csname", "snippet": "\\csname", "meta": "ifluatex-cmd", "score": 0.008565354665444157}], "chemfig": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "chemfig-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemfig-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemfig-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemfig-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chemfig-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chemfig-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chemfig-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chemfig-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chemfig-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemfig-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chemfig-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemfig-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chemfig-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chemfig-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chemfig-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "chemfig-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemfig-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemfig-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "chemfig-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "chemfig-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "chemfig-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "chemfig-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "chemfig-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemfig-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "chemfig-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "chemfig-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemfig-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "chemfig-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "chemfig-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chemfig-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chemfig-cmd", "score": 0.2864294797053033}], "abstract": [{"caption": "\\abstractnamefont", "snippet": "\\abstractnamefont", "meta": "abstract-cmd", "score": 6.2350576842596716e-06}], "tikz-cd": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cd-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-cd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-cd-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-cd-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-cd-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-cd-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-cd-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-cd-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cd-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-cd-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-cd-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-cd-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-cd-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-cd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-cd-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-cd-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-cd-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-cd-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-cd-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-cd-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-cd-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-cd-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-cd-cmd", "score": 0.2864294797053033}], "flowfram": [{"caption": "\\framebreak", "snippet": "\\framebreak", "meta": "flowfram-cmd", "score": 0.004019097827091264}, {"caption": "\\newstaticframe{}{}{}{}", "snippet": "\\newstaticframe{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.0014762683341407986}, {"caption": "\\newflowframe{}{}{}{}[]", "snippet": "\\newflowframe{$1}{$2}{$3}{$4}[$5]", "meta": "flowfram-cmd", "score": 0.002952536668281597}, {"caption": "\\csname", "snippet": "\\csname", "meta": "flowfram-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "flowfram-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "flowfram-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "flowfram-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "flowfram-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "flowfram-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "flowfram-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "flowfram-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "flowfram-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "flowfram-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "flowfram-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "flowfram-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "flowfram-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "flowfram-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "flowfram-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "flowfram-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "flowfram-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "flowfram-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "flowfram-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "flowfram-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "flowfram-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "flowfram-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "flowfram-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "flowfram-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "flowfram-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "flowfram-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "flowfram-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "flowfram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "flowfram-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "flowfram-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "flowfram-cmd", "score": 0.004649150613625593}, {"caption": "\\afterpage{}", "snippet": "\\afterpage{$1}", "meta": "flowfram-cmd", "score": 0.0018578070791608345}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "flowfram-cmd", "score": 0.1789117552185788}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "flowfram-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "flowfram-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "flowfram-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "flowfram-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "flowfram-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "flowfram-cmd", "score": 0.0018957469739775527}], "marginnote": [{"caption": "\\marginnote{}", "snippet": "\\marginnote{$1}", "meta": "marginnote-cmd", "score": 0.010285502283803235}, {"caption": "\\marginnote", "snippet": "\\marginnote", "meta": "marginnote-cmd", "score": 0.010285502283803235}, {"caption": "\\raggedleftmarginnote", "snippet": "\\raggedleftmarginnote", "meta": "marginnote-cmd", "score": 0.0011268470793267921}], "xfrac": [{"caption": "\\sfrac{}{}", "snippet": "\\sfrac{$1}{$2}", "meta": "xfrac-cmd", "score": 0.0030164694688453453}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "xfrac-cmd", "score": 0.00037306820619479756}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "xfrac-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "xfrac-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "xfrac-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xfrac-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xfrac-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xfrac-cmd", "score": 0.2864294797053033}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xfrac-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xfrac-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xfrac-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "xfrac-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "xfrac-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "xfrac-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "xfrac-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "xfrac-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xfrac-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "xfrac-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xfrac-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "xfrac-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xfrac-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "xfrac-cmd", "score": 0.004649150613625593}, {"caption": "\\do", "snippet": "\\do", "meta": "xfrac-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "xfrac-cmd", "score": 0.0063276692758974925}], "shortvrb": [{"caption": "\\MakeShortVerb{}", "snippet": "\\MakeShortVerb{$1}", "meta": "shortvrb-cmd", "score": 0.0002890733176655595}, {"caption": "\\do", "snippet": "\\do", "meta": "shortvrb-cmd", "score": 0.009278344180101056}], "animate": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "animate-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "animate-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "animate-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "animate-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "animate-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "animate-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "animate-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "animate-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "animate-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "animate-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "animate-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "animate-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "animate-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "animate-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "animate-cmd", "score": 0.004649150613625593}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "animate-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "animate-cmd", "score": 0.2864294797053033}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "animate-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "animate-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "animate-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "animate-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "animate-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "animate-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "animate-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "animate-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "animate-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "animate-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "animate-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "animate-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "animate-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "animate-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "animate-cmd", "score": 0.0018957469739775527}, {"caption": "\\csname", "snippet": "\\csname", "meta": "animate-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "animate-cmd", "score": 0.008565354665444157}], "euscript": [{"caption": "\\mathscr{}", "snippet": "\\mathscr{$1}", "meta": "euscript-cmd", "score": 0.025302230226027712}, {"caption": "\\mathcal{}", "snippet": "\\mathcal{$1}", "meta": "euscript-cmd", "score": 0.35084018920966636}], "hhline": [{"caption": "\\hhline{}", "snippet": "\\hhline{$1}", "meta": "hhline-cmd", "score": 0.0004816338278157677}], "subfiles": [{"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "subfiles-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "subfiles-cmd", "score": 1.4425339817971206}, {"caption": "\\subfile{}", "snippet": "\\subfile{$1}", "meta": "subfiles-cmd", "score": 0.03337062633525651}, {"caption": "\\endverbatim", "snippet": "\\endverbatim", "meta": "subfiles-cmd", "score": 0.0022216421267780076}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "subfiles-cmd", "score": 0.0072203369120285256}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "subfiles-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "subfiles-cmd", "score": 0.021170869458413965}, {"caption": "\\par", "snippet": "\\par", "meta": "subfiles-cmd", "score": 0.413853376001159}, {"caption": "\\verbatiminput{}", "snippet": "\\verbatiminput{$1}", "meta": "subfiles-cmd", "score": 0.0024547099784948665}, {"caption": "\\verbatiminput", "snippet": "\\verbatiminput", "meta": "subfiles-cmd", "score": 0.0024547099784948665}], "accents": [{"caption": "\\underaccent{}{}", "snippet": "\\underaccent{$1}{$2}", "meta": "accents-cmd", "score": 0.00109513727836357}], "theorem": [{"caption": "\\theorembodyfont{}", "snippet": "\\theorembodyfont{$1}", "meta": "theorem-cmd", "score": 0.00047103366488576113}], "metalogo": [{"caption": "\\XeTeX", "snippet": "\\XeTeX", "meta": "metalogo-cmd", "score": 0.0010635559050357936}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "metalogo-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "metalogo-cmd", "score": 0.02873756018238537}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "metalogo-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "metalogo-cmd", "score": 0.2334089308452787}, {"caption": "\\XeLaTeX", "snippet": "\\XeLaTeX", "meta": "metalogo-cmd", "score": 0.002009786035379175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "metalogo-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "metalogo-cmd", "score": 0.00037306820619479756}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "metalogo-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "metalogo-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "metalogo-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "metalogo-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "metalogo-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "metalogo-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "metalogo-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "metalogo-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "metalogo-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "metalogo-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "metalogo-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "metalogo-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "metalogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "metalogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "metalogo-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "metalogo-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "metalogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "metalogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "metalogo-cmd", "score": 0.004719094298848707}], "bookmark": [{"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "bookmark-cmd", "score": 0.006492248863367502}, {"caption": "\\bookmarkget{}", "snippet": "\\bookmarkget{$1}", "meta": "bookmark-cmd", "score": 0.00026847053008917257}, {"caption": "\\bookmarksetup{}", "snippet": "\\bookmarksetup{$1}", "meta": "bookmark-cmd", "score": 0.001134118016265821}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "bookmark-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "bookmark-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "bookmark-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "bookmark-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "bookmark-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "bookmark-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "bookmark-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "bookmark-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "bookmark-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "bookmark-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "bookmark-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "bookmark-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "bookmark-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "bookmark-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "bookmark-cmd", "score": 0.009472569279662113}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "bookmark-cmd", "score": 0.006492248863367502}, {"caption": "\\figureautorefname", "snippet": "\\figureautorefname", "meta": "bookmark-cmd", "score": 0.00014582556188448738}, {"caption": "\\figureautorefname{}", "snippet": "\\figureautorefname{$1}", "meta": "bookmark-cmd", "score": 0.00014582556188448738}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "bookmark-cmd", "score": 0.006963729684667191}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\footnoteautorefname", "snippet": "\\footnoteautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\roman{}", "snippet": "\\roman{$1}", "meta": "bookmark-cmd", "score": 0.005553384455935491}, {"caption": "\\roman", "snippet": "\\roman", "meta": "bookmark-cmd", "score": 0.005553384455935491}, {"caption": "\\string", "snippet": "\\string", "meta": "bookmark-cmd", "score": 0.001042697111754002}, {"caption": "\\MakeLowercase{}", "snippet": "\\MakeLowercase{$1}", "meta": "bookmark-cmd", "score": 0.017289599800633146}, {"caption": "\\textunderscore", "snippet": "\\textunderscore", "meta": "bookmark-cmd", "score": 0.001509072212764015}, {"caption": "\\do", "snippet": "\\do", "meta": "bookmark-cmd", "score": 0.009278344180101056}, {"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "bookmark-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "bookmark-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "bookmark-cmd", "score": 7.849662248028187}, {"caption": "\\FancyVerbLineautorefname", "snippet": "\\FancyVerbLineautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\hyperlink{}{}", "snippet": "\\hyperlink{$1}{$2}", "meta": "bookmark-cmd", "score": 0.00978652043902115}, {"caption": "\\tableautorefname", "snippet": "\\tableautorefname", "meta": "bookmark-cmd", "score": 0.00012704528567339081}, {"caption": "\\tableautorefname{}", "snippet": "\\tableautorefname{$1}", "meta": "bookmark-cmd", "score": 0.00012704528567339081}, {"caption": "\\equationautorefname", "snippet": "\\equationautorefname", "meta": "bookmark-cmd", "score": 0.00018777198999871106}, {"caption": "\\equationautorefname{}", "snippet": "\\equationautorefname{$1}", "meta": "bookmark-cmd", "score": 0.00018777198999871106}, {"caption": "\\chapterautorefname", "snippet": "\\chapterautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "bookmark-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "bookmark-cmd", "score": 0.02873756018238537}, {"caption": "\\protect", "snippet": "\\protect", "meta": "bookmark-cmd", "score": 0.0200686676229443}, {"caption": "\\appendixautorefname", "snippet": "\\appendixautorefname", "meta": "bookmark-cmd", "score": 7.950698053641679e-05}, {"caption": "\\appendixautorefname{}", "snippet": "\\appendixautorefname{$1}", "meta": "bookmark-cmd", "score": 7.950698053641679e-05}, {"caption": "\\newlabel{}{}", "snippet": "\\newlabel{$1}{$2}", "meta": "bookmark-cmd", "score": 0.00029737672328168955}, {"caption": "\\texorpdfstring{}{}", "snippet": "\\texorpdfstring{$1}{$2}", "meta": "bookmark-cmd", "score": 0.0073781967296121}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "bookmark-cmd", "score": 0.002140559856649122}, {"caption": "\\alph", "snippet": "\\alph", "meta": "bookmark-cmd", "score": 0.01034327266194849}, {"caption": "\\alph{}", "snippet": "\\alph{$1}", "meta": "bookmark-cmd", "score": 0.01034327266194849}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "bookmark-cmd", "score": 0.019788865471151957}, {"caption": "\\item", "snippet": "\\item", "meta": "bookmark-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "bookmark-cmd", "score": 3.800886892251021}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "bookmark-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "bookmark-cmd", "score": 0.2334089308452787}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\itemautorefname", "snippet": "\\itemautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "bookmark-cmd", "score": 1.2569477427490174}, {"caption": "\\sectionautorefname", "snippet": "\\sectionautorefname", "meta": "bookmark-cmd", "score": 0.0019832324299155183}, {"caption": "\\sectionautorefname{}", "snippet": "\\sectionautorefname{$1}", "meta": "bookmark-cmd", "score": 0.0019832324299155183}, {"caption": "\\LaTeXe", "snippet": "\\LaTeXe", "meta": "bookmark-cmd", "score": 0.007928096378157487}, {"caption": "\\LaTeXe{}", "snippet": "\\LaTeXe{$1}", "meta": "bookmark-cmd", "score": 0.007928096378157487}, {"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "bookmark-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "bookmark-cmd", "score": 0.0003680857021151614}, {"caption": "\\hypertarget{}{}", "snippet": "\\hypertarget{$1}{$2}", "meta": "bookmark-cmd", "score": 0.009652820108904094}, {"caption": "\\theoremautorefname", "snippet": "\\theoremautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "bookmark-cmd", "score": 0.7504160124360846}, {"caption": "\\subparagraphautorefname", "snippet": "\\subparagraphautorefname", "meta": "bookmark-cmd", "score": 0.0005446476945175932}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "bookmark-cmd", "score": 0.13586474005868793}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "bookmark-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "bookmark-cmd", "score": 0.8973590434087177}, {"caption": "\\href{}{}", "snippet": "\\href{$1}{$2}", "meta": "bookmark-cmd", "score": 0.27111130260612365}, {"caption": "\\Roman{}", "snippet": "\\Roman{$1}", "meta": "bookmark-cmd", "score": 0.0038703587462843594}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}, {"caption": "\\autoref{}", "snippet": "\\autoref{$1}", "meta": "bookmark-cmd", "score": 0.03741172773691362}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "bookmark-cmd", "score": 0.0004995635515943437}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "bookmark-cmd", "score": 7.847906405228455}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "bookmark-cmd", "score": 0.0174633138331273}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "bookmark-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "bookmark-cmd", "score": 0.006776001543888959}, {"caption": "\\partautorefname", "snippet": "\\partautorefname", "meta": "bookmark-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\Itemautorefname{}", "snippet": "\\Itemautorefname{$1}", "meta": "bookmark-cmd", "score": 6.006262128895586e-05}, {"caption": "\\halign{}", "snippet": "\\halign{$1}", "meta": "bookmark-cmd", "score": 0.00017906650306643613}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "bookmark-cmd", "score": 0.20852115286477566}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "bookmark-cmd", "score": 1.4380093454211778}, {"caption": "\\Alph{}", "snippet": "\\Alph{$1}", "meta": "bookmark-cmd", "score": 0.002233258780143355}, {"caption": "\\Alph", "snippet": "\\Alph", "meta": "bookmark-cmd", "score": 0.002233258780143355}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "bookmark-cmd", "score": 0.047007158741781095}, {"caption": "\\MP", "snippet": "\\MP", "meta": "bookmark-cmd", "score": 0.00018344383742255004}, {"caption": "\\MP{}", "snippet": "\\MP{$1}", "meta": "bookmark-cmd", "score": 0.00018344383742255004}, {"caption": "\\paragraphautorefname", "snippet": "\\paragraphautorefname", "meta": "bookmark-cmd", "score": 0.0005446476945175932}, {"caption": "\\citeN{}", "snippet": "\\citeN{$1}", "meta": "bookmark-cmd", "score": 0.0018503938529945614}, {"caption": "\\citeN", "snippet": "\\citeN", "meta": "bookmark-cmd", "score": 0.0018503938529945614}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "bookmark-cmd", "score": 0.07503475348393239}, {"caption": "\\subsectionautorefname", "snippet": "\\subsectionautorefname", "meta": "bookmark-cmd", "score": 0.0012546605780895737}, {"caption": "\\subsectionautorefname{}", "snippet": "\\subsectionautorefname{$1}", "meta": "bookmark-cmd", "score": 0.0012546605780895737}, {"caption": "\\hyperref[]{}", "snippet": "\\hyperref[$1]{$2}", "meta": "bookmark-cmd", "score": 0.004515152477030062}, {"caption": "\\arabic{}", "snippet": "\\arabic{$1}", "meta": "bookmark-cmd", "score": 0.02445837629741638}, {"caption": "\\arabic", "snippet": "\\arabic", "meta": "bookmark-cmd", "score": 0.02445837629741638}, {"caption": "\\newline", "snippet": "\\newline", "meta": "bookmark-cmd", "score": 0.3311721696201715}, {"caption": "\\hypersetup{}", "snippet": "\\hypersetup{$1}", "meta": "bookmark-cmd", "score": 0.06967310843464661}, {"caption": "\\subsubsectionautorefname", "snippet": "\\subsubsectionautorefname", "meta": "bookmark-cmd", "score": 0.0012064581899162352}, {"caption": "\\subsubsectionautorefname{}", "snippet": "\\subsubsectionautorefname{$1}", "meta": "bookmark-cmd", "score": 0.0012064581899162352}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "bookmark-cmd", "score": 0.9202908262245683}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bookmark-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "bookmark-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "bookmark-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "bookmark-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bookmark-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bookmark-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bookmark-cmd", "score": 0.00530510025314411}], "anysize": [{"caption": "\\marginsize{}{}{}{}", "snippet": "\\marginsize{$1}{$2}{$3}{$4}", "meta": "anysize-cmd", "score": 0.0012034744434699038}], "diagbox": [{"caption": "\\diagbox[]{}{}", "snippet": "\\diagbox[$1]{$2}{$3}", "meta": "diagbox-cmd", "score": 2.2176553306779127e-05}, {"caption": "\\backslashbox{}{}", "snippet": "\\backslashbox{$1}{$2}", "meta": "diagbox-cmd", "score": 0.0005060776550832729}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "diagbox-cmd", "score": 0.00037306820619479756}, {"caption": "\\Line", "snippet": "\\Line", "meta": "diagbox-cmd", "score": 0.0006078790177929149}, {"caption": "\\polygon", "snippet": "\\polygon", "meta": "diagbox-cmd", "score": 0.0008987552240147395}, {"caption": "\\line", "snippet": "\\line", "meta": "diagbox-cmd", "score": 0.014519741542622297}, {"caption": "\\polyline", "snippet": "\\polyline", "meta": "diagbox-cmd", "score": 0.00022468880600368487}, {"caption": "\\vector", "snippet": "\\vector", "meta": "diagbox-cmd", "score": 0.002970308722584179}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "diagbox-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "diagbox-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "diagbox-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "diagbox-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "diagbox-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "diagbox-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "diagbox-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "diagbox-cmd", "score": 0.018615449342361392}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "diagbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "diagbox-cmd", "score": 0.021170869458413965}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "diagbox-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "diagbox-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "diagbox-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "diagbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "diagbox-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "diagbox-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "diagbox-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "diagbox-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "diagbox-cmd", "score": 0.028955796305270766}], "commath": [{"caption": "\\dod{}{}", "snippet": "\\dod{$1}{$2}", "meta": "commath-cmd", "score": 7.950032807135384e-05}, {"caption": "\\dpd{}{}", "snippet": "\\dpd{$1}{$2}", "meta": "commath-cmd", "score": 0.00022966761442835552}, {"caption": "\\dpd[]{}{}", "snippet": "\\dpd[$1]{$2}{$3}", "meta": "commath-cmd", "score": 0.00022966761442835552}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "commath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "commath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "commath-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "commath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "commath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "commath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "commath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "commath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "commath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "commath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "commath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "commath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "commath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "commath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "commath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "commath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "commath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "commath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "commath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "commath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "commath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "commath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "commath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "commath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "commath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "commath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "commath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "commath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "commath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "commath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "commath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "commath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "commath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "commath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "commath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "commath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "commath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "commath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "commath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "commath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "commath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "commath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "commath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "commath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "commath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "commath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "commath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "commath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "commath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "commath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "commath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "commath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "commath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "commath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "commath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "commath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "commath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "commath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "commath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "commath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "commath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "commath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "commath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "commath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "commath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "commath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "commath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "commath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "commath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "commath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "commath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "commath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "commath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "commath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "commath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "commath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "commath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "commath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "commath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "commath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "commath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "commath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "commath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "commath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "commath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "commath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "commath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "commath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "commath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "commath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "commath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "commath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "commath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "commath-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "commath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "commath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "commath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "commath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "commath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "commath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "commath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "commath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "commath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "commath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "commath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "commath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "commath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "commath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "commath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "commath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "commath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "commath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "commath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "commath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "commath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "commath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "commath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "commath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "commath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "commath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "commath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "commath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "commath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "commath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "commath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "commath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "commath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "commath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "commath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "commath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "commath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "commath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "commath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "commath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "commath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "commath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "commath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "commath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "commath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "commath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "commath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "commath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "commath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "commath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "commath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "commath-cmd", "score": 0.0004286136584068833}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "commath-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "commath-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "commath-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "commath-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "commath-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "commath-cmd", "score": 0.0018957469739775527}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "commath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "commath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "commath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "commath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "commath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "commath-cmd", "score": 0.0063276692758974925}], "breqn": [{"caption": "\\biggl", "snippet": "\\biggl", "meta": "breqn-cmd", "score": 0.0016066581118686831}, {"caption": "\\biggl[]", "snippet": "\\biggl[$1]", "meta": "breqn-cmd", "score": 0.0016066581118686831}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "breqn-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "breqn-cmd", "score": 0.015507614799858266}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "breqn-cmd", "score": 7.847906405228455}, {"caption": "\\Big", "snippet": "\\Big", "meta": "breqn-cmd", "score": 0.050370758781422345}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "breqn-cmd", "score": 0.04318078602869565}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "breqn-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "breqn-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "breqn-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "breqn-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "breqn-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "breqn-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "breqn-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "breqn-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "breqn-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "breqn-cmd", "score": 0.028955796305270766}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "breqn-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "breqn-cmd", "score": 0.2864294797053033}], "ClearSans": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "ClearSans-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ClearSans-cmd", "score": 0.008565354665444157}], "ccicons": [{"caption": "\\ccbynd", "snippet": "\\ccbynd", "meta": "ccicons-cmd", "score": 0.0002103469673225986}, {"caption": "\\ccbysa", "snippet": "\\ccbysa", "meta": "ccicons-cmd", "score": 0.00016986782584471025}], "varioref": [{"caption": "\\csname", "snippet": "\\csname", "meta": "varioref-cmd", "score": 0.008565354665444157}], "SIunits": [{"caption": "\\micro", "snippet": "\\micro", "meta": "SIunits-cmd", "score": 0.011051971930487929}, {"caption": "\\meter", "snippet": "\\meter", "meta": "SIunits-cmd", "score": 0.012499244923238213}, {"caption": "\\cdot", "snippet": "\\cdot", "meta": "SIunits-cmd", "score": 0.23029085545522762}, {"caption": "\\degreecelsius", "snippet": "\\degreecelsius", "meta": "SIunits-cmd", "score": 0.002130669712103909}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "SIunits-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "SIunits-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "SIunits-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "SIunits-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "SIunits-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "SIunits-cmd", "score": 0.0063276692758974925}], "alltt": [{"caption": "\\par", "snippet": "\\par", "meta": "alltt-cmd", "score": 0.413853376001159}], "fancyvrb": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fancyvrb-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fancyvrb-cmd", "score": 0.021170869458413965}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "fancyvrb-cmd", "score": 0.002140559856649122}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "fancyvrb-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "fancyvrb-cmd", "score": 0.008565354665444157}, {"caption": "\\fvset{}", "snippet": "\\fvset{$1}", "meta": "fancyvrb-cmd", "score": 0.00015476887282479622}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "fancyvrb-cmd", "score": 0.00037306820619479756}], "textgreek": [{"caption": "\\temp", "snippet": "\\temp", "meta": "textgreek-cmd", "score": 0.0003566413345844499}, {"caption": "\\temp{}", "snippet": "\\temp{$1}", "meta": "textgreek-cmd", "score": 0.0003566413345844499}], "endnotes": [{"caption": "\\endnote", "snippet": "\\endnote", "meta": "endnotes-cmd", "score": 4.002553629215439e-05}, {"caption": "\\theendnotes", "snippet": "\\theendnotes", "meta": "endnotes-cmd", "score": 0.0002788252334941383}], "leading": [{"caption": "\\leading{}", "snippet": "\\leading{$1}", "meta": "leading-cmd", "score": 0.00029077374894594517}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "leading-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "leading-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "leading-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "leading-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "leading-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "leading-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "leading-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "leading-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "leading-cmd", "score": 0.028955796305270766}], "esvect": [{"caption": "\\vv", "snippet": "\\vv", "meta": "esvect-cmd", "score": 0.003087420708479709}, {"caption": "\\vv{}", "snippet": "\\vv{$1}", "meta": "esvect-cmd", "score": 0.003087420708479709}], "lettrine": [{"caption": "\\LettrineFontHook", "snippet": "\\LettrineFontHook", "meta": "lettrine-cmd", "score": 9.103413871235853e-05}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "lettrine-cmd", "score": 0.20852115286477566}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "lettrine-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "lettrine-cmd", "score": 0.2864294797053033}, {"caption": "\\lettrine[]{}{}", "snippet": "\\lettrine[$1]{$2}{$3}", "meta": "lettrine-cmd", "score": 0.0028028146688245602}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "lettrine-cmd", "score": 0.00037306820619479756}], "pgfopts": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfopts-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfopts-cmd", "score": 0.021170869458413965}], "tabulary": [{"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "tabulary-cmd", "score": 0.014532521139459619}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "tabulary-cmd", "score": 0.5473606021405326}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tabulary-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tabulary-cmd", "score": 0.021170869458413965}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "tabulary-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "tabulary-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "tabulary-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "tabulary-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "tabulary-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tabulary-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "tabulary-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "tabulary-cmd", "score": 0.018615449342361392}], "grffile": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "grffile-cmd", "score": 0.00021116765384691477}, {"caption": "\\empty", "snippet": "\\empty", "meta": "grffile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "grffile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "grffile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "grffile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "grffile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "grffile-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "grffile-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "grffile-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "grffile-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "grffile-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "grffile-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "grffile-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "grffile-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "grffile-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "grffile-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "grffile-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "grffile-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "grffile-cmd", "score": 0.004649150613625593}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "grffile-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "grffile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "grffile-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "grffile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "grffile-cmd", "score": 0.021170869458413965}], "pgfgantt": [{"caption": "\\gantttitlecalendar{}", "snippet": "\\gantttitlecalendar{$1}", "meta": "pgfgantt-cmd", "score": 0.00027821409061195467}, {"caption": "\\ganttset{}", "snippet": "\\ganttset{$1}", "meta": "pgfgantt-cmd", "score": 0.0002492292297037303}, {"caption": "\\gantttitlelist[]{}{}", "snippet": "\\gantttitlelist[$1]{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.00046430963549633653}, {"caption": "\\gantttitlelist{}{}", "snippet": "\\gantttitlelist{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.00046430963549633653}, {"caption": "\\ganttlink[]{}{}", "snippet": "\\ganttlink[$1]{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.0011494045501518014}, {"caption": "\\newganttchartelement{}{}", "snippet": "\\newganttchartelement{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.00023651453263545777}, {"caption": "\\gantttitle{}{}", "snippet": "\\gantttitle{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.001804531670553746}, {"caption": "\\gantttitle[]{}{}", "snippet": "\\gantttitle[$1]{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.001804531670553746}, {"caption": "\\setganttlinklabel{}{}", "snippet": "\\setganttlinklabel{$1}{$2}", "meta": "pgfgantt-cmd", "score": 9.045112044064169e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfgantt-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfgantt-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfgantt-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfgantt-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfgantt-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfgantt-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfgantt-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfgantt-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfgantt-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfgantt-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfgantt-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfgantt-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfgantt-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfgantt-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfgantt-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfgantt-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfgantt-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfgantt-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfgantt-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfgantt-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfgantt-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfgantt-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfgantt-cmd", "score": 0.2864294797053033}], "circuitikz": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "circuitikz-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "circuitikz-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "circuitikz-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "circuitikz-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "circuitikz-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "circuitikz-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "circuitikz-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "circuitikz-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "circuitikz-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "circuitikz-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "circuitikz-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "circuitikz-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "circuitikz-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "circuitikz-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "circuitikz-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "circuitikz-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "circuitikz-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "circuitikz-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "circuitikz-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "circuitikz-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "circuitikz-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "circuitikz-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "circuitikz-cmd", "score": 0.2864294797053033}], "hypcap": [{"caption": "\\csname", "snippet": "\\csname", "meta": "hypcap-cmd", "score": 0.008565354665444157}], "scrlayer-scrpage": [{"caption": "\\lofoot{}", "snippet": "\\lofoot{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.00011911213812243537}, {"caption": "\\rofoot{}", "snippet": "\\rofoot{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.00021082185485863327}, {"caption": "\\clearpairofpagestyles", "snippet": "\\clearpairofpagestyles", "meta": "scrlayer-scrpage-cmd", "score": 8.874602750594376e-05}, {"caption": "\\ihead{}", "snippet": "\\ihead{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.0004507603139230655}, {"caption": "\\ihead[]{}", "snippet": "\\ihead[$1]{$2}", "meta": "scrlayer-scrpage-cmd", "score": 0.0004507603139230655}, {"caption": "\\cofoot{}", "snippet": "\\cofoot{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.00021082185485863327}, {"caption": "\\cfoot{}", "snippet": "\\cfoot{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.013411641301057813}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "scrlayer-scrpage-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "scrlayer-scrpage-cmd", "score": 0.1789117552185788}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "scrlayer-scrpage-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "scrlayer-scrpage-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.000396664302361659}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scrlayer-scrpage-cmd", "score": 0.00037306820619479756}, {"caption": "\\automark[]{}", "snippet": "\\automark[$1]{$2}", "meta": "scrlayer-scrpage-cmd", "score": 0.0006703031783997437}, {"caption": "\\automark{}", "snippet": "\\automark{$1}", "meta": "scrlayer-scrpage-cmd", "score": 0.0006703031783997437}, {"caption": "\\pagemark", "snippet": "\\pagemark", "meta": "scrlayer-scrpage-cmd", "score": 0.0017520841736604843}], "amsgen": [{"caption": "\\do", "snippet": "\\do", "meta": "amsgen-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amsgen-cmd", "score": 0.0063276692758974925}], "tipa": [{"caption": "\\textipa{}", "snippet": "\\textipa{$1}", "meta": "tipa-cmd", "score": 0.0028202799587687334}], "appendixnumberbeamer": [{"caption": "\\appendix", "snippet": "\\appendix", "meta": "appendixnumberbeamer-cmd", "score": 0.047007158741781095}, {"caption": "\\inserttotalframenumber", "snippet": "\\inserttotalframenumber", "meta": "appendixnumberbeamer-cmd", "score": 0.0008756113669543194}], "totcount": [{"caption": "\\totvalue{}", "snippet": "\\totvalue{$1}", "meta": "totcount-cmd", "score": 0.000325977535138643}, {"caption": "\\newtotcounter{}", "snippet": "\\newtotcounter{$1}", "meta": "totcount-cmd", "score": 0.004398151085448998}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "totcount-cmd", "score": 0.00037306820619479756}], "atbegshi": [{"caption": "\\empty", "snippet": "\\empty", "meta": "atbegshi-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "atbegshi-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "atbegshi-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "atbegshi-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "atbegshi-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "atbegshi-cmd", "score": 0.008565354665444157}], "environ": [{"caption": "\\csname", "snippet": "\\csname", "meta": "environ-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "environ-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "environ-cmd", "score": 0.021170869458413965}], "arydshln": [{"caption": "\\hdashline", "snippet": "\\hdashline", "meta": "arydshln-cmd", "score": 3.1727559255976046e-05}, {"caption": "\\arrayrulecolor{}", "snippet": "\\arrayrulecolor{$1}", "meta": "arydshln-cmd", "score": 0.008538501902241319}, {"caption": "\\arrayrulecolor[]{}", "snippet": "\\arrayrulecolor[$1]{$2}", "meta": "arydshln-cmd", "score": 0.008538501902241319}, {"caption": "\\hline", "snippet": "\\hline", "meta": "arydshln-cmd", "score": 1.3209538327406387}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "arydshln-cmd", "score": 0.5473606021405326}, {"caption": "\\cline{}", "snippet": "\\cline{$1}", "meta": "arydshln-cmd", "score": 0.07276573550543858}], "fp": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fp-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fp-cmd", "score": 0.021170869458413965}], "here": [{"caption": "\\listof{}{}", "snippet": "\\listof{$1}{$2}", "meta": "here-cmd", "score": 0.0009837365348002915}, {"caption": "\\floatplacement{}{}", "snippet": "\\floatplacement{$1}{$2}", "meta": "here-cmd", "score": 0.0005815474978918903}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "here-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatstyle{}", "snippet": "\\floatstyle{$1}", "meta": "here-cmd", "score": 0.0015470917047414941}, {"caption": "\\floatname{}{}", "snippet": "\\floatname{$1}{$2}", "meta": "here-cmd", "score": 0.0011934321931750752}, {"caption": "\\csname", "snippet": "\\csname", "meta": "here-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "here-cmd", "score": 1.2569477427490174}, {"caption": "\\newfloat{}{}{}", "snippet": "\\newfloat{$1}{$2}{$3}", "meta": "here-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat", "snippet": "\\newfloat", "meta": "here-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat{}", "snippet": "\\newfloat{$1}", "meta": "here-cmd", "score": 0.0012745874472536625}], "layout": [{"caption": "\\layout", "snippet": "\\layout", "meta": "layout-cmd", "score": 0.0003951770756385293}, {"caption": "\\layout{}", "snippet": "\\layout{$1}", "meta": "layout-cmd", "score": 0.0003951770756385293}], "multibib": [{"caption": "\\newcites{}{}", "snippet": "\\newcites{$1}{$2}", "meta": "multibib-cmd", "score": 0.0024438508435048224}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "multibib-cmd", "score": 0.2659628337907604}], "tgpagella": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgpagella-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgpagella-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgpagella-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgpagella-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgpagella-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgpagella-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgpagella-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgpagella-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgpagella-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgpagella-cmd", "score": 0.021170869458413965}], "minitoc": [{"caption": "\\addstarredchapter{}", "snippet": "\\addstarredchapter{$1}", "meta": "minitoc-cmd", "score": 0.0009796486230293261}, {"caption": "\\minitoc", "snippet": "\\minitoc", "meta": "minitoc-cmd", "score": 0.001626371504530358}, {"caption": "\\dominitoc", "snippet": "\\dominitoc", "meta": "minitoc-cmd", "score": 0.0006984399207241325}, {"caption": "\\mtcaddchapter", "snippet": "\\mtcaddchapter", "meta": "minitoc-cmd", "score": 9.045112044064169e-05}, {"caption": "\\listoffigures", "snippet": "\\listoffigures", "meta": "minitoc-cmd", "score": 0.03447318897846567}, {"caption": "\\listoftables", "snippet": "\\listoftables", "meta": "minitoc-cmd", "score": 0.02104656820469027}, {"caption": "\\tableofcontents", "snippet": "\\tableofcontents", "meta": "minitoc-cmd", "score": 0.13360595130994957}, {"caption": "\\adjustmtc", "snippet": "\\adjustmtc", "meta": "minitoc-cmd", "score": 0.00015075186740106945}, {"caption": "\\section{}", "snippet": "\\section{$1}", "meta": "minitoc-cmd", "score": 3.0952612541683835}], "nameref": [{"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "nameref-cmd", "score": 0.009472569279662113}, {"caption": "\\protect", "snippet": "\\protect", "meta": "nameref-cmd", "score": 0.0200686676229443}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "nameref-cmd", "score": 1.4380093454211778}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "nameref-cmd", "score": 0.019788865471151957}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "nameref-cmd", "score": 1.897791904799601}, {"caption": "\\thepage", "snippet": "\\thepage", "meta": "nameref-cmd", "score": 0.0591555998103519}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nameref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "nameref-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "nameref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "nameref-cmd", "score": 0.021170869458413965}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "nameref-cmd", "score": 0.07503475348393239}, {"caption": "\\empty", "snippet": "\\empty", "meta": "nameref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "nameref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nameref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "nameref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "nameref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nameref-cmd", "score": 0.008565354665444157}], "ntheorem": [{"caption": "\\theoremclass{}", "snippet": "\\theoremclass{$1}", "meta": "ntheorem-cmd", "score": 0.0001448542182198375}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "ntheorem-cmd", "score": 0.06345266254167037}, {"caption": "\\theoremstyle{}", "snippet": "\\theoremstyle{$1}", "meta": "ntheorem-cmd", "score": 0.02533412165007986}, {"caption": "\\newshadedtheorem{}{}", "snippet": "\\newshadedtheorem{$1}{$2}", "meta": "ntheorem-cmd", "score": 0.0001632850673327423}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "ntheorem-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "ntheorem-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "ntheorem-cmd", "score": 0.215689795055434}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "ntheorem-cmd", "score": 1.897791904799601}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "ntheorem-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "ntheorem-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "ntheorem-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "ntheorem-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "ntheorem-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "ntheorem-cmd", "score": 0.0018957469739775527}], "tabto": [{"caption": "\\tab", "snippet": "\\tab", "meta": "tabto-cmd", "score": 0.016398493343291305}, {"caption": "\\tab{}", "snippet": "\\tab{$1}", "meta": "tabto-cmd", "score": 0.016398493343291305}, {"caption": "\\NumTabs{}", "snippet": "\\NumTabs{$1}", "meta": "tabto-cmd", "score": 0.00011350525217178113}, {"caption": "\\tabto{}{}", "snippet": "\\tabto{$1}{$2}", "meta": "tabto-cmd", "score": 0.002119919034744357}, {"caption": "\\tabto{}", "snippet": "\\tabto{$1}", "meta": "tabto-cmd", "score": 0.002119919034744357}], "emptypage": [{"caption": "\\cleardoublepage", "snippet": "\\cleardoublepage", "meta": "emptypage-cmd", "score": 0.044016804142963585}], "abntex2abrev": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "abntex2abrev-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "abntex2abrev-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "abntex2abrev-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "abntex2abrev-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "abntex2abrev-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "abntex2abrev-cmd", "score": 0.0018957469739775527}], "scrhack": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "scrhack-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "scrhack-cmd", "score": 0.1789117552185788}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "scrhack-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "scrhack-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "scrhack-cmd", "score": 0.000396664302361659}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scrhack-cmd", "score": 0.00037306820619479756}, {"caption": "\\xpatchcmd{}{}{}{}{}", "snippet": "\\xpatchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "scrhack-cmd", "score": 0.0019344877752147675}, {"caption": "\\xpatchcmd", "snippet": "\\xpatchcmd", "meta": "scrhack-cmd", "score": 0.0019344877752147675}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "scrhack-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "scrhack-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "scrhack-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "scrhack-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "scrhack-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "scrhack-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "scrhack-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "scrhack-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "scrhack-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "scrhack-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "scrhack-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "scrhack-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "scrhack-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "scrhack-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "scrhack-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "scrhack-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "scrhack-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "scrhack-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "scrhack-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "scrhack-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "scrhack-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "scrhack-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "scrhack-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "scrhack-cmd", "score": 0.2864294797053033}], "nth": [{"caption": "\\nth{}", "snippet": "\\nth{$1}", "meta": "nth-cmd", "score": 0.0006155314043974968}, {"caption": "\\thesection", "snippet": "\\thesection", "meta": "nth-cmd", "score": 0.011068945893347528}, {"caption": "\\thesection{}", "snippet": "\\thesection{$1}", "meta": "nth-cmd", "score": 0.011068945893347528}], "showkeys": [{"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "showkeys-cmd", "score": 1.897791904799601}], "fncychap": [{"caption": "\\appendix", "snippet": "\\appendix", "meta": "fncychap-cmd", "score": 0.047007158741781095}, {"caption": "\\ChTitleVar{}", "snippet": "\\ChTitleVar{$1}", "meta": "fncychap-cmd", "score": 0.00047530324346933345}, {"caption": "\\thechapter", "snippet": "\\thechapter", "meta": "fncychap-cmd", "score": 0.011821300392639589}], "ae": [{"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "ae-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "ae-cmd", "score": 0.008427383388519996}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "ae-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ae-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ae-cmd", "score": 0.021170869458413965}], "asymptote": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "asymptote-cmd", "score": 0.00037306820619479756}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "asymptote-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "asymptote-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "asymptote-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "asymptote-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "asymptote-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "asymptote-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "asymptote-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "asymptote-cmd", "score": 0.2864294797053033}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "asymptote-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "asymptote-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "asymptote-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "asymptote-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "asymptote-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "asymptote-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "asymptote-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "asymptote-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "asymptote-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "asymptote-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "asymptote-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "asymptote-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "asymptote-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "asymptote-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "asymptote-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "asymptote-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "asymptote-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "asymptote-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "asymptote-cmd", "score": 0.004649150613625593}, {"caption": "\\csname", "snippet": "\\csname", "meta": "asymptote-cmd", "score": 0.008565354665444157}], "truncate": [{"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "truncate-cmd", "score": 0.04598628699063736}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "truncate-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "truncate-cmd", "score": 0.021170869458413965}], "xpatch": [{"caption": "\\xpatchcmd{}{}{}{}{}", "snippet": "\\xpatchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "xpatch-cmd", "score": 0.0019344877752147675}, {"caption": "\\xpatchcmd", "snippet": "\\xpatchcmd", "meta": "xpatch-cmd", "score": 0.0019344877752147675}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "xpatch-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "xpatch-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "xpatch-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "xpatch-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "xpatch-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "xpatch-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "xpatch-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "xpatch-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "xpatch-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "xpatch-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "xpatch-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "xpatch-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "xpatch-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "xpatch-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "xpatch-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "xpatch-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xpatch-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "xpatch-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "xpatch-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "xpatch-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "xpatch-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xpatch-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xpatch-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xpatch-cmd", "score": 0.2864294797053033}], "totpages": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "totpages-cmd", "score": 0.00037306820619479756}], "fourier": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fourier-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fourier-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fourier-cmd", "score": 0.021170869458413965}], "scrbase": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "scrbase-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "scrbase-cmd", "score": 0.1789117552185788}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scrbase-cmd", "score": 0.00037306820619479756}], "svg": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "svg-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "svg-cmd", "score": 0.1789117552185788}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "svg-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "svg-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "svg-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "svg-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "svg-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "svg-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "svg-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "svg-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "svg-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "svg-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "svg-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "svg-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "svg-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "svg-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "svg-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "svg-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "svg-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "svg-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "svg-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "svg-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "svg-cmd", "score": 0.004649150613625593}, {"caption": "\\csname", "snippet": "\\csname", "meta": "svg-cmd", "score": 0.008565354665444157}], "etex": [{"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "etex-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "etex-cmd", "score": 0.00031058155311734754}], "linguex": [{"caption": "\\Last[]", "snippet": "\\Last[$1]", "meta": "linguex-cmd", "score": 0.0008163755131430334}, {"caption": "\\Last", "snippet": "\\Last", "meta": "linguex-cmd", "score": 0.0008163755131430334}, {"caption": "\\Next", "snippet": "\\Next", "meta": "linguex-cmd", "score": 0.0018776636802289772}, {"caption": "\\Next[]", "snippet": "\\Next[$1]", "meta": "linguex-cmd", "score": 0.0018776636802289772}, {"caption": "\\LLast[]", "snippet": "\\LLast[$1]", "meta": "linguex-cmd", "score": 0.00016327510262860667}, {"caption": "\\LLast", "snippet": "\\LLast", "meta": "linguex-cmd", "score": 0.00016327510262860667}, {"caption": "\\NNext[]", "snippet": "\\NNext[$1]", "meta": "linguex-cmd", "score": 0.0004490065322286684}, {"caption": "\\NNext", "snippet": "\\NNext", "meta": "linguex-cmd", "score": 0.0004490065322286684}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "linguex-cmd", "score": 1.897791904799601}, {"caption": "\\xspace", "snippet": "\\xspace", "meta": "linguex-cmd", "score": 0.07560370351316588}], "adforn": [{"caption": "\\adforn{}", "snippet": "\\adforn{$1}", "meta": "adforn-cmd", "score": 0.0003148505561835075}, {"caption": "\\ding{}", "snippet": "\\ding{$1}", "meta": "adforn-cmd", "score": 0.009992300665793867}], "bigstrut": [{"caption": "\\bigstrut", "snippet": "\\bigstrut", "meta": "bigstrut-cmd", "score": 0.005498219710082848}], "standalone": [{"caption": "\\renewcommand{}{}", "snippet": "\\renewcommand{$1}{$2}", "meta": "standalone-cmd", "score": 0.3267437011085663}, {"caption": "\\renewcommand", "snippet": "\\renewcommand", "meta": "standalone-cmd", "score": 0.3267437011085663}, {"caption": "\\currfiledir", "snippet": "\\currfiledir", "meta": "standalone-cmd", "score": 0.0002459788020229296}, {"caption": "\\empty", "snippet": "\\empty", "meta": "standalone-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "standalone-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "standalone-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "standalone-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "standalone-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "standalone-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "standalone-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "standalone-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "standalone-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "standalone-cmd", "score": 0.021170869458413965}], "ifsym": [{"caption": "\\Letter", "snippet": "\\Letter", "meta": "ifsym-cmd", "score": 0.0012281130571092198}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "ifsym-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "ifsym-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "ifsym-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ifsym-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ifsym-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "ifsym-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "ifsym-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "ifsym-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "ifsym-cmd", "score": 0.028955796305270766}], "newtxtext": [{"caption": "\\textsc{}", "snippet": "\\textsc{$1}", "meta": "newtxtext-cmd", "score": 0.6926466355384758}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "newtxtext-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "newtxtext-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "newtxtext-cmd", "score": 0.021170869458413965}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "newtxtext-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "newtxtext-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "newtxtext-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "newtxtext-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "newtxtext-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "newtxtext-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "newtxtext-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "newtxtext-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "newtxtext-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "newtxtext-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "newtxtext-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "newtxtext-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "newtxtext-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "newtxtext-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "newtxtext-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "newtxtext-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "newtxtext-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "newtxtext-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "newtxtext-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "newtxtext-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "newtxtext-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "newtxtext-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "newtxtext-cmd", "score": 0.008565354665444157}], "silence": [{"caption": "\\WarningsOff[]", "snippet": "\\WarningsOff[$1]", "meta": "silence-cmd", "score": 0.00014933999190577243}, {"caption": "\\WarningFilter{}{}", "snippet": "\\WarningFilter{$1}{$2}", "meta": "silence-cmd", "score": 0.0010293824370507024}], "numprint": [{"caption": "\\textcelsius", "snippet": "\\textcelsius", "meta": "numprint-cmd", "score": 0.00012244782670334462}, {"caption": "\\pm", "snippet": "\\pm", "meta": "numprint-cmd", "score": 0.15663535405975132}, {"caption": "\\npdecimalsign{}", "snippet": "\\npdecimalsign{$1}", "meta": "numprint-cmd", "score": 8.401009062000455e-06}, {"caption": "\\npthousandsep{}", "snippet": "\\npthousandsep{$1}", "meta": "numprint-cmd", "score": 8.401009062000455e-06}, {"caption": "\\np{}", "snippet": "\\np{$1}", "meta": "numprint-cmd", "score": 0.0001782233963311367}, {"caption": "\\np", "snippet": "\\np", "meta": "numprint-cmd", "score": 0.0001782233963311367}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "numprint-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "numprint-cmd", "score": 0.2864294797053033}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "numprint-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "numprint-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "numprint-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "numprint-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "numprint-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "numprint-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "numprint-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "numprint-cmd", "score": 0.018615449342361392}], "srcltx": [{"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "srcltx-cmd", "score": 0.2659628337907604}, {"caption": "\\input{}", "snippet": "\\input{$1}", "meta": "srcltx-cmd", "score": 0.4966021927742672}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "srcltx-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "srcltx-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "srcltx-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "srcltx-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "srcltx-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "srcltx-cmd", "score": 0.0018957469739775527}], "ctable": [{"caption": "\\tmark[]", "snippet": "\\tmark[$1]", "meta": "ctable-cmd", "score": 0.004423748442334348}, {"caption": "\\ctable[]{}{}{}", "snippet": "\\ctable[$1]{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.0007377841391165772}, {"caption": "\\let", "snippet": "\\let", "meta": "ctable-cmd", "score": 0.03789745970461662}, {"caption": "\\write", "snippet": "\\write", "meta": "ctable-cmd", "score": 0.0008038857295393196}, {"caption": "\\tabularxcolumn[]{}", "snippet": "\\tabularxcolumn[$1]{$2}", "meta": "ctable-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularxcolumn", "snippet": "\\tabularxcolumn", "meta": "ctable-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularx{}{}", "snippet": "\\tabularx{$1}{$2}", "meta": "ctable-cmd", "score": 0.0005861357565780464}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ctable-cmd", "score": 0.014532521139459619}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "ctable-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ctable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ctable-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "ctable-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "ctable-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "ctable-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "ctable-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "ctable-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "ctable-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ctable-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "ctable-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "ctable-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "ctable-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "ctable-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "ctable-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "ctable-cmd", "score": 0.0018957469739775527}, {"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "ctable-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "ctable-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "ctable-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "ctable-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "ctable-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "ctable-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "ctable-cmd", "score": 0.059857788139528495}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "ctable-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ctable-cmd", "score": 0.008565354665444157}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "ctable-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "ctable-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ctable-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "ctable-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ctable-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "ctable-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "ctable-cmd", "score": 0.018615449342361392}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "ctable-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "ctable-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "ctable-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "ctable-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "ctable-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "ctable-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "ctable-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "ctable-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "ctable-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "ctable-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "ctable-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "ctable-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "ctable-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "ctable-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ctable-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "ctable-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ctable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ctable-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "ctable-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "ctable-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "ctable-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "ctable-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "ctable-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "ctable-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ctable-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "ctable-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "ctable-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "ctable-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "ctable-cmd", "score": 0.2864294797053033}], "bbding": [{"caption": "\\HandRight", "snippet": "\\HandRight", "meta": "bbding-cmd", "score": 9.986169155719329e-05}, {"caption": "\\XSolidBrush", "snippet": "\\XSolidBrush", "meta": "bbding-cmd", "score": 0.0003502234425563509}, {"caption": "\\Checkmark", "snippet": "\\Checkmark", "meta": "bbding-cmd", "score": 0.0010506703276690528}], "endfloat": [{"caption": "\\DeclareDelayedFloatFlavor{}{}", "snippet": "\\DeclareDelayedFloatFlavor{$1}{$2}", "meta": "endfloat-cmd", "score": 0.00012872796177294446}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "endfloat-cmd", "score": 0.00037306820619479756}], "centernot": [{"caption": "\\centernot", "snippet": "\\centernot", "meta": "centernot-cmd", "score": 0.0002513707969474898}], "tikzpagenodes": [{"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpagenodes-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpagenodes-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzpagenodes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzpagenodes-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikzpagenodes-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikzpagenodes-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikzpagenodes-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpagenodes-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikzpagenodes-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpagenodes-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikzpagenodes-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikzpagenodes-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzpagenodes-cmd", "score": 0.004719094298848707}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpagenodes-cmd", "score": 0.00530510025314411}, {"caption": "\\checkoddpage", "snippet": "\\checkoddpage", "meta": "tikzpagenodes-cmd", "score": 0.00028672585452906425}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikzpagenodes-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzpagenodes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzpagenodes-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikzpagenodes-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzpagenodes-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikzpagenodes-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzpagenodes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikzpagenodes-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikzpagenodes-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikzpagenodes-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikzpagenodes-cmd", "score": 0.2864294797053033}], "xargs": [{"caption": "\\newcommandx{}[][]{}", "snippet": "\\newcommandx{$1}[$2][$3]{$4}", "meta": "xargs-cmd", "score": 0.0001110821063389004}], "morefloats": [{"caption": "\\empty", "snippet": "\\empty", "meta": "morefloats-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "morefloats-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "morefloats-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "morefloats-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "morefloats-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "morefloats-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "morefloats-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "morefloats-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "morefloats-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "morefloats-cmd", "score": 0.021170869458413965}], "background": [{"caption": "\\BgThispage", "snippet": "\\BgThispage", "meta": "background-cmd", "score": 0.0003956357273698423}, {"caption": "\\backgroundsetup{}", "snippet": "\\backgroundsetup{$1}", "meta": "background-cmd", "score": 0.0004910777123492879}], "bibunits": [{"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "bibunits-cmd", "score": 0.2659628337907604}], "moresize": [{"caption": "\\Huge", "snippet": "\\Huge", "meta": "moresize-cmd", "score": 0.04725806985998919}], "pgfpages": [{"caption": "\\pgfpagesphysicalpageoptions{}", "snippet": "\\pgfpagesphysicalpageoptions{$1}", "meta": "pgfpages-cmd", "score": 0.00045967325420052095}, {"caption": "\\pgfpageslogicalpageoptions{}{}", "snippet": "\\pgfpageslogicalpageoptions{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.00045967325420052095}, {"caption": "\\pgfpageoptionborder{}", "snippet": "\\pgfpageoptionborder{$1}", "meta": "pgfpages-cmd", "score": 0.0009193465084010419}, {"caption": "\\pgfpageoptionborder", "snippet": "\\pgfpageoptionborder", "meta": "pgfpages-cmd", "score": 0.0009193465084010419}, {"caption": "\\pgfpagesdeclarelayout{}{}{}", "snippet": "\\pgfpagesdeclarelayout{$1}{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.00045967325420052095}, {"caption": "\\pgfpagesuselayout{}", "snippet": "\\pgfpagesuselayout{$1}", "meta": "pgfpages-cmd", "score": 0.0006090132461062934}, {"caption": "\\pgfpagesuselayout{}[]", "snippet": "\\pgfpagesuselayout{$1}[$2]", "meta": "pgfpages-cmd", "score": 0.0006090132461062934}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "pgfpages-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "pgfpages-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "pgfpages-cmd", "score": 0.028955796305270766}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfpages-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfpages-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfpages-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfpages-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfpages-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfpages-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfpages-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfpages-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfpages-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfpages-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfpages-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfpages-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfpages-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfpages-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfpages-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfpages-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfpages-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfpages-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfpages-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfpages-cmd", "score": 0.2864294797053033}], "ctex": [{"caption": "\\CTeX", "snippet": "\\CTeX", "meta": "ctex-cmd", "score": 0.0005884706823906032}, {"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "ctex-cmd", "score": 0.04598628699063736}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "ctex-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "ctex-cmd", "score": 0.2864294797053033}], "algcompatible": [{"caption": "\\algrenewcommand", "snippet": "\\algrenewcommand", "meta": "algcompatible-cmd", "score": 0.0019861803661869416}, {"caption": "\\Statex", "snippet": "\\Statex", "meta": "algcompatible-cmd", "score": 0.008622777195102994}, {"caption": "\\BState{}", "snippet": "\\BState{$1}", "meta": "algcompatible-cmd", "score": 0.0008685861525307122}, {"caption": "\\BState", "snippet": "\\BState", "meta": "algcompatible-cmd", "score": 0.0008685861525307122}, {"caption": "\\algloopdefx{}[][]{}", "snippet": "\\algloopdefx{$1}[$2][$3]{$4}", "meta": "algcompatible-cmd", "score": 0.00025315185701145097}, {"caption": "\\algnewcommand", "snippet": "\\algnewcommand", "meta": "algcompatible-cmd", "score": 0.0030209395012065327}, {"caption": "\\algnewcommand{}[]{}", "snippet": "\\algnewcommand{$1}[$2]{$3}", "meta": "algcompatible-cmd", "score": 0.0030209395012065327}, {"caption": "\\Comment{}", "snippet": "\\Comment{$1}", "meta": "algcompatible-cmd", "score": 0.005178604573219454}, {"caption": "\\algblockdefx{}{}[]", "snippet": "\\algblockdefx{$1}{$2}[$3]", "meta": "algcompatible-cmd", "score": 0.00025315185701145097}, {"caption": "\\algrenewtext{}{}", "snippet": "\\algrenewtext{$1}{$2}", "meta": "algcompatible-cmd", "score": 0.0024415580558825975}, {"caption": "\\algrenewtext{}[]{}", "snippet": "\\algrenewtext{$1}[$2]{$3}", "meta": "algcompatible-cmd", "score": 0.0024415580558825975}, {"caption": "\\algblock{}{}", "snippet": "\\algblock{$1}{$2}", "meta": "algcompatible-cmd", "score": 0.0007916858220314837}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algcompatible-cmd", "score": 0.008565354665444157}, {"caption": "\\algdef{}[]{}{}{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "algcompatible-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}{}[]{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}[$5]{$6}{$7}", "meta": "algcompatible-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}[]{}", "snippet": "\\algdef{$1}[$2]{$3}[$4]{$5}", "meta": "algcompatible-cmd", "score": 0.0003102486920966127}, {"caption": "\\algtext{}", "snippet": "\\algtext{$1}", "meta": "algcompatible-cmd", "score": 0.0005463612015579842}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algcompatible-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algcompatible-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algcompatible-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algcompatible-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algcompatible-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algcompatible-cmd", "score": 0.0018957469739775527}], "draftwatermark": [{"caption": "\\SetWatermarkScale{}", "snippet": "\\SetWatermarkScale{$1}", "meta": "draftwatermark-cmd", "score": 0.0013776850432469145}, {"caption": "\\SetWatermarkText{}", "snippet": "\\SetWatermarkText{$1}", "meta": "draftwatermark-cmd", "score": 0.0017209596079747669}, {"caption": "\\SetWatermarkColor[]{}", "snippet": "\\SetWatermarkColor[$1]{$2}", "meta": "draftwatermark-cmd", "score": 0.0007061648188687239}, {"caption": "\\SetWatermarkFontSize{}", "snippet": "\\SetWatermarkFontSize{$1}", "meta": "draftwatermark-cmd", "score": 0.0005747853176838451}, {"caption": "\\SetWatermarkLightness{}", "snippet": "\\SetWatermarkLightness{$1}", "meta": "draftwatermark-cmd", "score": 0.0005747853176838451}, {"caption": "\\SetWatermarkAngle{}", "snippet": "\\SetWatermarkAngle{$1}", "meta": "draftwatermark-cmd", "score": 0.0005747853176838451}, {"caption": "\\csname", "snippet": "\\csname", "meta": "draftwatermark-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.00037306820619479756}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "draftwatermark-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "draftwatermark-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "draftwatermark-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "draftwatermark-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "draftwatermark-cmd", "score": 0.2864294797053033}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "draftwatermark-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "draftwatermark-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "draftwatermark-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "draftwatermark-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "draftwatermark-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "draftwatermark-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "draftwatermark-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "draftwatermark-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "draftwatermark-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "draftwatermark-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "draftwatermark-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "draftwatermark-cmd", "score": 0.004719094298848707}], "eqparbox": [{"caption": "\\eqparbox{}{}", "snippet": "\\eqparbox{$1}{$2}", "meta": "eqparbox-cmd", "score": 2.9423534119530166e-05}, {"caption": "\\item", "snippet": "\\item", "meta": "eqparbox-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "eqparbox-cmd", "score": 3.800886892251021}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "eqparbox-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "eqparbox-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "eqparbox-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "eqparbox-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "eqparbox-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "eqparbox-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "eqparbox-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "eqparbox-cmd", "score": 0.018615449342361392}, {"caption": "\\csname", "snippet": "\\csname", "meta": "eqparbox-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "eqparbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "eqparbox-cmd", "score": 0.021170869458413965}], "nowidow": [{"caption": "\\empty", "snippet": "\\empty", "meta": "nowidow-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "nowidow-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nowidow-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "nowidow-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "nowidow-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nowidow-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nowidow-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "nowidow-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "nowidow-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "nowidow-cmd", "score": 0.021170869458413965}], "stackrel": [{"caption": "\\stackrel{}{}", "snippet": "\\stackrel{$1}{$2}", "meta": "stackrel-cmd", "score": 0.009911875742973681}, {"caption": "\\csname", "snippet": "\\csname", "meta": "stackrel-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "stackrel-cmd", "score": 0.002958865219480927}], "threeparttablex": [{"caption": "\\item", "snippet": "\\item", "meta": "threeparttablex-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "threeparttablex-cmd", "score": 3.800886892251021}, {"caption": "\\insertTableNotes", "snippet": "\\insertTableNotes", "meta": "threeparttablex-cmd", "score": 4.002553629215439e-05}, {"caption": "\\tnotex{}", "snippet": "\\tnotex{$1}", "meta": "threeparttablex-cmd", "score": 0.0021491972748178554}, {"caption": "\\csname", "snippet": "\\csname", "meta": "threeparttablex-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "threeparttablex-cmd", "score": 0.008565354665444157}, {"caption": "\\item", "snippet": "\\item", "meta": "threeparttablex-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "threeparttablex-cmd", "score": 3.800886892251021}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "threeparttablex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "threeparttablex-cmd", "score": 0.021170869458413965}], "mathdesign": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mathdesign-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mathdesign-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mathdesign-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "mathdesign-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "mathdesign-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "mathdesign-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "mathdesign-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "mathdesign-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "mathdesign-cmd", "score": 0.0018957469739775527}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "mathdesign-cmd", "score": 0.00037306820619479756}], "pst-node": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-node-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-node-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-node-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-node-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-node-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-node-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-node-cmd", "score": 0.006520475264573554}], "varwidth": [{"caption": "\\par", "snippet": "\\par", "meta": "varwidth-cmd", "score": 0.413853376001159}], "schemabloc": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "schemabloc-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "schemabloc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "schemabloc-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "schemabloc-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "schemabloc-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "schemabloc-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "schemabloc-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "schemabloc-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "schemabloc-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "schemabloc-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "schemabloc-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "schemabloc-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "schemabloc-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "schemabloc-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "schemabloc-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "schemabloc-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "schemabloc-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "schemabloc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "schemabloc-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "schemabloc-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "schemabloc-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "schemabloc-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "schemabloc-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "schemabloc-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "schemabloc-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "schemabloc-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "schemabloc-cmd", "score": 0.2864294797053033}], "bigints": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "bigints-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "bigints-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "bigints-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "bigints-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "bigints-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "bigints-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "bigints-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "bigints-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "bigints-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "bigints-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "bigints-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "bigints-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "bigints-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "bigints-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "bigints-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "bigints-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "bigints-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "bigints-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "bigints-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "bigints-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "bigints-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "bigints-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "bigints-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "bigints-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "bigints-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "bigints-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "bigints-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "bigints-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "bigints-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "bigints-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "bigints-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "bigints-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "bigints-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "bigints-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "bigints-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "bigints-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "bigints-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "bigints-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "bigints-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "bigints-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "bigints-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "bigints-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "bigints-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "bigints-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "bigints-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "bigints-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "bigints-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "bigints-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "bigints-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "bigints-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "bigints-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "bigints-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "bigints-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "bigints-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "bigints-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "bigints-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "bigints-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "bigints-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "bigints-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "bigints-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "bigints-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "bigints-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "bigints-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "bigints-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "bigints-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "bigints-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "bigints-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "bigints-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "bigints-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "bigints-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "bigints-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "bigints-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "bigints-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "bigints-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "bigints-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "bigints-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "bigints-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "bigints-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "bigints-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "bigints-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "bigints-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "bigints-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "bigints-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "bigints-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "bigints-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "bigints-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "bigints-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "bigints-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "bigints-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "bigints-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "bigints-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "bigints-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "bigints-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "bigints-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "bigints-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "bigints-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "bigints-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "bigints-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "bigints-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "bigints-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "bigints-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "bigints-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "bigints-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "bigints-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "bigints-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "bigints-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "bigints-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "bigints-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "bigints-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "bigints-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "bigints-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "bigints-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "bigints-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "bigints-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "bigints-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "bigints-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "bigints-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "bigints-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "bigints-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "bigints-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "bigints-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "bigints-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "bigints-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "bigints-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "bigints-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "bigints-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "bigints-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "bigints-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "bigints-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "bigints-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "bigints-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "bigints-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "bigints-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "bigints-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "bigints-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "bigints-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "bigints-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "bigints-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "bigints-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "bigints-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "bigints-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "bigints-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "bigints-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "bigints-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "bigints-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "bigints-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "bigints-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "bigints-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "bigints-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bigints-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "bigints-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "bigints-cmd", "score": 0.0063276692758974925}], "classicthesis": [{"caption": "\\marginpar{}", "snippet": "\\marginpar{$1}", "meta": "classicthesis-cmd", "score": 0.003400158497921723}, {"caption": "\\marginpar", "snippet": "\\marginpar", "meta": "classicthesis-cmd", "score": 0.003400158497921723}, {"caption": "\\cftsecleader", "snippet": "\\cftsecleader", "meta": "classicthesis-cmd", "score": 0.0011340882025681251}, {"caption": "\\cftsubsecleader", "snippet": "\\cftsubsecleader", "meta": "classicthesis-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\spacedlowsmallcaps{}", "snippet": "\\spacedlowsmallcaps{$1}", "meta": "classicthesis-cmd", "score": 0.002677188251799468}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "classicthesis-cmd", "score": 0.005008938879210868}, {"caption": "\\chaptermark", "snippet": "\\chaptermark", "meta": "classicthesis-cmd", "score": 0.005924520024686584}, {"caption": "\\chaptermark{}", "snippet": "\\chaptermark{$1}", "meta": "classicthesis-cmd", "score": 0.005924520024686584}, {"caption": "\\part{}", "snippet": "\\part{$1}", "meta": "classicthesis-cmd", "score": 0.022180129487444723}, {"caption": "\\tocEntry{}", "snippet": "\\tocEntry{$1}", "meta": "classicthesis-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\graffito{}", "snippet": "\\graffito{$1}", "meta": "classicthesis-cmd", "score": 1.1006799670632527e-05}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "classicthesis-cmd", "score": 0.422097569591803}, {"caption": "\\spacedallcaps{}", "snippet": "\\spacedallcaps{$1}", "meta": "classicthesis-cmd", "score": 0.0015281000475958944}, {"caption": "\\cftchapleader", "snippet": "\\cftchapleader", "meta": "classicthesis-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\myVersion", "snippet": "\\myVersion", "meta": "classicthesis-cmd", "score": 0.00018029288638573757}, {"caption": "\\ctparttext{}", "snippet": "\\ctparttext{$1}", "meta": "classicthesis-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "classicthesis-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "classicthesis-cmd", "score": 0.1789117552185788}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.00037306820619479756}, {"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "classicthesis-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "classicthesis-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "classicthesis-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "classicthesis-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "classicthesis-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "classicthesis-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "classicthesis-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "classicthesis-cmd", "score": 0.059857788139528495}, {"caption": "\\titleclass{}{}[]", "snippet": "\\titleclass{$1}{$2}[$3]", "meta": "classicthesis-cmd", "score": 0.00028979763314974667}, {"caption": "\\titlelabel{}", "snippet": "\\titlelabel{$1}", "meta": "classicthesis-cmd", "score": 6.40387839367932e-06}, {"caption": "\\thetitle", "snippet": "\\thetitle", "meta": "classicthesis-cmd", "score": 0.0015531478302713473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "classicthesis-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "classicthesis-cmd", "score": 0.021170869458413965}, {"caption": "\\titleformat{}{}{}{}{}[]", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}[$6]", "meta": "classicthesis-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}[]{}{}{}{}", "snippet": "\\titleformat{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "classicthesis-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}", "snippet": "\\titleformat{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}{}{}{}", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}", "meta": "classicthesis-cmd", "score": 0.03475519439740096}, {"caption": "\\titlespacing{}{}{}{}", "snippet": "\\titlespacing{$1}{$2}{$3}{$4}", "meta": "classicthesis-cmd", "score": 0.023062744385192156}, {"caption": "\\markboth{}{}", "snippet": "\\markboth{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.038323601301945065}, {"caption": "\\markboth{}", "snippet": "\\markboth{$1}", "meta": "classicthesis-cmd", "score": 0.038323601301945065}, {"caption": "\\markright{}", "snippet": "\\markright{$1}", "meta": "classicthesis-cmd", "score": 0.007138622674767024}, {"caption": "\\markright{}{}", "snippet": "\\markright{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.007138622674767024}, {"caption": "\\filleft", "snippet": "\\filleft", "meta": "classicthesis-cmd", "score": 7.959989906732799e-05}, {"caption": "\\filcenter", "snippet": "\\filcenter", "meta": "classicthesis-cmd", "score": 0.0004835660211260246}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "classicthesis-cmd", "score": 0.2253056071787701}, {"caption": "\\cleardoublepage", "snippet": "\\cleardoublepage", "meta": "classicthesis-cmd", "score": 0.044016804142963585}, {"caption": "\\csname", "snippet": "\\csname", "meta": "classicthesis-cmd", "score": 0.008565354665444157}, {"caption": "\\chaptertitlename", "snippet": "\\chaptertitlename", "meta": "classicthesis-cmd", "score": 0.0016985007766926272}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "classicthesis-cmd", "score": 0.3277033727934986}, {"caption": "\\filright", "snippet": "\\filright", "meta": "classicthesis-cmd", "score": 7.959989906732799e-05}, {"caption": "\\titlerule", "snippet": "\\titlerule", "meta": "classicthesis-cmd", "score": 0.019273712561461216}, {"caption": "\\titlerule[]{}", "snippet": "\\titlerule[$1]{$2}", "meta": "classicthesis-cmd", "score": 0.019273712561461216}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "classicthesis-cmd", "score": 0.000396664302361659}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "classicthesis-cmd", "score": 2.341195220791228}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "classicthesis-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "classicthesis-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "classicthesis-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "classicthesis-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "classicthesis-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "classicthesis-cmd", "score": 0.0018957469739775527}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "classicthesis-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "classicthesis-cmd", "score": 0.021170869458413965}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "classicthesis-cmd", "score": 0.00530510025314411}, {"caption": "\\lsstyle", "snippet": "\\lsstyle", "meta": "classicthesis-cmd", "score": 0.0023367519914345774}, {"caption": "\\space", "snippet": "\\space", "meta": "classicthesis-cmd", "score": 0.023010789853665694}, {"caption": "\\DisableLigatures[]{}", "snippet": "\\DisableLigatures[$1]{$2}", "meta": "classicthesis-cmd", "score": 0.0009805246614299932}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "classicthesis-cmd", "score": 0.00021116765384691477}], "expl3": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "expl3-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "expl3-cmd", "score": 0.2864294797053033}], "pst-plot": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-plot-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-plot-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-plot-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-plot-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-plot-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-plot-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-plot-cmd", "score": 0.006520475264573554}], "chemarrow": [{"caption": "\\chemarrow", "snippet": "\\chemarrow", "meta": "chemarrow-cmd", "score": 0.0005176077206367611}], "prettyref": [{"caption": "\\newrefformat{}{}", "snippet": "\\newrefformat{$1}{$2}", "meta": "prettyref-cmd", "score": 0.001373625900102228}, {"caption": "\\prettyref{}", "snippet": "\\prettyref{$1}", "meta": "prettyref-cmd", "score": 0.005783541047730358}], "versions": [{"caption": "\\includeversion{}", "snippet": "\\includeversion{$1}", "meta": "versions-cmd", "score": 0.0028410409433993543}, {"caption": "\\excludeversion{}", "snippet": "\\excludeversion{$1}", "meta": "versions-cmd", "score": 0.001742562336270228}, {"caption": "\\processifversion{}{}", "snippet": "\\processifversion{$1}{$2}", "meta": "versions-cmd", "score": 0.0022991412707353805}], "contour": [{"caption": "\\contour{}{}", "snippet": "\\contour{$1}{$2}", "meta": "contour-cmd", "score": 0.0008245159401597211}, {"caption": "\\contourlength{}", "snippet": "\\contourlength{$1}", "meta": "contour-cmd", "score": 8.130187059343861e-05}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "contour-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "contour-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "contour-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "contour-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "contour-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "contour-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "contour-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "contour-cmd", "score": 0.2864294797053033}, {"caption": "\\csname", "snippet": "\\csname", "meta": "contour-cmd", "score": 0.008565354665444157}], "xintexpr": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xintexpr-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xintexpr-cmd", "score": 0.021170869458413965}], "tocstyle": [{"caption": "\\usetocstyle{}", "snippet": "\\usetocstyle{$1}", "meta": "tocstyle-cmd", "score": 3.2405622997778076e-06}], "bigdelim": [{"caption": "\\multirow{}{}{}", "snippet": "\\multirow{$1}{$2}{$3}", "meta": "bigdelim-cmd", "score": 0.07525389638751734}, {"caption": "\\multirow{}[]{}{}", "snippet": "\\multirow{$1}[$2]{$3}{$4}", "meta": "bigdelim-cmd", "score": 0.07525389638751734}], "eulervm": [{"caption": "\\big", "snippet": "\\big", "meta": "eulervm-cmd", "score": 0.05613164277964739}], "xr": [{"caption": "\\externaldocument{}", "snippet": "\\externaldocument{$1}", "meta": "xr-cmd", "score": 0.0008648763879096798}], "yhmath": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "yhmath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "yhmath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "yhmath-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "yhmath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "yhmath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "yhmath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "yhmath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "yhmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "yhmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "yhmath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "yhmath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "yhmath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "yhmath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "yhmath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "yhmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "yhmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "yhmath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "yhmath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "yhmath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "yhmath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "yhmath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "yhmath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "yhmath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "yhmath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "yhmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "yhmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "yhmath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "yhmath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "yhmath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "yhmath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "yhmath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "yhmath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "yhmath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "yhmath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "yhmath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "yhmath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "yhmath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "yhmath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "yhmath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "yhmath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "yhmath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "yhmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "yhmath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "yhmath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "yhmath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "yhmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "yhmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "yhmath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "yhmath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "yhmath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "yhmath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "yhmath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "yhmath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "yhmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "yhmath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "yhmath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "yhmath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "yhmath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "yhmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "yhmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "yhmath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "yhmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "yhmath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "yhmath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "yhmath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "yhmath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "yhmath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "yhmath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "yhmath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "yhmath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "yhmath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "yhmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "yhmath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "yhmath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "yhmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "yhmath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "yhmath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "yhmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "yhmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "yhmath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "yhmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "yhmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "yhmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "yhmath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "yhmath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "yhmath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "yhmath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "yhmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "yhmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "yhmath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "yhmath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "yhmath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "yhmath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "yhmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "yhmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "yhmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "yhmath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "yhmath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "yhmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "yhmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "yhmath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "yhmath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "yhmath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "yhmath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "yhmath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "yhmath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "yhmath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "yhmath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "yhmath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "yhmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "yhmath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "yhmath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "yhmath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "yhmath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "yhmath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "yhmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "yhmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "yhmath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "yhmath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "yhmath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "yhmath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "yhmath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "yhmath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "yhmath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "yhmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "yhmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "yhmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "yhmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "yhmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "yhmath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "yhmath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "yhmath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "yhmath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "yhmath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "yhmath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "yhmath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "yhmath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "yhmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "yhmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "yhmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "yhmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "yhmath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "yhmath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "yhmath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "yhmath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "yhmath-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "yhmath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "yhmath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "yhmath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "yhmath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "yhmath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "yhmath-cmd", "score": 0.0063276692758974925}], "XCharter": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "XCharter-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "XCharter-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "XCharter-cmd", "score": 0.021170869458413965}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "XCharter-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "XCharter-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "XCharter-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "XCharter-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "XCharter-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "XCharter-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "XCharter-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "XCharter-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "XCharter-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "XCharter-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "XCharter-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "XCharter-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "XCharter-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "XCharter-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "XCharter-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "XCharter-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "XCharter-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "XCharter-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "XCharter-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "XCharter-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "XCharter-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "XCharter-cmd", "score": 0.008565354665444157}], "tikz-feynman": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-feynman-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-feynman-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-feynman-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-feynman-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-feynman-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-feynman-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-feynman-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-feynman-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-feynman-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-feynman-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-feynman-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-feynman-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-feynman-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-feynman-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-feynman-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-feynman-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-feynman-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-feynman-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-feynman-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-feynman-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-feynman-cmd", "score": 0.2864294797053033}], "easylist": [{"caption": "\\ListProperties", "snippet": "\\ListProperties", "meta": "easylist-cmd", "score": 5.7747123038330224e-05}], "hologo": [{"caption": "\\hologo{}", "snippet": "\\hologo{$1}", "meta": "hologo-cmd", "score": 0.00028086100750460613}], "cases": [{"caption": "\\theequation", "snippet": "\\theequation", "meta": "cases-cmd", "score": 0.002995924112493351}], "xint": [{"caption": "\\xintSgnFork{}", "snippet": "\\xintSgnFork{$1}", "meta": "xint-cmd", "score": 0.0005720629946669665}, {"caption": "\\xintCmp{}{}", "snippet": "\\xintCmp{$1}{$2}", "meta": "xint-cmd", "score": 0.0002860314973334833}, {"caption": "\\xintOdd{}", "snippet": "\\xintOdd{$1}", "meta": "xint-cmd", "score": 0.0002860314973334833}, {"caption": "\\xintGeq", "snippet": "\\xintGeq", "meta": "xint-cmd", "score": 0.0002860314973334833}], "inputenx": [{"caption": "\\inputencoding{}", "snippet": "\\inputencoding{$1}", "meta": "inputenx-cmd", "score": 0.0002447047447770061}], "vwcol": [{"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "vwcol-cmd", "score": 0.04598628699063736}, {"caption": "\\csname", "snippet": "\\csname", "meta": "vwcol-cmd", "score": 0.008565354665444157}, {"caption": "\\justifying", "snippet": "\\justifying", "meta": "vwcol-cmd", "score": 0.010373702256548788}, {"caption": "\\justifying{}", "snippet": "\\justifying{$1}", "meta": "vwcol-cmd", "score": 0.010373702256548788}, {"caption": "\\RaggedRight", "snippet": "\\RaggedRight", "meta": "vwcol-cmd", "score": 0.001021021782267457}, {"caption": "\\Centering", "snippet": "\\Centering", "meta": "vwcol-cmd", "score": 0.00037395241488843035}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "vwcol-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "vwcol-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "vwcol-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "vwcol-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "vwcol-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "vwcol-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "vwcol-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "vwcol-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "vwcol-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "vwcol-cmd", "score": 0.028955796305270766}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "vwcol-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "vwcol-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "vwcol-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "vwcol-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "vwcol-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "vwcol-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "vwcol-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "vwcol-cmd", "score": 0.2864294797053033}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "vwcol-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "vwcol-cmd", "score": 0.021170869458413965}], "multimedia": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "multimedia-cmd", "score": 0.00037306820619479756}], "sgame": [{"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "sgame-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "sgame-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "sgame-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "sgame-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "sgame-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "sgame-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "sgame-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "sgame-cmd", "score": 0.2864294797053033}], "bussproofs": [{"caption": "\\makeatletter", "snippet": "\\makeatletter", "meta": "bussproofs-cmd", "score": 0.041979363643201636}, {"caption": "\\makeatother", "snippet": "\\makeatother", "meta": "bussproofs-cmd", "score": 0.03923442255397878}], "titlepic": [{"caption": "\\titlepic{}", "snippet": "\\titlepic{$1}", "meta": "titlepic-cmd", "score": 0.00020896323441399082}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "titlepic-cmd", "score": 0.7504160124360846}], "paracol": [{"caption": "\\switchcolumn", "snippet": "\\switchcolumn", "meta": "paracol-cmd", "score": 0.0008273060639466222}, {"caption": "\\csname", "snippet": "\\csname", "meta": "paracol-cmd", "score": 0.008565354665444157}], "polyglossia": [{"caption": "\\markboth{}{}", "snippet": "\\markboth{$1}{$2}", "meta": "polyglossia-cmd", "score": 0.038323601301945065}, {"caption": "\\markboth{}", "snippet": "\\markboth{$1}", "meta": "polyglossia-cmd", "score": 0.038323601301945065}, {"caption": "\\normalfont", "snippet": "\\normalfont", "meta": "polyglossia-cmd", "score": 0.06871177093091137}, {"caption": "\\normalfont{}", "snippet": "\\normalfont{$1}", "meta": "polyglossia-cmd", "score": 0.06871177093091137}, {"caption": "\\setdefaultlanguage{}", "snippet": "\\setdefaultlanguage{$1}", "meta": "polyglossia-cmd", "score": 0.00021116765384691477}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "polyglossia-cmd", "score": 0.00021116765384691477}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "polyglossia-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "polyglossia-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "polyglossia-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "polyglossia-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "polyglossia-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "polyglossia-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "polyglossia-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "polyglossia-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "polyglossia-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "polyglossia-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "polyglossia-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "polyglossia-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "polyglossia-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "polyglossia-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "polyglossia-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "polyglossia-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "polyglossia-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "polyglossia-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "polyglossia-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "polyglossia-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "polyglossia-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "polyglossia-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "polyglossia-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "polyglossia-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "polyglossia-cmd", "score": 0.2864294797053033}], "zref-user": [{"caption": "\\zlabel{}", "snippet": "\\zlabel{$1}", "meta": "zref-user-cmd", "score": 0.0005277905480209891}, {"caption": "\\zref", "snippet": "\\zref", "meta": "zref-user-cmd", "score": 0.002193637536912482}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "zref-user-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "zref-user-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-user-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "zref-user-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "zref-user-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-user-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-user-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-user-cmd", "score": 0.002958865219480927}], "zref-abspage": [{"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "zref-abspage-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "zref-abspage-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "zref-abspage-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "zref-abspage-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "zref-abspage-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "zref-abspage-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-abspage-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "zref-abspage-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "zref-abspage-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-abspage-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-abspage-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-abspage-cmd", "score": 0.002958865219480927}], "quotchap": [{"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "quotchap-cmd", "score": 0.422097569591803}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "quotchap-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "quotchap-cmd", "score": 0.2864294797053033}, {"caption": "\\qauthor{}", "snippet": "\\qauthor{$1}", "meta": "quotchap-cmd", "score": 0.002335082759143631}], "misccorr": [{"caption": "\\subsection{}", "snippet": "\\subsection{$1}", "meta": "misccorr-cmd", "score": 1.3890912739512353}, {"caption": "\\section{}", "snippet": "\\section{$1}", "meta": "misccorr-cmd", "score": 3.0952612541683835}, {"caption": "\\csname", "snippet": "\\csname", "meta": "misccorr-cmd", "score": 0.008565354665444157}, {"caption": "\\makelabel", "snippet": "\\makelabel", "meta": "misccorr-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel{}", "snippet": "\\makelabel{$1}", "meta": "misccorr-cmd", "score": 5.739925426740175e-05}, {"caption": "\\makelabel[]{}", "snippet": "\\makelabel[$1]{$2}", "meta": "misccorr-cmd", "score": 5.739925426740175e-05}, {"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "misccorr-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "misccorr-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "misccorr-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "misccorr-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "misccorr-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "misccorr-cmd", "score": 0.0006671850995492977}], "academicons": [{"caption": "\\aiResearchGateSquare", "snippet": "\\aiResearchGateSquare", "meta": "academicons-cmd", "score": 0.0005747853176838451}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "academicons-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "academicons-cmd", "score": 0.2864294797053033}], "tasks": [{"caption": "\\csname", "snippet": "\\csname", "meta": "tasks-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tasks-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tasks-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tasks-cmd", "score": 0.2864294797053033}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tasks-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tasks-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tasks-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "tasks-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "tasks-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "tasks-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "tasks-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "tasks-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "tasks-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "tasks-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "tasks-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "tasks-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "tasks-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "tasks-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "tasks-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "tasks-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tasks-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "tasks-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "tasks-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "tasks-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tasks-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tasks-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tasks-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tasks-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tasks-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tasks-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tasks-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tasks-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tasks-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tasks-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tasks-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tasks-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tasks-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tasks-cmd", "score": 0.2864294797053033}], "pstricks-add": [{"caption": "\\green", "snippet": "\\green", "meta": "pstricks-add-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pstricks-add-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pstricks-add-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pstricks-add-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pstricks-add-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pstricks-add-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pstricks-add-cmd", "score": 0.006520475264573554}], "extramarks": [{"caption": "\\leftmark", "snippet": "\\leftmark", "meta": "extramarks-cmd", "score": 0.01094124445235767}, {"caption": "\\extramarks{}{}", "snippet": "\\extramarks{$1}{$2}", "meta": "extramarks-cmd", "score": 0.0003269562507660904}, {"caption": "\\markboth{}{}", "snippet": "\\markboth{$1}{$2}", "meta": "extramarks-cmd", "score": 0.038323601301945065}, {"caption": "\\markboth{}", "snippet": "\\markboth{$1}", "meta": "extramarks-cmd", "score": 0.038323601301945065}, {"caption": "\\markright{}", "snippet": "\\markright{$1}", "meta": "extramarks-cmd", "score": 0.007138622674767024}, {"caption": "\\markright{}{}", "snippet": "\\markright{$1}{$2}", "meta": "extramarks-cmd", "score": 0.007138622674767024}, {"caption": "\\rightmark", "snippet": "\\rightmark", "meta": "extramarks-cmd", "score": 0.008472328846194114}], "calrsfs": [{"caption": "\\mathcal{}", "snippet": "\\mathcal{$1}", "meta": "calrsfs-cmd", "score": 0.35084018920966636}], "newlfont": [{"caption": "\\em", "snippet": "\\em", "meta": "newlfont-cmd", "score": 0.10357353994640862}], "mdwtab": [{"caption": "\\cline{}", "snippet": "\\cline{$1}", "meta": "mdwtab-cmd", "score": 0.07276573550543858}, {"caption": "\\hline", "snippet": "\\hline", "meta": "mdwtab-cmd", "score": 1.3209538327406387}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "mdwtab-cmd", "score": 0.5473606021405326}], "mdwmath": [{"caption": "\\bigg", "snippet": "\\bigg", "meta": "mdwmath-cmd", "score": 0.04318078602869565}], "wallpaper": [{"caption": "\\CenterWallPaper{}{}", "snippet": "\\CenterWallPaper{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.00042983945496357105}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "wallpaper-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "wallpaper-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "wallpaper-cmd", "score": 0.028955796305270766}, {"caption": "\\empty", "snippet": "\\empty", "meta": "wallpaper-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "wallpaper-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "wallpaper-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "wallpaper-cmd", "score": 0.008565354665444157}, {"caption": "\\AddToShipoutPictureFG{}", "snippet": "\\AddToShipoutPictureFG{$1}", "meta": "wallpaper-cmd", "score": 0.000325977535138643}, {"caption": "\\AddToShipoutPictureBG{}", "snippet": "\\AddToShipoutPictureBG{$1}", "meta": "wallpaper-cmd", "score": 0.0008957666085644653}, {"caption": "\\AtPageUpperLeft{}", "snippet": "\\AtPageUpperLeft{$1}", "meta": "wallpaper-cmd", "score": 0.0003608141410278152}, {"caption": "\\LenToUnit{}", "snippet": "\\LenToUnit{$1}", "meta": "wallpaper-cmd", "score": 0.0007216282820556304}, {"caption": "\\AddToShipoutPicture{}", "snippet": "\\AddToShipoutPicture{$1}", "meta": "wallpaper-cmd", "score": 0.0017658629469099734}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "wallpaper-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "wallpaper-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "wallpaper-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "wallpaper-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "wallpaper-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "wallpaper-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "wallpaper-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "wallpaper-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "wallpaper-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "wallpaper-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "wallpaper-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "wallpaper-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "wallpaper-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "wallpaper-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "wallpaper-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "wallpaper-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "wallpaper-cmd", "score": 0.008565354665444157}], "newunicodechar": [{"caption": "\\newunicodechar{}{}", "snippet": "\\newunicodechar{$1}{$2}", "meta": "newunicodechar-cmd", "score": 8.718084183564492e-05}], "thmtools": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thmtools-cmd", "score": 0.00037306820619479756}, {"caption": "\\listtheoremname", "snippet": "\\listtheoremname", "meta": "thmtools-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\thmtformatoptarg", "snippet": "\\thmtformatoptarg", "meta": "thmtools-cmd", "score": 6.353668036093916e-05}, {"caption": "\\listoftheorems[]", "snippet": "\\listoftheorems[$1]", "meta": "thmtools-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\declaretheoremstyle[]{}", "snippet": "\\declaretheoremstyle[$1]{$2}", "meta": "thmtools-cmd", "score": 0.0001168034231635369}, {"caption": "\\declaretheorem[]{}", "snippet": "\\declaretheorem[$1]{$2}", "meta": "thmtools-cmd", "score": 0.0004904790216915127}, {"caption": "\\theoremstyle{}", "snippet": "\\theoremstyle{$1}", "meta": "thmtools-cmd", "score": 0.02533412165007986}, {"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thmtools-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thmtools-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thmtools-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thmtools-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thmtools-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thmtools-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thmtools-cmd", "score": 0.0006133100544751855}, {"caption": "\\empty", "snippet": "\\empty", "meta": "thmtools-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "thmtools-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "thmtools-cmd", "score": 0.008565354665444157}], "nccmath": [{"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "nccmath-cmd", "score": 1.4341091141105058}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "nccmath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "nccmath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "nccmath-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "nccmath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "nccmath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "nccmath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "nccmath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "nccmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "nccmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "nccmath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "nccmath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "nccmath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "nccmath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "nccmath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "nccmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "nccmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "nccmath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "nccmath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "nccmath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "nccmath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "nccmath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "nccmath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "nccmath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "nccmath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "nccmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "nccmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "nccmath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "nccmath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "nccmath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "nccmath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "nccmath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "nccmath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "nccmath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "nccmath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "nccmath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "nccmath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "nccmath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "nccmath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "nccmath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "nccmath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "nccmath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "nccmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "nccmath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "nccmath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "nccmath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "nccmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "nccmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "nccmath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "nccmath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "nccmath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "nccmath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "nccmath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "nccmath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "nccmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "nccmath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "nccmath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "nccmath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "nccmath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "nccmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "nccmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "nccmath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "nccmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "nccmath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "nccmath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "nccmath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "nccmath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "nccmath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "nccmath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "nccmath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "nccmath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "nccmath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "nccmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "nccmath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "nccmath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "nccmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "nccmath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "nccmath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "nccmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "nccmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "nccmath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "nccmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "nccmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "nccmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "nccmath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "nccmath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "nccmath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "nccmath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "nccmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "nccmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "nccmath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "nccmath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "nccmath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "nccmath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "nccmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "nccmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "nccmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "nccmath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "nccmath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "nccmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "nccmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "nccmath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "nccmath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "nccmath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "nccmath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "nccmath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "nccmath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "nccmath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "nccmath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "nccmath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "nccmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "nccmath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "nccmath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "nccmath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "nccmath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "nccmath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "nccmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "nccmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "nccmath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "nccmath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "nccmath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "nccmath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "nccmath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "nccmath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "nccmath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "nccmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "nccmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "nccmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "nccmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "nccmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "nccmath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "nccmath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "nccmath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "nccmath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "nccmath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "nccmath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "nccmath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "nccmath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "nccmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "nccmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "nccmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "nccmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "nccmath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "nccmath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "nccmath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "nccmath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "nccmath-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "nccmath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "nccmath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "nccmath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nccmath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "nccmath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "nccmath-cmd", "score": 0.0063276692758974925}], "scrtime": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "scrtime-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "scrtime-cmd", "score": 0.1789117552185788}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "scrtime-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "scrtime-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "scrtime-cmd", "score": 0.000396664302361659}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scrtime-cmd", "score": 0.00037306820619479756}], "luainputenc": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "luainputenc-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "luainputenc-cmd", "score": 0.008565354665444157}], "curve2e": [{"caption": "\\polyline", "snippet": "\\polyline", "meta": "curve2e-cmd", "score": 0.00022468880600368487}, {"caption": "\\put", "snippet": "\\put", "meta": "curve2e-cmd", "score": 0.0406766030275089}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "curve2e-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "curve2e-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "curve2e-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "curve2e-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "curve2e-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "curve2e-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "curve2e-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "curve2e-cmd", "score": 0.2864294797053033}, {"caption": "\\Line", "snippet": "\\Line", "meta": "curve2e-cmd", "score": 0.0006078790177929149}, {"caption": "\\polygon", "snippet": "\\polygon", "meta": "curve2e-cmd", "score": 0.0008987552240147395}, {"caption": "\\line", "snippet": "\\line", "meta": "curve2e-cmd", "score": 0.014519741542622297}, {"caption": "\\polyline", "snippet": "\\polyline", "meta": "curve2e-cmd", "score": 0.00022468880600368487}, {"caption": "\\vector", "snippet": "\\vector", "meta": "curve2e-cmd", "score": 0.002970308722584179}], "couriers": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "couriers-cmd", "score": 0.00037306820619479756}], "caption3": [{"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "caption3-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "caption3-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "caption3-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "caption3-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "caption3-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "caption3-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "caption3-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "caption3-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "caption3-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "caption3-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "caption3-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "caption3-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "caption3-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "caption3-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "caption3-cmd", "score": 0.021473212893597875}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "caption3-cmd", "score": 0.00037306820619479756}], "gauss": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "gauss-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "gauss-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "gauss-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "gauss-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "gauss-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "gauss-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "gauss-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "gauss-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "gauss-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "gauss-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "gauss-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "gauss-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "gauss-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "gauss-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "gauss-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "gauss-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "gauss-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "gauss-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "gauss-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "gauss-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "gauss-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "gauss-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "gauss-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "gauss-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "gauss-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "gauss-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "gauss-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "gauss-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "gauss-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "gauss-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "gauss-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "gauss-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "gauss-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "gauss-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "gauss-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "gauss-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "gauss-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "gauss-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "gauss-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "gauss-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "gauss-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "gauss-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "gauss-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "gauss-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "gauss-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "gauss-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "gauss-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "gauss-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "gauss-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "gauss-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "gauss-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "gauss-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "gauss-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "gauss-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "gauss-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "gauss-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "gauss-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "gauss-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "gauss-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "gauss-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "gauss-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "gauss-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "gauss-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "gauss-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "gauss-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "gauss-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "gauss-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "gauss-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "gauss-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "gauss-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "gauss-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "gauss-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "gauss-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "gauss-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "gauss-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "gauss-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "gauss-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "gauss-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "gauss-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "gauss-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "gauss-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "gauss-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "gauss-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "gauss-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "gauss-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "gauss-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "gauss-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "gauss-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "gauss-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "gauss-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "gauss-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "gauss-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "gauss-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "gauss-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "gauss-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "gauss-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "gauss-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "gauss-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "gauss-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "gauss-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "gauss-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "gauss-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "gauss-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "gauss-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "gauss-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "gauss-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "gauss-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "gauss-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "gauss-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "gauss-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "gauss-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "gauss-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "gauss-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "gauss-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "gauss-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "gauss-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "gauss-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "gauss-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "gauss-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "gauss-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "gauss-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "gauss-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "gauss-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "gauss-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "gauss-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "gauss-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "gauss-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "gauss-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "gauss-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "gauss-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "gauss-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "gauss-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "gauss-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "gauss-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "gauss-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "gauss-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "gauss-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "gauss-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "gauss-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "gauss-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "gauss-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "gauss-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "gauss-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "gauss-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "gauss-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "gauss-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "gauss-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "gauss-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "gauss-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gauss-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "gauss-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "gauss-cmd", "score": 0.0063276692758974925}], "fancyref": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fancyref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fancyref-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "fancyref-cmd", "score": 0.008565354665444157}], "eufrak": [{"caption": "\\mathfrak{}", "snippet": "\\mathfrak{$1}", "meta": "eufrak-cmd", "score": 0.025213895825856578}, {"caption": "\\mathfrak", "snippet": "\\mathfrak", "meta": "eufrak-cmd", "score": 0.025213895825856578}], "fixme": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "fixme-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "fixme-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "fixme-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "fixme-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "fixme-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "fixme-cmd", "score": 0.0018957469739775527}, {"caption": "\\endverbatim", "snippet": "\\endverbatim", "meta": "fixme-cmd", "score": 0.0022216421267780076}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "fixme-cmd", "score": 0.0072203369120285256}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fixme-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fixme-cmd", "score": 0.021170869458413965}, {"caption": "\\par", "snippet": "\\par", "meta": "fixme-cmd", "score": 0.413853376001159}, {"caption": "\\verbatiminput{}", "snippet": "\\verbatiminput{$1}", "meta": "fixme-cmd", "score": 0.0024547099784948665}, {"caption": "\\verbatiminput", "snippet": "\\verbatiminput", "meta": "fixme-cmd", "score": 0.0024547099784948665}], "pgf-umlsd": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlsd-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-umlsd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-umlsd-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgf-umlsd-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgf-umlsd-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-umlsd-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlsd-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgf-umlsd-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgf-umlsd-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "pgf-umlsd-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "pgf-umlsd-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-umlsd-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-umlsd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-umlsd-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgf-umlsd-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-umlsd-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgf-umlsd-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlsd-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgf-umlsd-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgf-umlsd-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgf-umlsd-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgf-umlsd-cmd", "score": 0.2864294797053033}], "tgadventor": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgadventor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgadventor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgadventor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgadventor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgadventor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgadventor-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgadventor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgadventor-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgadventor-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgadventor-cmd", "score": 0.021170869458413965}], "fancyheadings": [{"caption": "\\lhead{}", "snippet": "\\lhead{$1}", "meta": "fancyheadings-cmd", "score": 0.05268978171228714}, {"caption": "\\chaptermark", "snippet": "\\chaptermark", "meta": "fancyheadings-cmd", "score": 0.005924520024686584}, {"caption": "\\chaptermark{}", "snippet": "\\chaptermark{$1}", "meta": "fancyheadings-cmd", "score": 0.005924520024686584}, {"caption": "\\fancypagestyle{}{}", "snippet": "\\fancypagestyle{$1}{$2}", "meta": "fancyheadings-cmd", "score": 0.009430919590937878}, {"caption": "\\footrule", "snippet": "\\footrule", "meta": "fancyheadings-cmd", "score": 0.0010032754348913366}, {"caption": "\\footrule{}", "snippet": "\\footrule{$1}", "meta": "fancyheadings-cmd", "score": 0.0010032754348913366}, {"caption": "\\fancyfoot[]{}", "snippet": "\\fancyfoot[$1]{$2}", "meta": "fancyheadings-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfoot{}", "snippet": "\\fancyfoot{$1}", "meta": "fancyheadings-cmd", "score": 0.024973618823189894}, {"caption": "\\fancyfootoffset[]{}", "snippet": "\\fancyfootoffset[$1]{$2}", "meta": "fancyheadings-cmd", "score": 0.0015373246231684555}, {"caption": "\\fancyfootoffset{}", "snippet": "\\fancyfootoffset{$1}", "meta": "fancyheadings-cmd", "score": 0.0015373246231684555}, {"caption": "\\footruleskip", "snippet": "\\footruleskip", "meta": "fancyheadings-cmd", "score": 0.000830117957327721}, {"caption": "\\fancyheadoffset[]{}", "snippet": "\\fancyheadoffset[$1]{$2}", "meta": "fancyheadings-cmd", "score": 0.0016786568695309166}, {"caption": "\\fancyheadoffset{}", "snippet": "\\fancyheadoffset{$1}", "meta": "fancyheadings-cmd", "score": 0.0016786568695309166}, {"caption": "\\iffloatpage{}{}", "snippet": "\\iffloatpage{$1}{$2}", "meta": "fancyheadings-cmd", "score": 6.606286310833368e-05}, {"caption": "\\cfoot{}", "snippet": "\\cfoot{$1}", "meta": "fancyheadings-cmd", "score": 0.013411641301057813}, {"caption": "\\subsectionmark", "snippet": "\\subsectionmark", "meta": "fancyheadings-cmd", "score": 3.1153423008593836e-05}, {"caption": "\\footrulewidth", "snippet": "\\footrulewidth", "meta": "fancyheadings-cmd", "score": 0.011424740897486949}, {"caption": "\\fancyhfoffset[]{}", "snippet": "\\fancyhfoffset[$1]{$2}", "meta": "fancyheadings-cmd", "score": 3.741978601121172e-05}, {"caption": "\\rhead{}", "snippet": "\\rhead{$1}", "meta": "fancyheadings-cmd", "score": 0.022782817416731292}, {"caption": "\\fancyplain{}{}", "snippet": "\\fancyplain{$1}{$2}", "meta": "fancyheadings-cmd", "score": 0.007402339896386138}, {"caption": "\\rfoot{}", "snippet": "\\rfoot{$1}", "meta": "fancyheadings-cmd", "score": 0.013393817825547868}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fancyheadings-cmd", "score": 0.00530510025314411}, {"caption": "\\plainheadrulewidth", "snippet": "\\plainheadrulewidth", "meta": "fancyheadings-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\baselinestretch", "snippet": "\\baselinestretch", "meta": "fancyheadings-cmd", "score": 0.03225350148161425}, {"caption": "\\lfoot{}", "snippet": "\\lfoot{$1}", "meta": "fancyheadings-cmd", "score": 0.00789399846642229}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "fancyheadings-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "fancyheadings-cmd", "score": 0.006776001543888959}, {"caption": "\\fancyhf{}", "snippet": "\\fancyhf{$1}", "meta": "fancyheadings-cmd", "score": 0.02314618933449356}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "fancyheadings-cmd", "score": 0.005008938879210868}, {"caption": "\\fancyhead[]{}", "snippet": "\\fancyhead[$1]{$2}", "meta": "fancyheadings-cmd", "score": 0.039101068064744296}, {"caption": "\\fancyhead{}", "snippet": "\\fancyhead{$1}", "meta": "fancyheadings-cmd", "score": 0.039101068064744296}, {"caption": "\\nouppercase{}", "snippet": "\\nouppercase{$1}", "meta": "fancyheadings-cmd", "score": 0.006416387071584083}, {"caption": "\\nouppercase", "snippet": "\\nouppercase", "meta": "fancyheadings-cmd", "score": 0.006416387071584083}, {"caption": "\\headrule", "snippet": "\\headrule", "meta": "fancyheadings-cmd", "score": 0.0008327432627715623}, {"caption": "\\headrule{}", "snippet": "\\headrule{$1}", "meta": "fancyheadings-cmd", "score": 0.0008327432627715623}, {"caption": "\\chead{}", "snippet": "\\chead{$1}", "meta": "fancyheadings-cmd", "score": 0.00755042164734884}, {"caption": "\\headrulewidth", "snippet": "\\headrulewidth", "meta": "fancyheadings-cmd", "score": 0.02268137935335823}], "tikz-3dplot": [{"caption": "\\tdplotsetmaincoords{}{}", "snippet": "\\tdplotsetmaincoords{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.00021728148272883815}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-3dplot-cmd", "score": 0.008565354665444157}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tikz-3dplot-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tikz-3dplot-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-3dplot-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-3dplot-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-3dplot-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-3dplot-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-3dplot-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-3dplot-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-3dplot-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-3dplot-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-3dplot-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-3dplot-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-3dplot-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-3dplot-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-3dplot-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-3dplot-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-3dplot-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-3dplot-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-3dplot-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-3dplot-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-3dplot-cmd", "score": 0.2864294797053033}], "ltxtable": [{"caption": "\\let", "snippet": "\\let", "meta": "ltxtable-cmd", "score": 0.03789745970461662}, {"caption": "\\write", "snippet": "\\write", "meta": "ltxtable-cmd", "score": 0.0008038857295393196}, {"caption": "\\tabularxcolumn[]{}", "snippet": "\\tabularxcolumn[$1]{$2}", "meta": "ltxtable-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularxcolumn", "snippet": "\\tabularxcolumn", "meta": "ltxtable-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularx{}{}", "snippet": "\\tabularx{$1}{$2}", "meta": "ltxtable-cmd", "score": 0.0005861357565780464}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ltxtable-cmd", "score": 0.014532521139459619}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "ltxtable-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "ltxtable-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "ltxtable-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ltxtable-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "ltxtable-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ltxtable-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "ltxtable-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "ltxtable-cmd", "score": 0.018615449342361392}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "ltxtable-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "ltxtable-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ltxtable-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ltxtable-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "ltxtable-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "ltxtable-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "ltxtable-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "ltxtable-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "ltxtable-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "ltxtable-cmd", "score": 0.0313525090421608}], "pict2e": [{"caption": "\\Line", "snippet": "\\Line", "meta": "pict2e-cmd", "score": 0.0006078790177929149}, {"caption": "\\polygon", "snippet": "\\polygon", "meta": "pict2e-cmd", "score": 0.0008987552240147395}, {"caption": "\\line", "snippet": "\\line", "meta": "pict2e-cmd", "score": 0.014519741542622297}, {"caption": "\\polyline", "snippet": "\\polyline", "meta": "pict2e-cmd", "score": 0.00022468880600368487}, {"caption": "\\vector", "snippet": "\\vector", "meta": "pict2e-cmd", "score": 0.002970308722584179}], "ltablex": [{"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "ltablex-cmd", "score": 1.2569477427490174}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "ltablex-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "ltablex-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "ltablex-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ltablex-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "ltablex-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ltablex-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "ltablex-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "ltablex-cmd", "score": 0.018615449342361392}, {"caption": "\\let", "snippet": "\\let", "meta": "ltablex-cmd", "score": 0.03789745970461662}, {"caption": "\\write", "snippet": "\\write", "meta": "ltablex-cmd", "score": 0.0008038857295393196}, {"caption": "\\tabularxcolumn[]{}", "snippet": "\\tabularxcolumn[$1]{$2}", "meta": "ltablex-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularxcolumn", "snippet": "\\tabularxcolumn", "meta": "ltablex-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularx{}{}", "snippet": "\\tabularx{$1}{$2}", "meta": "ltablex-cmd", "score": 0.0005861357565780464}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ltablex-cmd", "score": 0.014532521139459619}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "ltablex-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "ltablex-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ltablex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ltablex-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "ltablex-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "ltablex-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "ltablex-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "ltablex-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "ltablex-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "ltablex-cmd", "score": 0.0313525090421608}], "amsopn": [{"caption": "\\sinh", "snippet": "\\sinh", "meta": "amsopn-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "amsopn-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "amsopn-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "amsopn-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "amsopn-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "amsopn-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "amsopn-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "amsopn-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "amsopn-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "amsopn-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "amsopn-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "amsopn-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "amsopn-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "amsopn-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "amsopn-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "amsopn-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "amsopn-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "amsopn-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "amsopn-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "amsopn-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "amsopn-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "amsopn-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "amsopn-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "amsopn-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "amsopn-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "amsopn-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "amsopn-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "amsopn-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "amsopn-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "amsopn-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "amsopn-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "amsopn-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "amsopn-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "amsopn-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "amsopn-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "amsopn-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "amsopn-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "amsopn-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "amsopn-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "amsopn-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "amsopn-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "amsopn-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "amsopn-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "amsopn-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "amsopn-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "amsopn-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "amsopn-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "amsopn-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "amsopn-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "amsopn-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "amsopn-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "amsopn-cmd", "score": 0.0004286136584068833}, {"caption": "\\do", "snippet": "\\do", "meta": "amsopn-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "amsopn-cmd", "score": 0.0063276692758974925}], "topcoman": [{"caption": "\\listing{}", "snippet": "\\listing{$1}", "meta": "topcoman-cmd", "score": 0.00023765162173466673}, {"caption": "\\micro", "snippet": "\\micro", "meta": "topcoman-cmd", "score": 0.011051971930487929}, {"caption": "\\gradi", "snippet": "\\gradi", "meta": "topcoman-cmd", "score": 0.00023765162173466673}, {"caption": "\\unit[]{}", "snippet": "\\unit[$1]{$2}", "meta": "topcoman-cmd", "score": 0.028299796173135428}, {"caption": "\\unit{}", "snippet": "\\unit{$1}", "meta": "topcoman-cmd", "score": 0.028299796173135428}, {"caption": "\\ped{}", "snippet": "\\ped{$1}", "meta": "topcoman-cmd", "score": 0.0007129548652040002}, {"caption": "\\ohm", "snippet": "\\ohm", "meta": "topcoman-cmd", "score": 0.0038146685721293138}, {"caption": "\\gei", "snippet": "\\gei", "meta": "topcoman-cmd", "score": 0.00023765162173466673}], "topfront": [{"caption": "\\corsodilaurea{}", "snippet": "\\corsodilaurea{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeQuartoTomo{}", "snippet": "\\NomeQuartoTomo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\ciclodidottorato{}", "snippet": "\\ciclodidottorato{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\CorsoDiLaureaIn{}", "snippet": "\\CorsoDiLaureaIn{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\ateneo{}", "snippet": "\\ateneo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\retrofrontespizio{}", "snippet": "\\retrofrontespizio{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\InName{}", "snippet": "\\InName{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\secondocandidato{}", "snippet": "\\secondocandidato{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeMonografia{}", "snippet": "\\NomeMonografia{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeTutoreAziendale{}", "snippet": "\\NomeTutoreAziendale{$1}", "meta": "topfront-cmd", "score": 0.00047530324346933345}, {"caption": "\\TutorName{}", "snippet": "\\TutorName{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeDissertazione{}", "snippet": "\\NomeDissertazione{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\sedutadilaurea{}", "snippet": "\\sedutadilaurea{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\logosede{}", "snippet": "\\logosede{$1}", "meta": "topfront-cmd", "score": 0.00047530324346933345}, {"caption": "\\TesiDiLaurea{}", "snippet": "\\TesiDiLaurea{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeTerzoTomo{}", "snippet": "\\NomeTerzoTomo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\AdvisorName{}", "snippet": "\\AdvisorName{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\facolta[]{}", "snippet": "\\facolta[$1]{$2}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\CycleName{}", "snippet": "\\CycleName{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomePrimoTomo{}", "snippet": "\\NomePrimoTomo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\candidato{}", "snippet": "\\candidato{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\NomeSecondoTomo{}", "snippet": "\\NomeSecondoTomo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\titolo{}", "snippet": "\\titolo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\CandidateName{}", "snippet": "\\CandidateName{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\secondorelatore{}", "snippet": "\\secondorelatore{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\FacoltaDi{}", "snippet": "\\FacoltaDi{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\nomeateneo{}", "snippet": "\\nomeateneo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\DottoratoIn{}", "snippet": "\\DottoratoIn{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\sottotitolo{}", "snippet": "\\sottotitolo{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\relatore{}", "snippet": "\\relatore{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}, {"caption": "\\tutoreaziendale{}", "snippet": "\\tutoreaziendale{$1}", "meta": "topfront-cmd", "score": 0.00023765162173466673}], "mathspec": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "mathspec-cmd", "score": 0.00021116765384691477}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "mathspec-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "mathspec-cmd", "score": 0.2864294797053033}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "mathspec-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "mathspec-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "mathspec-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "mathspec-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "mathspec-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "mathspec-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "mathspec-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "mathspec-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "mathspec-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "mathspec-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "mathspec-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "mathspec-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "mathspec-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "mathspec-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "mathspec-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "mathspec-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mathspec-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "mathspec-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "mathspec-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "mathspec-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "mathspec-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mathspec-cmd", "score": 0.008565354665444157}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "mathspec-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "mathspec-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "mathspec-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mathspec-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "mathspec-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "mathspec-cmd", "score": 0.0063276692758974925}], "overpic": [{"caption": "\\csname", "snippet": "\\csname", "meta": "overpic-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "overpic-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "overpic-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "overpic-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "overpic-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "overpic-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "overpic-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "overpic-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "overpic-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "overpic-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "overpic-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "overpic-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "overpic-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "overpic-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "overpic-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "overpic-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "overpic-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "overpic-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "overpic-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "overpic-cmd", "score": 0.004719094298848707}], "tkz-euclide": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-euclide-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "tkz-euclide-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "tkz-euclide-cmd", "score": 0.00031058155311734754}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tkz-euclide-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tkz-euclide-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tkz-euclide-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-euclide-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tkz-euclide-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-euclide-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tkz-euclide-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-euclide-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tkz-euclide-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tkz-euclide-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-euclide-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tkz-euclide-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-euclide-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tkz-euclide-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-euclide-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tkz-euclide-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tkz-euclide-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tkz-euclide-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tkz-euclide-cmd", "score": 0.2864294797053033}], "morewrites": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "morewrites-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "morewrites-cmd", "score": 0.2864294797053033}], "pgflibraryshapes": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgflibraryshapes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgflibraryshapes-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgflibraryshapes-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgflibraryshapes-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryshapes-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgflibraryshapes-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryshapes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgflibraryshapes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgflibraryshapes-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryshapes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgflibraryshapes-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgflibraryshapes-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgflibraryshapes-cmd", "score": 0.2864294797053033}], "pdfcolparallel": [{"caption": "\\empty", "snippet": "\\empty", "meta": "pdfcolparallel-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "pdfcolparallel-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "pdfcolparallel-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pdfcolparallel-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pdfcolparallel-cmd", "score": 0.00037306820619479756}, {"caption": "\\ParallelRText{}", "snippet": "\\ParallelRText{$1}", "meta": "pdfcolparallel-cmd", "score": 0.0005986518360651812}, {"caption": "\\ParallelLText{}", "snippet": "\\ParallelLText{$1}", "meta": "pdfcolparallel-cmd", "score": 0.0005986518360651812}, {"caption": "\\ParallelPar", "snippet": "\\ParallelPar", "meta": "pdfcolparallel-cmd", "score": 0.0005986518360651812}], "aeguill": [{"caption": "\\guillemotleft", "snippet": "\\guillemotleft", "meta": "aeguill-cmd", "score": 9.764370963946686e-05}, {"caption": "\\guillemotright", "snippet": "\\guillemotright", "meta": "aeguill-cmd", "score": 9.764370963946686e-05}, {"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "aeguill-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "aeguill-cmd", "score": 0.008427383388519996}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aeguill-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "aeguill-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "aeguill-cmd", "score": 0.021170869458413965}], "changes": [{"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "changes-cmd", "score": 0.04598628699063736}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "changes-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "changes-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "changes-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "changes-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "changes-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "changes-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "changes-cmd", "score": 0.028955796305270766}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "changes-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "changes-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "changes-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "changes-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "changes-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "changes-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "changes-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "changes-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "changes-cmd", "score": 0.0018957469739775527}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "changes-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "changes-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "changes-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "changes-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "changes-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "changes-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "changes-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "changes-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "changes-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "changes-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "changes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "changes-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "changes-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "changes-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "changes-cmd", "score": 0.2864294797053033}], "droidmono": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "droidmono-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "droidmono-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "droidmono-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "droidmono-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "droidmono-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "droidmono-cmd", "score": 0.0018957469739775527}, {"caption": "\\scshape", "snippet": "\\scshape", "meta": "droidmono-cmd", "score": 0.05364108855914402}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "droidmono-cmd", "score": 0.00037306820619479756}], "tgheros": [{"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "tgheros-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "tgheros-cmd", "score": 0.008427383388519996}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgheros-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgheros-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgheros-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgheros-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgheros-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgheros-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgheros-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgheros-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgheros-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgheros-cmd", "score": 0.021170869458413965}], "har2nat": [{"caption": "\\citeasnoun{}", "snippet": "\\citeasnoun{$1}", "meta": "har2nat-cmd", "score": 0.010452591644582749}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "har2nat-cmd", "score": 2.341195220791228}, {"caption": "\\citealt{}", "snippet": "\\citealt{$1}", "meta": "har2nat-cmd", "score": 0.007302105441724955}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "har2nat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "har2nat-cmd", "score": 0.021170869458413965}, {"caption": "\\textsuperscript{}", "snippet": "\\textsuperscript{$1}", "meta": "har2nat-cmd", "score": 0.05216393882408519}, {"caption": "\\nocite{}", "snippet": "\\nocite{$1}", "meta": "har2nat-cmd", "score": 0.04990693820960752}, {"caption": "\\bibname", "snippet": "\\bibname", "meta": "har2nat-cmd", "score": 0.007599529252128519}, {"caption": "\\bibname{}", "snippet": "\\bibname{$1}", "meta": "har2nat-cmd", "score": 0.007599529252128519}, {"caption": "\\bibpunct", "snippet": "\\bibpunct", "meta": "har2nat-cmd", "score": 0.001148574749873469}, {"caption": "\\bibpunct{}{}{}{}{}{}", "snippet": "\\bibpunct{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "har2nat-cmd", "score": 0.001148574749873469}, {"caption": "\\bibpunct[]{}{}{}{}{}{}", "snippet": "\\bibpunct[$1]{$2}{$3}{$4}{$5}{$6}{$7}", "meta": "har2nat-cmd", "score": 0.001148574749873469}, {"caption": "\\citepalias{}", "snippet": "\\citepalias{$1}", "meta": "har2nat-cmd", "score": 0.00032712684909035603}, {"caption": "\\citepalias[][]{}", "snippet": "\\citepalias[$1][$2]{$3}", "meta": "har2nat-cmd", "score": 0.00032712684909035603}, {"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "har2nat-cmd", "score": 0.010304996748556729}, {"caption": "\\citep{}", "snippet": "\\citep{$1}", "meta": "har2nat-cmd", "score": 0.2941882834697057}, {"caption": "\\bibsection", "snippet": "\\bibsection", "meta": "har2nat-cmd", "score": 0.00038872734530908233}, {"caption": "\\bibsection{}", "snippet": "\\bibsection{$1}", "meta": "har2nat-cmd", "score": 0.00038872734530908233}, {"caption": "\\refname", "snippet": "\\refname", "meta": "har2nat-cmd", "score": 0.006490238196722249}, {"caption": "\\refname{}", "snippet": "\\refname{$1}", "meta": "har2nat-cmd", "score": 0.006490238196722249}, {"caption": "\\citealp{}", "snippet": "\\citealp{$1}", "meta": "har2nat-cmd", "score": 0.005275912376595364}, {"caption": "\\citealp[]{}", "snippet": "\\citealp[$1]{$2}", "meta": "har2nat-cmd", "score": 0.005275912376595364}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "har2nat-cmd", "score": 2.341195220791228}, {"caption": "\\citetalias{}", "snippet": "\\citetalias{$1}", "meta": "har2nat-cmd", "score": 0.001419571355756266}, {"caption": "\\bibitem{}", "snippet": "\\bibitem{$1}", "meta": "har2nat-cmd", "score": 0.3689547570562042}, {"caption": "\\bibitem[]{}", "snippet": "\\bibitem[$1]{$2}", "meta": "har2nat-cmd", "score": 0.3689547570562042}, {"caption": "\\citet{}", "snippet": "\\citet{$1}", "meta": "har2nat-cmd", "score": 0.09046048561361801}, {"caption": "\\defcitealias{}{}", "snippet": "\\defcitealias{$1}{$2}", "meta": "har2nat-cmd", "score": 0.00042021825647418025}, {"caption": "\\aftergroup", "snippet": "\\aftergroup", "meta": "har2nat-cmd", "score": 0.002020423627422133}, {"caption": "\\setcitestyle{}", "snippet": "\\setcitestyle{$1}", "meta": "har2nat-cmd", "score": 0.0015840652870152204}, {"caption": "\\citeyearpar{}", "snippet": "\\citeyearpar{$1}", "meta": "har2nat-cmd", "score": 0.001877888310324327}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "har2nat-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "har2nat-cmd", "score": 0.006776001543888959}, {"caption": "\\newblock", "snippet": "\\newblock", "meta": "har2nat-cmd", "score": 0.03684301726876973}, {"caption": "\\newblock{}", "snippet": "\\newblock{$1}", "meta": "har2nat-cmd", "score": 0.03684301726876973}, {"caption": "\\bibnumfmt", "snippet": "\\bibnumfmt", "meta": "har2nat-cmd", "score": 0.000353353600267394}, {"caption": "\\citeyear{}", "snippet": "\\citeyear{$1}", "meta": "har2nat-cmd", "score": 0.01091041305836494}, {"caption": "\\citeauthor{}", "snippet": "\\citeauthor{$1}", "meta": "har2nat-cmd", "score": 0.01359248786373484}, {"caption": "\\let", "snippet": "\\let", "meta": "har2nat-cmd", "score": 0.03789745970461662}], "matlab-prettifier": [{"caption": "\\mlttfamily", "snippet": "\\mlttfamily", "meta": "matlab-prettifier-cmd", "score": 0.000856282742498241}, {"caption": "\\vskip", "snippet": "\\vskip", "meta": "matlab-prettifier-cmd", "score": 0.05143052892347224}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "matlab-prettifier-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "matlab-prettifier-cmd", "score": 0.021170869458413965}, {"caption": "\\do", "snippet": "\\do", "meta": "matlab-prettifier-cmd", "score": 0.009278344180101056}, {"caption": "\\thelstlisting", "snippet": "\\thelstlisting", "meta": "matlab-prettifier-cmd", "score": 0.00012774128088872144}, {"caption": "\\lstinputlisting[]{}", "snippet": "\\lstinputlisting[$1]{$2}", "meta": "matlab-prettifier-cmd", "score": 0.011660477607086044}, {"caption": "\\lstinputlisting{}", "snippet": "\\lstinputlisting{$1}", "meta": "matlab-prettifier-cmd", "score": 0.011660477607086044}, {"caption": "\\space", "snippet": "\\space", "meta": "matlab-prettifier-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "matlab-prettifier-cmd", "score": 0.008565354665444157}, {"caption": "\\lstinline", "snippet": "\\lstinline", "meta": "matlab-prettifier-cmd", "score": 0.005972262850694285}, {"caption": "\\lstinline{}", "snippet": "\\lstinline{$1}", "meta": "matlab-prettifier-cmd", "score": 0.005972262850694285}, {"caption": "\\lstlistoflistings", "snippet": "\\lstlistoflistings", "meta": "matlab-prettifier-cmd", "score": 0.005279080363360602}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "matlab-prettifier-cmd", "score": 0.00037306820619479756}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "matlab-prettifier-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "matlab-prettifier-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "matlab-prettifier-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "matlab-prettifier-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "matlab-prettifier-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "matlab-prettifier-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "matlab-prettifier-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "matlab-prettifier-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "matlab-prettifier-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "matlab-prettifier-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "matlab-prettifier-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "matlab-prettifier-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "matlab-prettifier-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "matlab-prettifier-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "matlab-prettifier-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "matlab-prettifier-cmd", "score": 0.2864294797053033}], "datetime2": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "datetime2-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "datetime2-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "datetime2-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "datetime2-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "datetime2-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "datetime2-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "datetime2-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "datetime2-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "datetime2-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "datetime2-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "datetime2-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "datetime2-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "datetime2-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "datetime2-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "datetime2-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "datetime2-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "datetime2-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "datetime2-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "datetime2-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "datetime2-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "datetime2-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datetime2-cmd", "score": 0.008565354665444157}], "lapdf": [{"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "lapdf-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "lapdf-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "lapdf-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "lapdf-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "lapdf-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "lapdf-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "lapdf-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "lapdf-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "lapdf-cmd", "score": 0.028955796305270766}], "nccbbb": [{"caption": "\\bbbe", "snippet": "\\bbbe", "meta": "nccbbb-cmd", "score": 0.0013332214754983353}, {"caption": "\\bbbe[]", "snippet": "\\bbbe[$1]", "meta": "nccbbb-cmd", "score": 0.0013332214754983353}, {"caption": "\\bbbr", "snippet": "\\bbbr", "meta": "nccbbb-cmd", "score": 0.0015739010274051707}], "tgbonum": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgbonum-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgbonum-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgbonum-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgbonum-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgbonum-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgbonum-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgbonum-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgbonum-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgbonum-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgbonum-cmd", "score": 0.021170869458413965}], "thm-restate": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thm-restate-cmd", "score": 0.00037306820619479756}, {"caption": "\\listtheoremname", "snippet": "\\listtheoremname", "meta": "thm-restate-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\thmtformatoptarg", "snippet": "\\thmtformatoptarg", "meta": "thm-restate-cmd", "score": 6.353668036093916e-05}, {"caption": "\\listoftheorems[]", "snippet": "\\listoftheorems[$1]", "meta": "thm-restate-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\declaretheoremstyle[]{}", "snippet": "\\declaretheoremstyle[$1]{$2}", "meta": "thm-restate-cmd", "score": 0.0001168034231635369}, {"caption": "\\declaretheorem[]{}", "snippet": "\\declaretheorem[$1]{$2}", "meta": "thm-restate-cmd", "score": 0.0004904790216915127}, {"caption": "\\theoremstyle{}", "snippet": "\\theoremstyle{$1}", "meta": "thm-restate-cmd", "score": 0.02533412165007986}, {"caption": "\\empty", "snippet": "\\empty", "meta": "thm-restate-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "thm-restate-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "thm-restate-cmd", "score": 0.008565354665444157}, {"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thm-restate-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thm-restate-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thm-restate-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thm-restate-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thm-restate-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thm-restate-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thm-restate-cmd", "score": 0.0006133100544751855}], "biblatex-chicago": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "biblatex-chicago-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "biblatex-chicago-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "biblatex-chicago-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "biblatex-chicago-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "biblatex-chicago-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "biblatex-chicago-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "biblatex-chicago-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "biblatex-chicago-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "biblatex-chicago-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "biblatex-chicago-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "biblatex-chicago-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "biblatex-chicago-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "biblatex-chicago-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "biblatex-chicago-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "biblatex-chicago-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "biblatex-chicago-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "biblatex-chicago-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "biblatex-chicago-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "biblatex-chicago-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "biblatex-chicago-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "biblatex-chicago-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "biblatex-chicago-cmd", "score": 0.008565354665444157}], "pseudocode": [{"caption": "\\shadowbox{}", "snippet": "\\shadowbox{$1}", "meta": "pseudocode-cmd", "score": 0.00107667147399019}, {"caption": "\\doublebox", "snippet": "\\doublebox", "meta": "pseudocode-cmd", "score": 0.00015142240898356106}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "pseudocode-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\thisfancypage{}{}", "snippet": "\\thisfancypage{$1}{$2}", "meta": "pseudocode-cmd", "score": 0.00015142240898356106}, {"caption": "\\TheSbox", "snippet": "\\TheSbox", "meta": "pseudocode-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "pseudocode-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "pseudocode-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "pseudocode-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "pseudocode-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "pseudocode-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "pseudocode-cmd", "score": 0.0018957469739775527}], "imakeidx": [{"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "imakeidx-cmd", "score": 0.010304996748556729}, {"caption": "\\printindex", "snippet": "\\printindex", "meta": "imakeidx-cmd", "score": 0.004417016910870522}, {"caption": "\\index{}", "snippet": "\\index{$1}", "meta": "imakeidx-cmd", "score": 0.013774721817648336}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "imakeidx-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "imakeidx-cmd", "score": 0.008565354665444157}], "uri": [{"caption": "\\empty", "snippet": "\\empty", "meta": "uri-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "uri-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "uri-cmd", "score": 0.008565354665444157}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "uri-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "uri-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "uri-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "uri-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "uri-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "uri-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "uri-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "uri-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "uri-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "uri-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "uri-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\empty", "snippet": "\\empty", "meta": "uri-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "uri-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "uri-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "uri-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "uri-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "uri-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "uri-cmd", "score": 0.021170869458413965}], "tocvsec2": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tocvsec2-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tocvsec2-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "tocvsec2-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "tocvsec2-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tocvsec2-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "tocvsec2-cmd", "score": 0.0018957469739775527}], "graphbox": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "graphbox-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "graphbox-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "graphbox-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "graphbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "graphbox-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "graphbox-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "graphbox-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "graphbox-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "graphbox-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphbox-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "graphbox-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "graphbox-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "graphbox-cmd", "score": 0.004719094298848707}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "graphbox-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "graphbox-cmd", "score": 0.008565354665444157}], "limap": [{"caption": "\\MapContinuing{}", "snippet": "\\MapContinuing{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\MapTextFraction{}", "snippet": "\\MapTextFraction{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\MapBlockLabelFont{}", "snippet": "\\MapBlockLabelFont{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\Block{}", "snippet": "\\Block{$1}", "meta": "limap-cmd", "score": 0.011618215341095648}, {"caption": "\\MapRuleWidth{}", "snippet": "\\MapRuleWidth{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\MapTitleFraction{}", "snippet": "\\MapTitleFraction{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\MapContinued{}", "snippet": "\\MapContinued{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\WideBlock{}", "snippet": "\\WideBlock{$1}", "meta": "limap-cmd", "score": 0.002453536158989143}, {"caption": "\\MapParskip{}", "snippet": "\\MapParskip{$1}", "meta": "limap-cmd", "score": 7.216282820556303e-05}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "limap-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "limap-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "limap-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "limap-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "limap-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "limap-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "limap-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "limap-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "limap-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "limap-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "limap-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "limap-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "limap-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "limap-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "limap-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "limap-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "limap-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "limap-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "limap-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "limap-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "limap-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "limap-cmd", "score": 0.008565354665444157}, {"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "limap-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "limap-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "limap-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "limap-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "limap-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "limap-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "limap-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "limap-cmd", "score": 0.059857788139528495}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "limap-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "limap-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "limap-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "limap-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "limap-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "limap-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "limap-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "limap-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "limap-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "limap-cmd", "score": 0.0313525090421608}], "tikzscale": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikzscale-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikzscale-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikzscale-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikzscale-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikzscale-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikzscale-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzscale-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikzscale-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzscale-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikzscale-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikzscale-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikzscale-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzscale-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzscale-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "tikzscale-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "tikzscale-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "tikzscale-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "tikzscale-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "tikzscale-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "tikzscale-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "tikzscale-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "tikzscale-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "tikzscale-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "tikzscale-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "tikzscale-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "tikzscale-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "tikzscale-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "tikzscale-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "tikzscale-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikzscale-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "tikzscale-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "tikzscale-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "tikzscale-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "tikzscale-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikzscale-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikzscale-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikzscale-cmd", "score": 0.2864294797053033}], "savesym": [{"caption": "\\savesymbol{}", "snippet": "\\savesymbol{$1}", "meta": "savesym-cmd", "score": 6.662041157021826e-05}], "subscript": [{"caption": "\\textsubscript{}", "snippet": "\\textsubscript{$1}", "meta": "subscript-cmd", "score": 0.058405875394131175}], "letterspace": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "letterspace-cmd", "score": 0.00037306820619479756}], "mathastext": [{"caption": "\\Huge", "snippet": "\\Huge", "meta": "mathastext-cmd", "score": 0.04725806985998919}, {"caption": "\\sfdefault", "snippet": "\\sfdefault", "meta": "mathastext-cmd", "score": 0.008427383388519996}, {"caption": "\\sfdefault{}", "snippet": "\\sfdefault{$1}", "meta": "mathastext-cmd", "score": 0.008427383388519996}, {"caption": "\\implies", "snippet": "\\implies", "meta": "mathastext-cmd", "score": 0.021828316911576096}, {"caption": "\\mathrm{}", "snippet": "\\mathrm{$1}", "meta": "mathastext-cmd", "score": 0.19117752976172653}], "movie15": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "movie15-cmd", "score": 0.00037306820619479756}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "movie15-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "movie15-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "movie15-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "movie15-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "movie15-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "movie15-cmd", "score": 0.0018957469739775527}], "refstyle": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "refstyle-cmd", "score": 0.00037306820619479756}], "pst-3d": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-3d-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-3d-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-3d-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-3d-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-3d-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-3d-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-3d-cmd", "score": 0.006520475264573554}], "rotfloat": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.00037306820619479756}, {"caption": "\\listof{}{}", "snippet": "\\listof{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.0009837365348002915}, {"caption": "\\floatplacement{}{}", "snippet": "\\floatplacement{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.0005815474978918903}, {"caption": "\\restylefloat{}", "snippet": "\\restylefloat{$1}", "meta": "rotfloat-cmd", "score": 0.0008866338267686714}, {"caption": "\\floatstyle{}", "snippet": "\\floatstyle{$1}", "meta": "rotfloat-cmd", "score": 0.0015470917047414941}, {"caption": "\\floatname{}{}", "snippet": "\\floatname{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.0011934321931750752}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rotfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "rotfloat-cmd", "score": 1.2569477427490174}, {"caption": "\\newfloat{}{}{}", "snippet": "\\newfloat{$1}{$2}{$3}", "meta": "rotfloat-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat", "snippet": "\\newfloat", "meta": "rotfloat-cmd", "score": 0.0012745874472536625}, {"caption": "\\newfloat{}", "snippet": "\\newfloat{$1}", "meta": "rotfloat-cmd", "score": 0.0012745874472536625}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rotfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "rotfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "rotfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "rotfloat-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "rotfloat-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "rotfloat-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "rotfloat-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "rotfloat-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "rotfloat-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rotfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "rotfloat-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "rotfloat-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "rotfloat-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "rotfloat-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "rotfloat-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "rotfloat-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "rotfloat-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "rotfloat-cmd", "score": 0.004719094298848707}], "progressbar": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "progressbar-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "progressbar-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "progressbar-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "progressbar-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "progressbar-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "progressbar-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "progressbar-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "progressbar-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "progressbar-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "progressbar-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "progressbar-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "progressbar-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "progressbar-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "progressbar-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "progressbar-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "progressbar-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "progressbar-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "progressbar-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "progressbar-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "progressbar-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "progressbar-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "progressbar-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "progressbar-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "progressbar-cmd", "score": 0.2864294797053033}, {"caption": "\\empty", "snippet": "\\empty", "meta": "progressbar-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "progressbar-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "progressbar-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "progressbar-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "progressbar-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "progressbar-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "progressbar-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "progressbar-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "progressbar-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "progressbar-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "progressbar-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "progressbar-cmd", "score": 0.028955796305270766}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "progressbar-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "progressbar-cmd", "score": 0.008565354665444157}], "pagecolor": [{"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pagecolor-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pagecolor-cmd", "score": 0.0008147200475678891}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pagecolor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pagecolor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pagecolor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pagecolor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pagecolor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pagecolor-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pagecolor-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pagecolor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pagecolor-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pagecolor-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pagecolor-cmd", "score": 0.021170869458413965}], "gb4e": [{"caption": "\\ex", "snippet": "\\ex", "meta": "gb4e-cmd", "score": 0.00916111174873264}], "ESIEEcv": [{"caption": "\\let", "snippet": "\\let", "meta": "ESIEEcv-cmd", "score": 0.03789745970461662}, {"caption": "\\write", "snippet": "\\write", "meta": "ESIEEcv-cmd", "score": 0.0008038857295393196}, {"caption": "\\tabularxcolumn[]{}", "snippet": "\\tabularxcolumn[$1]{$2}", "meta": "ESIEEcv-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularxcolumn", "snippet": "\\tabularxcolumn", "meta": "ESIEEcv-cmd", "score": 0.00048507499766588637}, {"caption": "\\tabularx{}{}", "snippet": "\\tabularx{$1}{$2}", "meta": "ESIEEcv-cmd", "score": 0.0005861357565780464}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ESIEEcv-cmd", "score": 0.014532521139459619}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "ESIEEcv-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "ESIEEcv-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "ESIEEcv-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "ESIEEcv-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "ESIEEcv-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ESIEEcv-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "ESIEEcv-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "ESIEEcv-cmd", "score": 0.018615449342361392}], "ftnright": [{"caption": "\\footnotesize", "snippet": "\\footnotesize", "meta": "ftnright-cmd", "score": 0.2038592081252624}, {"caption": "\\footnotesize{}", "snippet": "\\footnotesize{$1}", "meta": "ftnright-cmd", "score": 0.2038592081252624}], "chemformula": [{"caption": "\\ch{}", "snippet": "\\ch{$1}", "meta": "chemformula-cmd", "score": 0.0013276105116845872}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "chemformula-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "chemformula-cmd", "score": 0.1789117552185788}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "chemformula-cmd", "score": 0.00037306820619479756}, {"caption": "\\nicefrac{}{}", "snippet": "\\nicefrac{$1}{$2}", "meta": "chemformula-cmd", "score": 0.0018011350423659288}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "chemformula-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "chemformula-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "chemformula-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "chemformula-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "chemformula-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "chemformula-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "chemformula-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "chemformula-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "chemformula-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "chemformula-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "chemformula-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "chemformula-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "chemformula-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "chemformula-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "chemformula-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "chemformula-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "chemformula-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "chemformula-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "chemformula-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "chemformula-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "chemformula-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "chemformula-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "chemformula-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "chemformula-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "chemformula-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "chemformula-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "chemformula-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "chemformula-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "chemformula-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "chemformula-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "chemformula-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "chemformula-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "chemformula-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "chemformula-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "chemformula-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "chemformula-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "chemformula-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "chemformula-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "chemformula-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "chemformula-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "chemformula-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "chemformula-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "chemformula-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "chemformula-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "chemformula-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "chemformula-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "chemformula-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "chemformula-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "chemformula-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "chemformula-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "chemformula-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "chemformula-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "chemformula-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "chemformula-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "chemformula-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemformula-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chemformula-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chemformula-cmd", "score": 0.2864294797053033}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemformula-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemformula-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chemformula-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chemformula-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chemformula-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chemformula-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chemformula-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemformula-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chemformula-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemformula-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chemformula-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chemformula-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "chemformula-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemformula-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemformula-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "chemformula-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "chemformula-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "chemformula-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "chemformula-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "chemformula-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemformula-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "chemformula-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "chemformula-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemformula-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "chemformula-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "chemformula-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chemformula-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chemformula-cmd", "score": 0.2864294797053033}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "chemformula-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "chemformula-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "chemformula-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "chemformula-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "chemformula-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "chemformula-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "chemformula-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "chemformula-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "chemformula-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "chemformula-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "chemformula-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "chemformula-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "chemformula-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "chemformula-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "chemformula-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "chemformula-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "chemformula-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "chemformula-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "chemformula-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "chemformula-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "chemformula-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "chemformula-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "chemformula-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "chemformula-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "chemformula-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "chemformula-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "chemformula-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "chemformula-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "chemformula-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "chemformula-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "chemformula-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "chemformula-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "chemformula-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "chemformula-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "chemformula-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "chemformula-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "chemformula-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "chemformula-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "chemformula-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "chemformula-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "chemformula-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "chemformula-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "chemformula-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "chemformula-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "chemformula-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "chemformula-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "chemformula-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "chemformula-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "chemformula-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "chemformula-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "chemformula-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "chemformula-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "chemformula-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "chemformula-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "chemformula-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "chemformula-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "chemformula-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "chemformula-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "chemformula-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "chemformula-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "chemformula-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "chemformula-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "chemformula-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "chemformula-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "chemformula-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "chemformula-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "chemformula-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "chemformula-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "chemformula-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "chemformula-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "chemformula-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "chemformula-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "chemformula-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "chemformula-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "chemformula-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "chemformula-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "chemformula-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "chemformula-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "chemformula-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "chemformula-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "chemformula-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "chemformula-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "chemformula-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "chemformula-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "chemformula-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "chemformula-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "chemformula-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "chemformula-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "chemformula-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "chemformula-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "chemformula-cmd", "score": 0.0058847868741168765}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "chemformula-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "chemformula-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "chemformula-cmd", "score": 0.18137737738638837}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "chemformula-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "chemformula-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "chemformula-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "chemformula-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "chemformula-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "chemformula-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chemformula-cmd", "score": 0.004719094298848707}, {"caption": "\\sfrac{}{}", "snippet": "\\sfrac{$1}{$2}", "meta": "chemformula-cmd", "score": 0.0030164694688453453}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemformula-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "chemformula-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "chemformula-cmd", "score": 0.0063276692758974925}], "pgfautomata": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfautomata-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfautomata-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfautomata-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfautomata-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfautomata-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfautomata-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfautomata-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfautomata-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfautomata-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfautomata-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfautomata-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfautomata-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfautomata-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfautomata-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfautomata-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfautomata-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfautomata-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfautomata-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfautomata-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfautomata-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfautomata-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfautomata-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfautomata-cmd", "score": 0.2864294797053033}], "pgfnodes": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfnodes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfnodes-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfnodes-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfnodes-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfnodes-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfnodes-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfnodes-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfnodes-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfnodes-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfnodes-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfnodes-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfnodes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfnodes-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfnodes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfnodes-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfnodes-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfnodes-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfnodes-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfnodes-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfnodes-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfnodes-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfnodes-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfnodes-cmd", "score": 0.2864294797053033}], "pgfarrows": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfarrows-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfarrows-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfarrows-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfarrows-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfarrows-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfarrows-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfarrows-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfarrows-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfarrows-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfarrows-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfarrows-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfarrows-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfarrows-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfarrows-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfarrows-cmd", "score": 0.2864294797053033}], "pst-text": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-text-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-text-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-text-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-text-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-text-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-text-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-text-cmd", "score": 0.006520475264573554}], "keystroke": [{"caption": "\\csname", "snippet": "\\csname", "meta": "keystroke-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "keystroke-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "keystroke-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "keystroke-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "keystroke-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "keystroke-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "keystroke-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "keystroke-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "keystroke-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "keystroke-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "keystroke-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "keystroke-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "keystroke-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "keystroke-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "keystroke-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "keystroke-cmd", "score": 0.004649150613625593}], "currvita": [{"caption": "\\cvheadingfont", "snippet": "\\cvheadingfont", "meta": "currvita-cmd", "score": 5.547871753177405e-05}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "currvita-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "currvita-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "currvita-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "currvita-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "currvita-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "currvita-cmd", "score": 0.0018957469739775527}], "subfigmat": [{"caption": "\\subfigure[]{}", "snippet": "\\subfigure[$1]{$2}", "meta": "subfigmat-cmd", "score": 0.037856842641104005}, {"caption": "\\subref{}", "snippet": "\\subref{$1}", "meta": "subfigmat-cmd", "score": 0.007192033516871399}, {"caption": "\\subfigure[]{}", "snippet": "\\subfigure[$1]{$2}", "meta": "subfigmat-cmd", "score": 0.037856842641104005}], "boxhandler": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "boxhandler-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "boxhandler-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "boxhandler-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "boxhandler-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "boxhandler-cmd", "score": 0.0018957469739775527}, {"caption": "\\pbox{}{}", "snippet": "\\pbox{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.0010883030320478486}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "boxhandler-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "boxhandler-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "boxhandler-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "boxhandler-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "boxhandler-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "boxhandler-cmd", "score": 0.028955796305270766}], "media9": [{"caption": "\\empty", "snippet": "\\empty", "meta": "media9-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "media9-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "media9-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "media9-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "media9-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "media9-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "media9-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "media9-cmd", "score": 0.2864294797053033}], "translator": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "translator-cmd", "score": 0.00037306820619479756}], "german": [{"caption": "\\today", "snippet": "\\today", "meta": "german-cmd", "score": 0.10733849317324783}], "mhsetup": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mhsetup-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mhsetup-cmd", "score": 0.021170869458413965}], "nomentbl": [{"caption": "\\nomenclature[]{}{}", "snippet": "\\nomenclature[$1]{$2}{$3}", "meta": "nomentbl-cmd", "score": 0.016053526743355948}, {"caption": "\\nomenclature{}{}", "snippet": "\\nomenclature{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.016053526743355948}, {"caption": "\\nomlabel", "snippet": "\\nomlabel", "meta": "nomentbl-cmd", "score": 6.353668036093916e-05}, {"caption": "\\printnomenclature", "snippet": "\\printnomenclature", "meta": "nomentbl-cmd", "score": 0.0014526113324237952}, {"caption": "\\printnomenclature[]", "snippet": "\\printnomenclature[$1]", "meta": "nomentbl-cmd", "score": 0.0014526113324237952}, {"caption": "\\makenomenclature", "snippet": "\\makenomenclature", "meta": "nomentbl-cmd", "score": 0.002310610204652063}, {"caption": "\\nomgroup", "snippet": "\\nomgroup", "meta": "nomentbl-cmd", "score": 0.0005549290951493257}, {"caption": "\\nomgroup[]{}", "snippet": "\\nomgroup[$1]{$2}", "meta": "nomentbl-cmd", "score": 0.0005549290951493257}, {"caption": "\\nomname", "snippet": "\\nomname", "meta": "nomentbl-cmd", "score": 0.0015092617929470952}, {"caption": "\\nompreamble", "snippet": "\\nompreamble", "meta": "nomentbl-cmd", "score": 2.4350510995473236e-05}, {"caption": "\\nomentryend", "snippet": "\\nomentryend", "meta": "nomentbl-cmd", "score": 0.000137692304514793}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "nomentbl-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "nomentbl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "nomentbl-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "nomentbl-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "nomentbl-cmd", "score": 0.028955796305270766}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "nomentbl-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "nomentbl-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "nomentbl-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "nomentbl-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "nomentbl-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "nomentbl-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "nomentbl-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.018615449342361392}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "nomentbl-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "nomentbl-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "nomentbl-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "nomentbl-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "nomentbl-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "nomentbl-cmd", "score": 0.0018957469739775527}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "nomentbl-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "nomentbl-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "nomentbl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "nomentbl-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "nomentbl-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "nomentbl-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "nomentbl-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "nomentbl-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "nomentbl-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "nomentbl-cmd", "score": 0.0313525090421608}], "miller": [{"caption": "\\hkl", "snippet": "\\hkl", "meta": "miller-cmd", "score": 0.0034259481311452946}, {"caption": "\\hkl{}", "snippet": "\\hkl{$1}", "meta": "miller-cmd", "score": 0.0034259481311452946}, {"caption": "\\hkl[]", "snippet": "\\hkl[$1]", "meta": "miller-cmd", "score": 0.0034259481311452946}], "lpform": [{"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "lpform-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "lpform-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "lpform-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "lpform-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "lpform-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "lpform-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "lpform-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "lpform-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "lpform-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "lpform-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "lpform-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "lpform-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "lpform-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "lpform-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "lpform-cmd", "score": 0.0018957469739775527}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "lpform-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "lpform-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "lpform-cmd", "score": 0.009331077109224957}], "xepersian": [{"caption": "\\settextfont[]{}", "snippet": "\\settextfont[$1]{$2}", "meta": "xepersian-cmd", "score": 0.00015447355412753335}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xepersian-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xepersian-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "xepersian-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "xepersian-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xepersian-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xepersian-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xepersian-cmd", "score": 0.2864294797053033}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "xepersian-cmd", "score": 0.3277033727934986}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "xepersian-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "xepersian-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xepersian-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xepersian-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xepersian-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xepersian-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "xepersian-cmd", "score": 0.002958865219480927}], "chapterbib": [{"caption": "\\bibliographystyle{}", "snippet": "\\bibliographystyle{$1}", "meta": "chapterbib-cmd", "score": 0.25122317941387773}, {"caption": "\\bibliography{}", "snippet": "\\bibliography{$1}", "meta": "chapterbib-cmd", "score": 0.2659628337907604}, {"caption": "\\include{}", "snippet": "\\include{$1}", "meta": "chapterbib-cmd", "score": 0.1547080054979312}], "scalerel": [{"caption": "\\scaleto{}{}", "snippet": "\\scaleto{$1}{$2}", "meta": "scalerel-cmd", "score": 0.00027615383978106523}, {"caption": "\\csname", "snippet": "\\csname", "meta": "scalerel-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "scalerel-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "scalerel-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "scalerel-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "scalerel-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "scalerel-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "scalerel-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "scalerel-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "scalerel-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "scalerel-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "scalerel-cmd", "score": 0.028955796305270766}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "scalerel-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "scalerel-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "scalerel-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "scalerel-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "scalerel-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "scalerel-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "scalerel-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "scalerel-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "scalerel-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "scalerel-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "scalerel-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "scalerel-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "scalerel-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "scalerel-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "scalerel-cmd", "score": 0.004649150613625593}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "scalerel-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "scalerel-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "scalerel-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "scalerel-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "scalerel-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "scalerel-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "scalerel-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "scalerel-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "scalerel-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "scalerel-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "scalerel-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "scalerel-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "scalerel-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "scalerel-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "scalerel-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "scalerel-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "scalerel-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "scalerel-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "scalerel-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "scalerel-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "scalerel-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "scalerel-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "scalerel-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "scalerel-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "scalerel-cmd", "score": 0.004719094298848707}], "extarrows": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "extarrows-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "extarrows-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "extarrows-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "extarrows-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "extarrows-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "extarrows-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "extarrows-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "extarrows-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "extarrows-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "extarrows-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "extarrows-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "extarrows-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "extarrows-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "extarrows-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "extarrows-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "extarrows-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "extarrows-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "extarrows-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "extarrows-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "extarrows-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "extarrows-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "extarrows-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "extarrows-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "extarrows-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "extarrows-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "extarrows-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "extarrows-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "extarrows-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "extarrows-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "extarrows-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "extarrows-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "extarrows-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "extarrows-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "extarrows-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "extarrows-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "extarrows-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "extarrows-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "extarrows-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "extarrows-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "extarrows-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "extarrows-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "extarrows-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "extarrows-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "extarrows-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "extarrows-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "extarrows-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "extarrows-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "extarrows-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "extarrows-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "extarrows-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "extarrows-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "extarrows-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "extarrows-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "extarrows-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "extarrows-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "extarrows-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "extarrows-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "extarrows-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "extarrows-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "extarrows-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "extarrows-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "extarrows-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "extarrows-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "extarrows-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "extarrows-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "extarrows-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "extarrows-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "extarrows-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "extarrows-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "extarrows-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "extarrows-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "extarrows-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "extarrows-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "extarrows-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "extarrows-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "extarrows-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "extarrows-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "extarrows-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "extarrows-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "extarrows-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "extarrows-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "extarrows-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "extarrows-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "extarrows-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "extarrows-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "extarrows-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "extarrows-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "extarrows-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "extarrows-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "extarrows-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "extarrows-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "extarrows-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "extarrows-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "extarrows-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "extarrows-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "extarrows-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "extarrows-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "extarrows-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "extarrows-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "extarrows-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "extarrows-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "extarrows-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "extarrows-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "extarrows-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "extarrows-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "extarrows-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "extarrows-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "extarrows-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "extarrows-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "extarrows-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "extarrows-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "extarrows-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "extarrows-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "extarrows-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "extarrows-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "extarrows-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "extarrows-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "extarrows-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "extarrows-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "extarrows-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "extarrows-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "extarrows-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "extarrows-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "extarrows-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "extarrows-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "extarrows-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "extarrows-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "extarrows-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "extarrows-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "extarrows-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "extarrows-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "extarrows-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "extarrows-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "extarrows-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "extarrows-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "extarrows-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "extarrows-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "extarrows-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "extarrows-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "extarrows-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "extarrows-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "extarrows-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "extarrows-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "extarrows-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "extarrows-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "extarrows-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "extarrows-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "extarrows-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "extarrows-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "extarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "extarrows-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "extarrows-cmd", "score": 0.0063276692758974925}], "listingsutf8": [{"caption": "\\vskip", "snippet": "\\vskip", "meta": "listingsutf8-cmd", "score": 0.05143052892347224}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "listingsutf8-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "listingsutf8-cmd", "score": 0.021170869458413965}, {"caption": "\\do", "snippet": "\\do", "meta": "listingsutf8-cmd", "score": 0.009278344180101056}, {"caption": "\\thelstlisting", "snippet": "\\thelstlisting", "meta": "listingsutf8-cmd", "score": 0.00012774128088872144}, {"caption": "\\lstinputlisting[]{}", "snippet": "\\lstinputlisting[$1]{$2}", "meta": "listingsutf8-cmd", "score": 0.011660477607086044}, {"caption": "\\lstinputlisting{}", "snippet": "\\lstinputlisting{$1}", "meta": "listingsutf8-cmd", "score": 0.011660477607086044}, {"caption": "\\space", "snippet": "\\space", "meta": "listingsutf8-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "listingsutf8-cmd", "score": 0.008565354665444157}, {"caption": "\\lstinline", "snippet": "\\lstinline", "meta": "listingsutf8-cmd", "score": 0.005972262850694285}, {"caption": "\\lstinline{}", "snippet": "\\lstinline{$1}", "meta": "listingsutf8-cmd", "score": 0.005972262850694285}, {"caption": "\\lstlistoflistings", "snippet": "\\lstlistoflistings", "meta": "listingsutf8-cmd", "score": 0.005279080363360602}, {"caption": "\\csname", "snippet": "\\csname", "meta": "listingsutf8-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "listingsutf8-cmd", "score": 0.002958865219480927}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "listingsutf8-cmd", "score": 0.00037306820619479756}], "forloop": [{"caption": "\\forloop{}{}{}{}", "snippet": "\\forloop{$1}{$2}{$3}{$4}", "meta": "forloop-cmd", "score": 0.00029867998381154486}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "forloop-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "forloop-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "forloop-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "forloop-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "forloop-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "forloop-cmd", "score": 0.0018957469739775527}], "xymtex": [{"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "xymtex-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "xymtex-cmd", "score": 0.022224283488673075}, {"caption": "\\mathcal{}", "snippet": "\\mathcal{$1}", "meta": "xymtex-cmd", "score": 0.35084018920966636}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "xymtex-cmd", "score": 0.002995924112493351}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "xymtex-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xymtex-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xymtex-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "xymtex-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "xymtex-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "xymtex-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "xymtex-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "xymtex-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xymtex-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "xymtex-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "xymtex-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xymtex-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "xymtex-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "xymtex-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xymtex-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xymtex-cmd", "score": 0.2864294797053033}], "eqlist": [{"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "eqlist-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "eqlist-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "eqlist-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "eqlist-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "eqlist-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "eqlist-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "eqlist-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "eqlist-cmd", "score": 0.018615449342361392}, {"caption": "\\csname", "snippet": "\\csname", "meta": "eqlist-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "eqlist-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "eqlist-cmd", "score": 0.021170869458413965}, {"caption": "\\eqparbox{}{}", "snippet": "\\eqparbox{$1}{$2}", "meta": "eqlist-cmd", "score": 2.9423534119530166e-05}, {"caption": "\\item", "snippet": "\\item", "meta": "eqlist-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "eqlist-cmd", "score": 3.800886892251021}], "tgschola": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgschola-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgschola-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgschola-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgschola-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgschola-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgschola-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgschola-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgschola-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgschola-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgschola-cmd", "score": 0.021170869458413965}], "mfirstuc": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "mfirstuc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "mfirstuc-cmd", "score": 0.021170869458413965}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "mfirstuc-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "mfirstuc-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "mfirstuc-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "mfirstuc-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "mfirstuc-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "mfirstuc-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "mfirstuc-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "mfirstuc-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "mfirstuc-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "mfirstuc-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "mfirstuc-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "mfirstuc-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "mfirstuc-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "mfirstuc-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "mfirstuc-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "mfirstuc-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "mfirstuc-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "mfirstuc-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "mfirstuc-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "mfirstuc-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "mfirstuc-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "mfirstuc-cmd", "score": 0.008565354665444157}], "gloss": [{"caption": "\\makegloss", "snippet": "\\makegloss", "meta": "gloss-cmd", "score": 0.0018653410309739879}], "ltxcmds": [{"caption": "\\csname", "snippet": "\\csname", "meta": "ltxcmds-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "ltxcmds-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "ltxcmds-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "ltxcmds-cmd", "score": 0.021170869458413965}], "outlines": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "outlines-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "outlines-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "outlines-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "outlines-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "outlines-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "outlines-cmd", "score": 0.0018957469739775527}], "typearea": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "typearea-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "typearea-cmd", "score": 0.1789117552185788}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "typearea-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "typearea-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "typearea-cmd", "score": 0.000396664302361659}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "typearea-cmd", "score": 0.00037306820619479756}], "currfile": [{"caption": "\\currfiledir", "snippet": "\\currfiledir", "meta": "currfile-cmd", "score": 0.0002459788020229296}, {"caption": "\\empty", "snippet": "\\empty", "meta": "currfile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "currfile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "currfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "currfile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "currfile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "currfile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "currfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "currfile-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "currfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "currfile-cmd", "score": 0.021170869458413965}], "toptesi": [{"caption": "\\tomo", "snippet": "\\tomo", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\mainmatter", "snippet": "\\mainmatter", "meta": "toptesi-cmd", "score": 0.025705092792367497}, {"caption": "\\ringraziamenti", "snippet": "\\ringraziamenti", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\sommario", "snippet": "\\sommario", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\NoteWhiteLine", "snippet": "\\NoteWhiteLine", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\paginavuota", "snippet": "\\paginavuota", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\nota{}", "snippet": "\\nota{$1}", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\indici", "snippet": "\\indici", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\csname", "snippet": "\\csname", "meta": "toptesi-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "toptesi-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "toptesi-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "toptesi-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "toptesi-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "toptesi-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "toptesi-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "toptesi-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "toptesi-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "toptesi-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "toptesi-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "toptesi-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "toptesi-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "toptesi-cmd", "score": 0.004649150613625593}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "toptesi-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "toptesi-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "toptesi-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "toptesi-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "toptesi-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "toptesi-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "toptesi-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "toptesi-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "toptesi-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "toptesi-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "toptesi-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "toptesi-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "toptesi-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "toptesi-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "toptesi-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "toptesi-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "toptesi-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "toptesi-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "toptesi-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "toptesi-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "toptesi-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "toptesi-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "toptesi-cmd", "score": 0.004719094298848707}, {"caption": "\\listing{}", "snippet": "\\listing{$1}", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\micro", "snippet": "\\micro", "meta": "toptesi-cmd", "score": 0.011051971930487929}, {"caption": "\\gradi", "snippet": "\\gradi", "meta": "toptesi-cmd", "score": 0.00023765162173466673}, {"caption": "\\unit[]{}", "snippet": "\\unit[$1]{$2}", "meta": "toptesi-cmd", "score": 0.028299796173135428}, {"caption": "\\unit{}", "snippet": "\\unit{$1}", "meta": "toptesi-cmd", "score": 0.028299796173135428}, {"caption": "\\ped{}", "snippet": "\\ped{$1}", "meta": "toptesi-cmd", "score": 0.0007129548652040002}, {"caption": "\\ohm", "snippet": "\\ohm", "meta": "toptesi-cmd", "score": 0.0038146685721293138}, {"caption": "\\gei", "snippet": "\\gei", "meta": "toptesi-cmd", "score": 0.00023765162173466673}], "amsrefs": [{"caption": "\\ndash", "snippet": "\\ndash", "meta": "amsrefs-cmd", "score": 0.0003420867634658178}, {"caption": "\\bib{}{}{}", "snippet": "\\bib{$1}{$2}{$3}", "meta": "amsrefs-cmd", "score": 0.0017473230242849183}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "amsrefs-cmd", "score": 2.341195220791228}], "sistyle": [{"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "sistyle-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "sistyle-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "sistyle-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "sistyle-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "sistyle-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "sistyle-cmd", "score": 0.0063276692758974925}], "suffix": [{"caption": "\\let", "snippet": "\\let", "meta": "suffix-cmd", "score": 0.03789745970461662}], "sansmath": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "sansmath-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "sansmath-cmd", "score": 0.021170869458413965}], "tikz-qtree": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-qtree-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-qtree-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-qtree-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-qtree-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-qtree-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-qtree-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-qtree-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-qtree-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-qtree-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-qtree-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-qtree-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-qtree-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-qtree-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-qtree-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-qtree-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-qtree-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-qtree-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-qtree-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-qtree-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-qtree-cmd", "score": 0.2864294797053033}], "floatpag": [{"caption": "\\rotfloatpagestyle{}", "snippet": "\\rotfloatpagestyle{$1}", "meta": "floatpag-cmd", "score": 0.0004535003423927585}, {"caption": "\\floatpagestyle{}", "snippet": "\\floatpagestyle{$1}", "meta": "floatpag-cmd", "score": 0.0004535003423927585}], "colortab": [{"caption": "\\shadowbox{}", "snippet": "\\shadowbox{$1}", "meta": "colortab-cmd", "score": 0.00107667147399019}, {"caption": "\\doublebox", "snippet": "\\doublebox", "meta": "colortab-cmd", "score": 0.00015142240898356106}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "colortab-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\thisfancypage{}{}", "snippet": "\\thisfancypage{$1}{$2}", "meta": "colortab-cmd", "score": 0.00015142240898356106}, {"caption": "\\TheSbox", "snippet": "\\TheSbox", "meta": "colortab-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\green", "snippet": "\\green", "meta": "colortab-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "colortab-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "colortab-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "colortab-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "colortab-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "colortab-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "colortab-cmd", "score": 0.006520475264573554}], "parcolumns": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "parcolumns-cmd", "score": 0.00037306820619479756}], "dingbat": [{"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "dingbat-cmd", "score": 0.025060530944368123}], "ifoddpage": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "ifoddpage-cmd", "score": 0.00530510025314411}, {"caption": "\\checkoddpage", "snippet": "\\checkoddpage", "meta": "ifoddpage-cmd", "score": 0.00028672585452906425}], "kvoptions": [{"caption": "\\empty", "snippet": "\\empty", "meta": "kvoptions-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "kvoptions-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "kvoptions-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "kvoptions-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "kvoptions-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "kvoptions-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "kvoptions-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "kvoptions-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "kvoptions-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "kvoptions-cmd", "score": 0.021170869458413965}], "pst-tree": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-tree-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-tree-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-tree-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-tree-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-tree-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-tree-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-tree-cmd", "score": 0.006520475264573554}], "nonfloat": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "nonfloat-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "nonfloat-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "nonfloat-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "nonfloat-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "nonfloat-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "nonfloat-cmd", "score": 0.0018957469739775527}], "rsphrase": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "rsphrase-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "rsphrase-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "rsphrase-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "rsphrase-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "rsphrase-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "rsphrase-cmd", "score": 0.0018957469739775527}], "beramono": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "beramono-cmd", "score": 0.00037306820619479756}], "pgfbaseimage": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfbaseimage-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfbaseimage-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfbaseimage-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfbaseimage-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfbaseimage-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfbaseimage-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfbaseimage-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfbaseimage-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfbaseimage-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfbaseimage-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfbaseimage-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfbaseimage-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfbaseimage-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfbaseimage-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfbaseimage-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfbaseimage-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfbaseimage-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfbaseimage-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfbaseimage-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfbaseimage-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfbaseimage-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfbaseimage-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfbaseimage-cmd", "score": 0.2864294797053033}], "romannum": [{"caption": "\\thefootnote", "snippet": "\\thefootnote", "meta": "romannum-cmd", "score": 0.007676927812687567}, {"caption": "\\thefootnote{}", "snippet": "\\thefootnote{$1}", "meta": "romannum-cmd", "score": 0.007676927812687567}], "tgtermes": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgtermes-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgtermes-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgtermes-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgtermes-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgtermes-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgtermes-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgtermes-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgtermes-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgtermes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgtermes-cmd", "score": 0.021170869458413965}], "Alegreya": [{"caption": "\\rmfamily", "snippet": "\\rmfamily", "meta": "Alegreya-cmd", "score": 0.00898937903263608}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "Alegreya-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "Alegreya-cmd", "score": 0.008565354665444157}], "glossaries-extra": [{"caption": "\\gls{}", "snippet": "\\gls{$1}", "meta": "glossaries-extra-cmd", "score": 0.06939353309055077}, {"caption": "\\Gls{}", "snippet": "\\Gls{$1}", "meta": "glossaries-extra-cmd", "score": 0.003696678698317109}, {"caption": "\\makeglossaries", "snippet": "\\makeglossaries", "meta": "glossaries-extra-cmd", "score": 0.0056737600836936995}, {"caption": "\\newabbreviation{}{}{}", "snippet": "\\newabbreviation{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 0.00023275591440052114}, {"caption": "\\newglossaryentry{}{}", "snippet": "\\newglossaryentry{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.018524394136900962}, {"caption": "\\newglossary{}{}", "snippet": "\\newglossary{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 1.4547244650032571e-05}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\glslongpluralkey", "snippet": "\\glslongpluralkey", "meta": "glossaries-extra-cmd", "score": 1.4538687447297259e-05}, {"caption": "\\Glspl{}", "snippet": "\\Glspl{$1}", "meta": "glossaries-extra-cmd", "score": 0.0025291265119320736}, {"caption": "\\glossarysection", "snippet": "\\glossarysection", "meta": "glossaries-extra-cmd", "score": 9.579755294730752e-05}, {"caption": "\\printglossaries", "snippet": "\\printglossaries", "meta": "glossaries-extra-cmd", "score": 0.0010106582768889887}, {"caption": "\\Gls{}", "snippet": "\\Gls{$1}", "meta": "glossaries-extra-cmd", "score": 0.003696678698317109}, {"caption": "\\setglossarystyle{}", "snippet": "\\setglossarystyle{$1}", "meta": "glossaries-extra-cmd", "score": 0.0003758893277679221}, {"caption": "\\printglossary", "snippet": "\\printglossary", "meta": "glossaries-extra-cmd", "score": 0.009139682306158714}, {"caption": "\\printglossary[]", "snippet": "\\printglossary[$1]", "meta": "glossaries-extra-cmd", "score": 0.009139682306158714}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-extra-cmd", "score": 0.009278344180101056}, {"caption": "\\setglossarysection{}", "snippet": "\\setglossarysection{$1}", "meta": "glossaries-extra-cmd", "score": 3.6081414102781514e-05}, {"caption": "\\glsresetall", "snippet": "\\glsresetall", "meta": "glossaries-extra-cmd", "score": 0.0006123462672467326}, {"caption": "\\the", "snippet": "\\the", "meta": "glossaries-extra-cmd", "score": 0.007238960303946444}, {"caption": "\\acrshort{}", "snippet": "\\acrshort{$1}", "meta": "glossaries-extra-cmd", "score": 0.009936841864059727}, {"caption": "\\printnoidxglossary[]", "snippet": "\\printnoidxglossary[$1]", "meta": "glossaries-extra-cmd", "score": 0.00021912375285685037}, {"caption": "\\newglossary{}{}", "snippet": "\\newglossary{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 1.4547244650032571e-05}, {"caption": "\\gls{}", "snippet": "\\gls{$1}", "meta": "glossaries-extra-cmd", "score": 0.06939353309055077}, {"caption": "\\printnoidxglossaries", "snippet": "\\printnoidxglossaries", "meta": "glossaries-extra-cmd", "score": 5.6789564226023136e-05}, {"caption": "\\printindex", "snippet": "\\printindex", "meta": "glossaries-extra-cmd", "score": 0.004417016910870522}, {"caption": "\\defglsentryfmt[]{}", "snippet": "\\defglsentryfmt[$1]{$2}", "meta": "glossaries-extra-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\glspostdescription", "snippet": "\\glspostdescription", "meta": "glossaries-extra-cmd", "score": 0.0006337376579591112}, {"caption": "\\number", "snippet": "\\number", "meta": "glossaries-extra-cmd", "score": 0.000968714260809983}, {"caption": "\\glsaddall", "snippet": "\\glsaddall", "meta": "glossaries-extra-cmd", "score": 0.0008363820557740373}, {"caption": "\\glsaddall[]", "snippet": "\\glsaddall[$1]", "meta": "glossaries-extra-cmd", "score": 0.0008363820557740373}, {"caption": "\\makeglossaries", "snippet": "\\makeglossaries", "meta": "glossaries-extra-cmd", "score": 0.0056737600836936995}, {"caption": "\\glossaryname", "snippet": "\\glossaryname", "meta": "glossaries-extra-cmd", "score": 0.0006174536302752427}, {"caption": "\\newglossaryentry{}{}", "snippet": "\\newglossaryentry{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.018524394136900962}, {"caption": "\\glslabel", "snippet": "\\glslabel", "meta": "glossaries-extra-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\glsadd{}", "snippet": "\\glsadd{$1}", "meta": "glossaries-extra-cmd", "score": 3.0150373480213892e-05}, {"caption": "\\makenoidxglossaries", "snippet": "\\makenoidxglossaries", "meta": "glossaries-extra-cmd", "score": 0.0001382210125680805}, {"caption": "\\glsgenentryfmt", "snippet": "\\glsgenentryfmt", "meta": "glossaries-extra-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\acronymtype", "snippet": "\\acronymtype", "meta": "glossaries-extra-cmd", "score": 0.002000834271117562}, {"caption": "\\acrfull{}", "snippet": "\\acrfull{$1}", "meta": "glossaries-extra-cmd", "score": 0.0032622587277765067}, {"caption": "\\newacronym{}{}{}", "snippet": "\\newacronym{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 0.03193935544723102}, {"caption": "\\glspl{}", "snippet": "\\glspl{$1}", "meta": "glossaries-extra-cmd", "score": 0.0034025897522047717}, {"caption": "\\ifglsused{}{}{}", "snippet": "\\ifglsused{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 4.8990621725283124e-05}, {"caption": "\\acrlong{}", "snippet": "\\acrlong{$1}", "meta": "glossaries-extra-cmd", "score": 0.002517821598213752}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "glossaries-extra-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-extra-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "glossaries-extra-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "glossaries-extra-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "glossaries-extra-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "glossaries-extra-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "glossaries-extra-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "glossaries-extra-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "glossaries-extra-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "glossaries-extra-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "glossaries-extra-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "glossaries-extra-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "glossaries-extra-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "glossaries-extra-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "glossaries-extra-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "glossaries-extra-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "glossaries-extra-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "glossaries-extra-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "glossaries-extra-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "glossaries-extra-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "glossaries-extra-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "glossaries-extra-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "glossaries-extra-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "glossaries-extra-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "glossaries-extra-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "glossaries-extra-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "glossaries-extra-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "glossaries-extra-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "glossaries-extra-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "glossaries-extra-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "glossaries-extra-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "glossaries-extra-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "glossaries-extra-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "glossaries-extra-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "glossaries-extra-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "glossaries-extra-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "glossaries-extra-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "glossaries-extra-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "glossaries-extra-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "glossaries-extra-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "glossaries-extra-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "glossaries-extra-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "glossaries-extra-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "glossaries-extra-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "glossaries-extra-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "glossaries-extra-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "glossaries-extra-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "glossaries-extra-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "glossaries-extra-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "glossaries-extra-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "glossaries-extra-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "glossaries-extra-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "glossaries-extra-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "glossaries-extra-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "glossaries-extra-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "glossaries-extra-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "glossaries-extra-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "glossaries-extra-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "glossaries-extra-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "glossaries-extra-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "glossaries-extra-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "glossaries-extra-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "glossaries-extra-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "glossaries-extra-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "glossaries-extra-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "glossaries-extra-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "glossaries-extra-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "glossaries-extra-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "glossaries-extra-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "glossaries-extra-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "glossaries-extra-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "glossaries-extra-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "glossaries-extra-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "glossaries-extra-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "glossaries-extra-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "glossaries-extra-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "glossaries-extra-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "glossaries-extra-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "glossaries-extra-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "glossaries-extra-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "glossaries-extra-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "glossaries-extra-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "glossaries-extra-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "glossaries-extra-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "glossaries-extra-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "glossaries-extra-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "glossaries-extra-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "glossaries-extra-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "glossaries-extra-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "glossaries-extra-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "glossaries-extra-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "glossaries-extra-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "glossaries-extra-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "glossaries-extra-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "glossaries-extra-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "glossaries-extra-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "glossaries-extra-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "glossaries-extra-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "glossaries-extra-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "glossaries-extra-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "glossaries-extra-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "glossaries-extra-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "glossaries-extra-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "glossaries-extra-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "glossaries-extra-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "glossaries-extra-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "glossaries-extra-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "glossaries-extra-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "glossaries-extra-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "glossaries-extra-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "glossaries-extra-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "glossaries-extra-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "glossaries-extra-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "glossaries-extra-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "glossaries-extra-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "glossaries-extra-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "glossaries-extra-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "glossaries-extra-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "glossaries-extra-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "glossaries-extra-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "glossaries-extra-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "glossaries-extra-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "glossaries-extra-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "glossaries-extra-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "glossaries-extra-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "glossaries-extra-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "glossaries-extra-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "glossaries-extra-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "glossaries-extra-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "glossaries-extra-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "glossaries-extra-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "glossaries-extra-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "glossaries-extra-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "glossaries-extra-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "glossaries-extra-cmd", "score": 0.008565354665444157}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "glossaries-extra-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "glossaries-extra-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "glossaries-extra-cmd", "score": 0.18137737738638837}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "glossaries-extra-cmd", "score": 2.341195220791228}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossaries-extra-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "glossaries-extra-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "glossaries-extra-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "glossaries-extra-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "glossaries-extra-cmd", "score": 0.0018957469739775527}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "glossaries-extra-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "glossaries-extra-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "glossaries-extra-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "glossaries-extra-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-extra-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "glossaries-extra-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "glossaries-extra-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "glossaries-extra-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "glossaries-extra-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "glossaries-extra-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "glossaries-extra-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "glossaries-extra-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "glossaries-extra-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "glossaries-extra-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "glossaries-extra-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "glossaries-extra-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "glossaries-extra-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "glossaries-extra-cmd", "score": 0.0063276692758974925}], "dashrule": [{"caption": "\\hdashrule[]{}{}{}", "snippet": "\\hdashrule[$1]{$2}{$3}{$4}", "meta": "dashrule-cmd", "score": 0.00029867998381154486}], "bclogo": [{"caption": "\\csname", "snippet": "\\csname", "meta": "bclogo-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "bclogo-cmd", "score": 0.00037306820619479756}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "bclogo-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "bclogo-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "bclogo-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "bclogo-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "bclogo-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "bclogo-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "bclogo-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "bclogo-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "bclogo-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "bclogo-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "bclogo-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "bclogo-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "bclogo-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bclogo-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "bclogo-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "bclogo-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "bclogo-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bclogo-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bclogo-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bclogo-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "bclogo-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "bclogo-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "bclogo-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "bclogo-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bclogo-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "bclogo-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bclogo-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "bclogo-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "bclogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "bclogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "bclogo-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "bclogo-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "bclogo-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "bclogo-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "bclogo-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "bclogo-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "bclogo-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "bclogo-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "bclogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "bclogo-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "bclogo-cmd", "score": 0.004719094298848707}], "isomath": [{"caption": "\\empty", "snippet": "\\empty", "meta": "isomath-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "isomath-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "isomath-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "isomath-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "isomath-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "isomath-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "isomath-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "isomath-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "isomath-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "isomath-cmd", "score": 0.021170869458413965}], "tkz-graph": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-graph-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-graph-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tkz-graph-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tkz-graph-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tkz-graph-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-graph-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tkz-graph-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-graph-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tkz-graph-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tkz-graph-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tkz-graph-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "tkz-graph-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tkz-graph-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "tkz-graph-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-graph-cmd", "score": 0.004719094298848707}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "tkz-graph-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "tkz-graph-cmd", "score": 0.00031058155311734754}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-graph-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tkz-graph-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-graph-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-graph-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tkz-graph-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-graph-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tkz-graph-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-graph-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tkz-graph-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tkz-graph-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tkz-graph-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tkz-graph-cmd", "score": 0.2864294797053033}], "sourcesanspro": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "sourcesanspro-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "sourcesanspro-cmd", "score": 0.008565354665444157}], "longdivision": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "longdivision-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "longdivision-cmd", "score": 0.2864294797053033}], "xmpmulti": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "xmpmulti-cmd", "score": 0.00037306820619479756}], "epsdice": [{"caption": "\\csname", "snippet": "\\csname", "meta": "epsdice-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "epsdice-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "epsdice-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "epsdice-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "epsdice-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "epsdice-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "epsdice-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "epsdice-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "epsdice-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "epsdice-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "epsdice-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "epsdice-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "epsdice-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "epsdice-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "epsdice-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "epsdice-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "epsdice-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "epsdice-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "epsdice-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "epsdice-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "epsdice-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "epsdice-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "epsdice-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "epsdice-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "epsdice-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "epsdice-cmd", "score": 0.004719094298848707}], "apptools": [{"caption": "\\appendix", "snippet": "\\appendix", "meta": "apptools-cmd", "score": 0.047007158741781095}, {"caption": "\\AtAppendix{}", "snippet": "\\AtAppendix{$1}", "meta": "apptools-cmd", "score": 8.82390883984482e-06}], "letltxmacro": [{"caption": "\\csname", "snippet": "\\csname", "meta": "letltxmacro-cmd", "score": 0.008565354665444157}], "menukeys": [{"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "menukeys-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "menukeys-cmd", "score": 0.354445763583904}, {"caption": "\\adjustbox{}{}", "snippet": "\\adjustbox{$1}{$2}", "meta": "menukeys-cmd", "score": 0.002008185536556013}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "menukeys-cmd", "score": 0.00037306820619479756}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "menukeys-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "menukeys-cmd", "score": 1.4425339817971206}, {"caption": "\\usepackage{}", "snippet": "\\usepackage{$1}", "meta": "menukeys-cmd", "score": 5.427890758130527}, {"caption": "\\usepackage[]{}", "snippet": "\\usepackage[$1]{$2}", "meta": "menukeys-cmd", "score": 5.427890758130527}, {"caption": "\\empty", "snippet": "\\empty", "meta": "menukeys-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "menukeys-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "menukeys-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "menukeys-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "menukeys-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "menukeys-cmd", "score": 0.2864294797053033}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\mathlarger{}", "snippet": "\\mathlarger{$1}", "meta": "menukeys-cmd", "score": 0.0031475241540308316}, {"caption": "\\smaller", "snippet": "\\smaller", "meta": "menukeys-cmd", "score": 0.001271007880944704}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "menukeys-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "menukeys-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "menukeys-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "menukeys-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "menukeys-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "menukeys-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "menukeys-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "menukeys-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "menukeys-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "menukeys-cmd", "score": 0.004649150613625593}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "menukeys-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "menukeys-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "menukeys-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "menukeys-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "menukeys-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "menukeys-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "menukeys-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "menukeys-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "menukeys-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "menukeys-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "menukeys-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "menukeys-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "menukeys-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "menukeys-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "menukeys-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "menukeys-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "menukeys-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "menukeys-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "menukeys-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "menukeys-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "menukeys-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "menukeys-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "menukeys-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "menukeys-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "menukeys-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "menukeys-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "menukeys-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "menukeys-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "menukeys-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "menukeys-cmd", "score": 0.2864294797053033}], "hypdvips": [{"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "hypdvips-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "hypdvips-cmd", "score": 0.8973590434087177}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "hypdvips-cmd", "score": 0.9202908262245683}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "hypdvips-cmd", "score": 7.847906405228455}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "hypdvips-cmd", "score": 0.1789117552185788}, {"caption": "\\global", "snippet": "\\global", "meta": "hypdvips-cmd", "score": 0.006609629561859019}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "hypdvips-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "hypdvips-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "hypdvips-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "hypdvips-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "hypdvips-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "hypdvips-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "hypdvips-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "hypdvips-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "hypdvips-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "hypdvips-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "hypdvips-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "hypdvips-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "hypdvips-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "hypdvips-cmd", "score": 0.009472569279662113}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.006492248863367502}, {"caption": "\\figureautorefname", "snippet": "\\figureautorefname", "meta": "hypdvips-cmd", "score": 0.00014582556188448738}, {"caption": "\\figureautorefname{}", "snippet": "\\figureautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.00014582556188448738}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.006963729684667191}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\footnoteautorefname", "snippet": "\\footnoteautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\roman{}", "snippet": "\\roman{$1}", "meta": "hypdvips-cmd", "score": 0.005553384455935491}, {"caption": "\\roman", "snippet": "\\roman", "meta": "hypdvips-cmd", "score": 0.005553384455935491}, {"caption": "\\string", "snippet": "\\string", "meta": "hypdvips-cmd", "score": 0.001042697111754002}, {"caption": "\\MakeLowercase{}", "snippet": "\\MakeLowercase{$1}", "meta": "hypdvips-cmd", "score": 0.017289599800633146}, {"caption": "\\textunderscore", "snippet": "\\textunderscore", "meta": "hypdvips-cmd", "score": 0.001509072212764015}, {"caption": "\\do", "snippet": "\\do", "meta": "hypdvips-cmd", "score": 0.009278344180101056}, {"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "hypdvips-cmd", "score": 7.849662248028187}, {"caption": "\\FancyVerbLineautorefname", "snippet": "\\FancyVerbLineautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\hyperlink{}{}", "snippet": "\\hyperlink{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.00978652043902115}, {"caption": "\\tableautorefname", "snippet": "\\tableautorefname", "meta": "hypdvips-cmd", "score": 0.00012704528567339081}, {"caption": "\\tableautorefname{}", "snippet": "\\tableautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.00012704528567339081}, {"caption": "\\equationautorefname", "snippet": "\\equationautorefname", "meta": "hypdvips-cmd", "score": 0.00018777198999871106}, {"caption": "\\equationautorefname{}", "snippet": "\\equationautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.00018777198999871106}, {"caption": "\\chapterautorefname", "snippet": "\\chapterautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "hypdvips-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "hypdvips-cmd", "score": 0.02873756018238537}, {"caption": "\\protect", "snippet": "\\protect", "meta": "hypdvips-cmd", "score": 0.0200686676229443}, {"caption": "\\appendixautorefname", "snippet": "\\appendixautorefname", "meta": "hypdvips-cmd", "score": 7.950698053641679e-05}, {"caption": "\\appendixautorefname{}", "snippet": "\\appendixautorefname{$1}", "meta": "hypdvips-cmd", "score": 7.950698053641679e-05}, {"caption": "\\newlabel{}{}", "snippet": "\\newlabel{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.00029737672328168955}, {"caption": "\\texorpdfstring{}{}", "snippet": "\\texorpdfstring{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.0073781967296121}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "hypdvips-cmd", "score": 0.002140559856649122}, {"caption": "\\alph", "snippet": "\\alph", "meta": "hypdvips-cmd", "score": 0.01034327266194849}, {"caption": "\\alph{}", "snippet": "\\alph{$1}", "meta": "hypdvips-cmd", "score": 0.01034327266194849}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "hypdvips-cmd", "score": 0.019788865471151957}, {"caption": "\\item", "snippet": "\\item", "meta": "hypdvips-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "hypdvips-cmd", "score": 3.800886892251021}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "hypdvips-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "hypdvips-cmd", "score": 0.2334089308452787}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\itemautorefname", "snippet": "\\itemautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "hypdvips-cmd", "score": 1.2569477427490174}, {"caption": "\\sectionautorefname", "snippet": "\\sectionautorefname", "meta": "hypdvips-cmd", "score": 0.0019832324299155183}, {"caption": "\\sectionautorefname{}", "snippet": "\\sectionautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.0019832324299155183}, {"caption": "\\LaTeXe", "snippet": "\\LaTeXe", "meta": "hypdvips-cmd", "score": 0.007928096378157487}, {"caption": "\\LaTeXe{}", "snippet": "\\LaTeXe{$1}", "meta": "hypdvips-cmd", "score": 0.007928096378157487}, {"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "hypdvips-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "hypdvips-cmd", "score": 0.0003680857021151614}, {"caption": "\\hypertarget{}{}", "snippet": "\\hypertarget{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.009652820108904094}, {"caption": "\\theoremautorefname", "snippet": "\\theoremautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "hypdvips-cmd", "score": 0.7504160124360846}, {"caption": "\\subparagraphautorefname", "snippet": "\\subparagraphautorefname", "meta": "hypdvips-cmd", "score": 0.0005446476945175932}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "hypdvips-cmd", "score": 0.13586474005868793}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "hypdvips-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "hypdvips-cmd", "score": 0.8973590434087177}, {"caption": "\\href{}{}", "snippet": "\\href{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.27111130260612365}, {"caption": "\\Roman{}", "snippet": "\\Roman{$1}", "meta": "hypdvips-cmd", "score": 0.0038703587462843594}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\autoref{}", "snippet": "\\autoref{$1}", "meta": "hypdvips-cmd", "score": 0.03741172773691362}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "hypdvips-cmd", "score": 0.0004995635515943437}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "hypdvips-cmd", "score": 7.847906405228455}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "hypdvips-cmd", "score": 0.0174633138331273}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "hypdvips-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "hypdvips-cmd", "score": 0.006776001543888959}, {"caption": "\\partautorefname", "snippet": "\\partautorefname", "meta": "hypdvips-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\Itemautorefname{}", "snippet": "\\Itemautorefname{$1}", "meta": "hypdvips-cmd", "score": 6.006262128895586e-05}, {"caption": "\\halign{}", "snippet": "\\halign{$1}", "meta": "hypdvips-cmd", "score": 0.00017906650306643613}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.20852115286477566}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "hypdvips-cmd", "score": 1.4380093454211778}, {"caption": "\\Alph{}", "snippet": "\\Alph{$1}", "meta": "hypdvips-cmd", "score": 0.002233258780143355}, {"caption": "\\Alph", "snippet": "\\Alph", "meta": "hypdvips-cmd", "score": 0.002233258780143355}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "hypdvips-cmd", "score": 0.047007158741781095}, {"caption": "\\MP", "snippet": "\\MP", "meta": "hypdvips-cmd", "score": 0.00018344383742255004}, {"caption": "\\MP{}", "snippet": "\\MP{$1}", "meta": "hypdvips-cmd", "score": 0.00018344383742255004}, {"caption": "\\paragraphautorefname", "snippet": "\\paragraphautorefname", "meta": "hypdvips-cmd", "score": 0.0005446476945175932}, {"caption": "\\citeN{}", "snippet": "\\citeN{$1}", "meta": "hypdvips-cmd", "score": 0.0018503938529945614}, {"caption": "\\citeN", "snippet": "\\citeN", "meta": "hypdvips-cmd", "score": 0.0018503938529945614}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.07503475348393239}, {"caption": "\\subsectionautorefname", "snippet": "\\subsectionautorefname", "meta": "hypdvips-cmd", "score": 0.0012546605780895737}, {"caption": "\\subsectionautorefname{}", "snippet": "\\subsectionautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.0012546605780895737}, {"caption": "\\hyperref[]{}", "snippet": "\\hyperref[$1]{$2}", "meta": "hypdvips-cmd", "score": 0.004515152477030062}, {"caption": "\\arabic{}", "snippet": "\\arabic{$1}", "meta": "hypdvips-cmd", "score": 0.02445837629741638}, {"caption": "\\arabic", "snippet": "\\arabic", "meta": "hypdvips-cmd", "score": 0.02445837629741638}, {"caption": "\\newline", "snippet": "\\newline", "meta": "hypdvips-cmd", "score": 0.3311721696201715}, {"caption": "\\hypersetup{}", "snippet": "\\hypersetup{$1}", "meta": "hypdvips-cmd", "score": 0.06967310843464661}, {"caption": "\\subsubsectionautorefname", "snippet": "\\subsubsectionautorefname", "meta": "hypdvips-cmd", "score": 0.0012064581899162352}, {"caption": "\\subsubsectionautorefname{}", "snippet": "\\subsubsectionautorefname{$1}", "meta": "hypdvips-cmd", "score": 0.0012064581899162352}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "hypdvips-cmd", "score": 0.9202908262245683}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.006492248863367502}, {"caption": "\\bookmarkget{}", "snippet": "\\bookmarkget{$1}", "meta": "hypdvips-cmd", "score": 0.00026847053008917257}, {"caption": "\\bookmarksetup{}", "snippet": "\\bookmarksetup{$1}", "meta": "hypdvips-cmd", "score": 0.001134118016265821}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "hypdvips-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "hypdvips-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "hypdvips-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "hypdvips-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "hypdvips-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hypdvips-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "hypdvips-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hypdvips-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "hypdvips-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hypdvips-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "hypdvips-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "hypdvips-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "hypdvips-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "hypdvips-cmd", "score": 0.2864294797053033}], "easyReview": [{"caption": "\\highlight{}", "snippet": "\\highlight{$1}", "meta": "easyReview-cmd", "score": 0.00021546602164732416}, {"caption": "\\highlight", "snippet": "\\highlight", "meta": "easyReview-cmd", "score": 0.00021546602164732416}, {"caption": "\\alert{}", "snippet": "\\alert{$1}", "meta": "easyReview-cmd", "score": 0.02756568949970745}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "easyReview-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "easyReview-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "easyReview-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "easyReview-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "easyReview-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "easyReview-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "easyReview-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "easyReview-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "easyReview-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "easyReview-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "easyReview-cmd", "score": 0.004649150613625593}, {"caption": "\\missingfigure[]{}", "snippet": "\\missingfigure[$1]{$2}", "meta": "easyReview-cmd", "score": 0.001558719179721163}, {"caption": "\\missingfigure", "snippet": "\\missingfigure", "meta": "easyReview-cmd", "score": 0.001558719179721163}, {"caption": "\\todototoc", "snippet": "\\todototoc", "meta": "easyReview-cmd", "score": 0.000325977535138643}, {"caption": "\\todo{}", "snippet": "\\todo{$1}", "meta": "easyReview-cmd", "score": 0.04115074278362878}, {"caption": "\\todo[]{}", "snippet": "\\todo[$1]{$2}", "meta": "easyReview-cmd", "score": 0.04115074278362878}, {"caption": "\\todo", "snippet": "\\todo", "meta": "easyReview-cmd", "score": 0.04115074278362878}, {"caption": "\\listoftodos", "snippet": "\\listoftodos", "meta": "easyReview-cmd", "score": 0.0005325975940754609}, {"caption": "\\listoftodos[]", "snippet": "\\listoftodos[$1]", "meta": "easyReview-cmd", "score": 0.0005325975940754609}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "easyReview-cmd", "score": 0.0174633138331273}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "easyReview-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "easyReview-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "easyReview-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "easyReview-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "easyReview-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "easyReview-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "easyReview-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "easyReview-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "easyReview-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "easyReview-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "easyReview-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "easyReview-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "easyReview-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "easyReview-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareRobustCommand{}{}", "snippet": "\\DeclareRobustCommand{$1}{$2}", "meta": "easyReview-cmd", "score": 0.0010373158471650705}, {"caption": "\\DeclareRobustCommand{}[]{}", "snippet": "\\DeclareRobustCommand{$1}[$2]{$3}", "meta": "easyReview-cmd", "score": 0.0010373158471650705}, {"caption": "\\sethlcolor{}", "snippet": "\\sethlcolor{$1}", "meta": "easyReview-cmd", "score": 0.01970230898277056}, {"caption": "\\st", "snippet": "\\st", "meta": "easyReview-cmd", "score": 0.004652662833362787}, {"caption": "\\st{}", "snippet": "\\st{$1}", "meta": "easyReview-cmd", "score": 0.004652662833362787}, {"caption": "\\def", "snippet": "\\def", "meta": "easyReview-cmd", "score": 0.21357759092476175}, {"caption": "\\hl{}", "snippet": "\\hl{$1}", "meta": "easyReview-cmd", "score": 0.03421486301062431}, {"caption": "\\sodef", "snippet": "\\sodef", "meta": "easyReview-cmd", "score": 0.0017045357696831268}, {"caption": "\\csname", "snippet": "\\csname", "meta": "easyReview-cmd", "score": 0.008565354665444157}, {"caption": "\\so", "snippet": "\\so", "meta": "easyReview-cmd", "score": 0.004308800134587786}, {"caption": "\\so{}", "snippet": "\\so{$1}", "meta": "easyReview-cmd", "score": 0.004308800134587786}, {"caption": "\\csname", "snippet": "\\csname", "meta": "easyReview-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "easyReview-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "easyReview-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "easyReview-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "easyReview-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "easyReview-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "easyReview-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "easyReview-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "easyReview-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "easyReview-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "easyReview-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "easyReview-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "easyReview-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "easyReview-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "easyReview-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "easyReview-cmd", "score": 0.2864294797053033}], "quoting": [{"caption": "\\par", "snippet": "\\par", "meta": "quoting-cmd", "score": 0.413853376001159}, {"caption": "\\empty", "snippet": "\\empty", "meta": "quoting-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "quoting-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "quoting-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "quoting-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "quoting-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "quoting-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "quoting-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "quoting-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "quoting-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "quoting-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "quoting-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "quoting-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "quoting-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "quoting-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "quoting-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "quoting-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "quoting-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "quoting-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "quoting-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "quoting-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "quoting-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "quoting-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "quoting-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "quoting-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "quoting-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "quoting-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "quoting-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "quoting-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "quoting-cmd", "score": 0.021170869458413965}, {"caption": "\\empty", "snippet": "\\empty", "meta": "quoting-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "quoting-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "quoting-cmd", "score": 0.008565354665444157}], "fouriernc": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fouriernc-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "fouriernc-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "fouriernc-cmd", "score": 0.021170869458413965}], "realboxes": [{"caption": "\\Rotatebox{}{}", "snippet": "\\Rotatebox{$1}{$2}", "meta": "realboxes-cmd", "score": 1.8920528094586312e-05}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "realboxes-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "realboxes-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "realboxes-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "realboxes-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "realboxes-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "realboxes-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "realboxes-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "realboxes-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "realboxes-cmd", "score": 0.028955796305270766}, {"caption": "\\shadowbox{}", "snippet": "\\shadowbox{$1}", "meta": "realboxes-cmd", "score": 0.00107667147399019}, {"caption": "\\doublebox", "snippet": "\\doublebox", "meta": "realboxes-cmd", "score": 0.00015142240898356106}, {"caption": "\\VerbatimEnvironment", "snippet": "\\VerbatimEnvironment", "meta": "realboxes-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\thisfancypage{}{}", "snippet": "\\thisfancypage{$1}{$2}", "meta": "realboxes-cmd", "score": 0.00015142240898356106}, {"caption": "\\TheSbox", "snippet": "\\TheSbox", "meta": "realboxes-cmd", "score": 4.5350034239275855e-05}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "realboxes-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "realboxes-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "realboxes-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "realboxes-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "realboxes-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "realboxes-cmd", "score": 0.0018957469739775527}], "etextools": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "etextools-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "etextools-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "etextools-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "etextools-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "etextools-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "etextools-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "etextools-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "etextools-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "etextools-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "etextools-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "etextools-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "etextools-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "etextools-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "etextools-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "etextools-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "etextools-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "etextools-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "etextools-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "etextools-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "etextools-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "etextools-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "etextools-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "etextools-cmd", "score": 0.008565354665444157}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "etextools-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "etextools-cmd", "score": 0.00031058155311734754}], "ccaption": [{"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "ccaption-cmd", "score": 1.2569477427490174}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "ccaption-cmd", "score": 1.897791904799601}], "exercise": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "exercise-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "exercise-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "exercise-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "exercise-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "exercise-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "exercise-cmd", "score": 0.0018957469739775527}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "exercise-cmd", "score": 0.00037306820619479756}], "slantsc": [{"caption": "\\scshape", "snippet": "\\scshape", "meta": "slantsc-cmd", "score": 0.05364108855914402}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "slantsc-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "slantsc-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "slantsc-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "slantsc-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "slantsc-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "slantsc-cmd", "score": 0.0018957469739775527}], "glossary-longbooktabs": [{"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "glossary-longbooktabs-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "glossary-longbooktabs-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "glossary-longbooktabs-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "glossary-longbooktabs-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "glossary-longbooktabs-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "glossary-longbooktabs-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "glossary-longbooktabs-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "glossary-longbooktabs-cmd", "score": 0.059857788139528495}, {"caption": "\\endhead", "snippet": "\\endhead", "meta": "glossary-longbooktabs-cmd", "score": 0.0023853501147448834}, {"caption": "\\endfoot", "snippet": "\\endfoot", "meta": "glossary-longbooktabs-cmd", "score": 0.00044045261916551967}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "glossary-longbooktabs-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "glossary-longbooktabs-cmd", "score": 0.021170869458413965}, {"caption": "\\nopagebreak", "snippet": "\\nopagebreak", "meta": "glossary-longbooktabs-cmd", "score": 9.952664522415981e-05}, {"caption": "\\endfirsthead", "snippet": "\\endfirsthead", "meta": "glossary-longbooktabs-cmd", "score": 0.0016148498709822416}, {"caption": "\\endlastfoot", "snippet": "\\endlastfoot", "meta": "glossary-longbooktabs-cmd", "score": 0.00044045261916551967}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "glossary-longbooktabs-cmd", "score": 0.3277033727934986}, {"caption": "\\tablename", "snippet": "\\tablename", "meta": "glossary-longbooktabs-cmd", "score": 0.0029238994233674776}, {"caption": "\\pagebreak", "snippet": "\\pagebreak", "meta": "glossary-longbooktabs-cmd", "score": 0.0313525090421608}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "glossary-longbooktabs-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "glossary-longbooktabs-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "glossary-longbooktabs-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "glossary-longbooktabs-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "glossary-longbooktabs-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "glossary-longbooktabs-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "glossary-longbooktabs-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "glossary-longbooktabs-cmd", "score": 0.018615449342361392}], "pgflibraryarrows": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgflibraryarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgflibraryarrows-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgflibraryarrows-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgflibraryarrows-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgflibraryarrows-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgflibraryarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgflibraryarrows-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgflibraryarrows-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgflibraryarrows-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgflibraryarrows-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgflibraryarrows-cmd", "score": 0.2864294797053033}], "soulpos": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "soulpos-cmd", "score": 0.00037306820619479756}], "gmp": [{"caption": "\\par", "snippet": "\\par", "meta": "gmp-cmd", "score": 0.413853376001159}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gmp-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gmp-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "gmp-cmd", "score": 0.00037306820619479756}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "gmp-cmd", "score": 0.00021116765384691477}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "gmp-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "gmp-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "gmp-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "gmp-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "gmp-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "gmp-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "gmp-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "gmp-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "gmp-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gmp-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "gmp-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "gmp-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "gmp-cmd", "score": 0.004719094298848707}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "gmp-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "gmp-cmd", "score": 0.021170869458413965}], "csvsimple": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "csvsimple-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "csvsimple-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "csvsimple-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "csvsimple-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "csvsimple-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "csvsimple-cmd", "score": 0.0018957469739775527}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "csvsimple-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "csvsimple-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "csvsimple-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "csvsimple-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "csvsimple-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "csvsimple-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "csvsimple-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "csvsimple-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "csvsimple-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "csvsimple-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "csvsimple-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "csvsimple-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "csvsimple-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "csvsimple-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "csvsimple-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "csvsimple-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "csvsimple-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "csvsimple-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "csvsimple-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "csvsimple-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "csvsimple-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "csvsimple-cmd", "score": 0.008565354665444157}], "ebgaramond": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "ebgaramond-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ebgaramond-cmd", "score": 0.008565354665444157}], "boldline": [{"caption": "\\hlineB{}", "snippet": "\\hlineB{$1}", "meta": "boldline-cmd", "score": 0.0009735563258863602}, {"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "boldline-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "boldline-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "boldline-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "boldline-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "boldline-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "boldline-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "boldline-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "boldline-cmd", "score": 0.018615449342361392}], "fontaxes": [{"caption": "\\csname", "snippet": "\\csname", "meta": "fontaxes-cmd", "score": 0.008565354665444157}], "pbsi": [{"caption": "\\bsifamily", "snippet": "\\bsifamily", "meta": "pbsi-cmd", "score": 3.140504277052775e-05}], "tikz-qtree-compat": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-qtree-compat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tikz-qtree-compat-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tikz-qtree-compat-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-qtree-compat-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-compat-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tikz-qtree-compat-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-compat-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tikz-qtree-compat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tikz-qtree-compat-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tikz-qtree-compat-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tikz-qtree-compat-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tikz-qtree-compat-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tikz-qtree-compat-cmd", "score": 0.2864294797053033}], "ebgaramond-maths": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "ebgaramond-maths-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "ebgaramond-maths-cmd", "score": 0.008565354665444157}], "complexity": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "complexity-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "complexity-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "complexity-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "complexity-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "complexity-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "complexity-cmd", "score": 0.0018957469739775527}], "everysel": [{"caption": "\\selectfont", "snippet": "\\selectfont", "meta": "everysel-cmd", "score": 0.04598628699063736}], "txfontsb": [{"caption": "\\sqrt{}", "snippet": "\\sqrt{$1}", "meta": "txfontsb-cmd", "score": 0.20240160977404634}], "nath": [{"caption": "\\vert", "snippet": "\\vert", "meta": "nath-cmd", "score": 0.05152912629788525}, {"caption": "\\prod", "snippet": "\\prod", "meta": "nath-cmd", "score": 0.02549889375975901}, {"caption": "\\quad", "snippet": "\\quad", "meta": "nath-cmd", "score": 0.15242755832392743}, {"caption": "\\underbrace{}", "snippet": "\\underbrace{$1}", "meta": "nath-cmd", "score": 0.010373780436850907}, {"caption": "\\sum", "snippet": "\\sum", "meta": "nath-cmd", "score": 0.42607994509619934}, {"caption": "\\delimgrowth", "snippet": "\\delimgrowth", "meta": "nath-cmd", "score": 1.8073688234300064e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "nath-cmd", "score": 1.4341091141105058}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "nath-cmd", "score": 0.11280487530505384}, {"caption": "\\underline{}", "snippet": "\\underline{$1}", "meta": "nath-cmd", "score": 0.14748550887002482}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "nath-cmd", "score": 1.897791904799601}, {"caption": "\\qquad", "snippet": "\\qquad", "meta": "nath-cmd", "score": 0.0878145577017131}], "vietnam": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "vietnam-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "vietnam-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "vietnam-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "vietnam-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "vietnam-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "vietnam-cmd", "score": 0.0018957469739775527}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "vietnam-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "vietnam-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "vietnam-cmd", "score": 0.021170869458413965}], "answers": [{"caption": "\\endverbatim", "snippet": "\\endverbatim", "meta": "answers-cmd", "score": 0.0022216421267780076}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "answers-cmd", "score": 0.0072203369120285256}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "answers-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "answers-cmd", "score": 0.021170869458413965}, {"caption": "\\par", "snippet": "\\par", "meta": "answers-cmd", "score": 0.413853376001159}, {"caption": "\\verbatiminput{}", "snippet": "\\verbatiminput{$1}", "meta": "answers-cmd", "score": 0.0024547099784948665}, {"caption": "\\verbatiminput", "snippet": "\\verbatiminput", "meta": "answers-cmd", "score": 0.0024547099784948665}], "attachfile": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "attachfile-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "attachfile-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "attachfile-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "attachfile-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "attachfile-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "attachfile-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "attachfile-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "attachfile-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "attachfile-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "attachfile-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "attachfile-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "attachfile-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "attachfile-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "attachfile-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "attachfile-cmd", "score": 0.009472569279662113}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "attachfile-cmd", "score": 0.006492248863367502}, {"caption": "\\figureautorefname", "snippet": "\\figureautorefname", "meta": "attachfile-cmd", "score": 0.00014582556188448738}, {"caption": "\\figureautorefname{}", "snippet": "\\figureautorefname{$1}", "meta": "attachfile-cmd", "score": 0.00014582556188448738}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "attachfile-cmd", "score": 0.006963729684667191}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\footnoteautorefname", "snippet": "\\footnoteautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\roman{}", "snippet": "\\roman{$1}", "meta": "attachfile-cmd", "score": 0.005553384455935491}, {"caption": "\\roman", "snippet": "\\roman", "meta": "attachfile-cmd", "score": 0.005553384455935491}, {"caption": "\\string", "snippet": "\\string", "meta": "attachfile-cmd", "score": 0.001042697111754002}, {"caption": "\\MakeLowercase{}", "snippet": "\\MakeLowercase{$1}", "meta": "attachfile-cmd", "score": 0.017289599800633146}, {"caption": "\\textunderscore", "snippet": "\\textunderscore", "meta": "attachfile-cmd", "score": 0.001509072212764015}, {"caption": "\\do", "snippet": "\\do", "meta": "attachfile-cmd", "score": 0.009278344180101056}, {"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "attachfile-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "attachfile-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "attachfile-cmd", "score": 7.849662248028187}, {"caption": "\\FancyVerbLineautorefname", "snippet": "\\FancyVerbLineautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\hyperlink{}{}", "snippet": "\\hyperlink{$1}{$2}", "meta": "attachfile-cmd", "score": 0.00978652043902115}, {"caption": "\\tableautorefname", "snippet": "\\tableautorefname", "meta": "attachfile-cmd", "score": 0.00012704528567339081}, {"caption": "\\tableautorefname{}", "snippet": "\\tableautorefname{$1}", "meta": "attachfile-cmd", "score": 0.00012704528567339081}, {"caption": "\\equationautorefname", "snippet": "\\equationautorefname", "meta": "attachfile-cmd", "score": 0.00018777198999871106}, {"caption": "\\equationautorefname{}", "snippet": "\\equationautorefname{$1}", "meta": "attachfile-cmd", "score": 0.00018777198999871106}, {"caption": "\\chapterautorefname", "snippet": "\\chapterautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "attachfile-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "attachfile-cmd", "score": 0.02873756018238537}, {"caption": "\\protect", "snippet": "\\protect", "meta": "attachfile-cmd", "score": 0.0200686676229443}, {"caption": "\\appendixautorefname", "snippet": "\\appendixautorefname", "meta": "attachfile-cmd", "score": 7.950698053641679e-05}, {"caption": "\\appendixautorefname{}", "snippet": "\\appendixautorefname{$1}", "meta": "attachfile-cmd", "score": 7.950698053641679e-05}, {"caption": "\\newlabel{}{}", "snippet": "\\newlabel{$1}{$2}", "meta": "attachfile-cmd", "score": 0.00029737672328168955}, {"caption": "\\texorpdfstring{}{}", "snippet": "\\texorpdfstring{$1}{$2}", "meta": "attachfile-cmd", "score": 0.0073781967296121}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "attachfile-cmd", "score": 0.002140559856649122}, {"caption": "\\alph", "snippet": "\\alph", "meta": "attachfile-cmd", "score": 0.01034327266194849}, {"caption": "\\alph{}", "snippet": "\\alph{$1}", "meta": "attachfile-cmd", "score": 0.01034327266194849}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "attachfile-cmd", "score": 0.019788865471151957}, {"caption": "\\item", "snippet": "\\item", "meta": "attachfile-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "attachfile-cmd", "score": 3.800886892251021}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "attachfile-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "attachfile-cmd", "score": 0.2334089308452787}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\itemautorefname", "snippet": "\\itemautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "attachfile-cmd", "score": 1.2569477427490174}, {"caption": "\\sectionautorefname", "snippet": "\\sectionautorefname", "meta": "attachfile-cmd", "score": 0.0019832324299155183}, {"caption": "\\sectionautorefname{}", "snippet": "\\sectionautorefname{$1}", "meta": "attachfile-cmd", "score": 0.0019832324299155183}, {"caption": "\\LaTeXe", "snippet": "\\LaTeXe", "meta": "attachfile-cmd", "score": 0.007928096378157487}, {"caption": "\\LaTeXe{}", "snippet": "\\LaTeXe{$1}", "meta": "attachfile-cmd", "score": 0.007928096378157487}, {"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "attachfile-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "attachfile-cmd", "score": 0.0003680857021151614}, {"caption": "\\hypertarget{}{}", "snippet": "\\hypertarget{$1}{$2}", "meta": "attachfile-cmd", "score": 0.009652820108904094}, {"caption": "\\theoremautorefname", "snippet": "\\theoremautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "attachfile-cmd", "score": 0.7504160124360846}, {"caption": "\\subparagraphautorefname", "snippet": "\\subparagraphautorefname", "meta": "attachfile-cmd", "score": 0.0005446476945175932}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "attachfile-cmd", "score": 0.13586474005868793}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "attachfile-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "attachfile-cmd", "score": 0.8973590434087177}, {"caption": "\\href{}{}", "snippet": "\\href{$1}{$2}", "meta": "attachfile-cmd", "score": 0.27111130260612365}, {"caption": "\\Roman{}", "snippet": "\\Roman{$1}", "meta": "attachfile-cmd", "score": 0.0038703587462843594}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}, {"caption": "\\autoref{}", "snippet": "\\autoref{$1}", "meta": "attachfile-cmd", "score": 0.03741172773691362}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "attachfile-cmd", "score": 0.0004995635515943437}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "attachfile-cmd", "score": 7.847906405228455}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "attachfile-cmd", "score": 0.0174633138331273}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "attachfile-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "attachfile-cmd", "score": 0.006776001543888959}, {"caption": "\\partautorefname", "snippet": "\\partautorefname", "meta": "attachfile-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\Itemautorefname{}", "snippet": "\\Itemautorefname{$1}", "meta": "attachfile-cmd", "score": 6.006262128895586e-05}, {"caption": "\\halign{}", "snippet": "\\halign{$1}", "meta": "attachfile-cmd", "score": 0.00017906650306643613}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "attachfile-cmd", "score": 0.20852115286477566}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "attachfile-cmd", "score": 1.4380093454211778}, {"caption": "\\Alph{}", "snippet": "\\Alph{$1}", "meta": "attachfile-cmd", "score": 0.002233258780143355}, {"caption": "\\Alph", "snippet": "\\Alph", "meta": "attachfile-cmd", "score": 0.002233258780143355}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "attachfile-cmd", "score": 0.047007158741781095}, {"caption": "\\MP", "snippet": "\\MP", "meta": "attachfile-cmd", "score": 0.00018344383742255004}, {"caption": "\\MP{}", "snippet": "\\MP{$1}", "meta": "attachfile-cmd", "score": 0.00018344383742255004}, {"caption": "\\paragraphautorefname", "snippet": "\\paragraphautorefname", "meta": "attachfile-cmd", "score": 0.0005446476945175932}, {"caption": "\\citeN{}", "snippet": "\\citeN{$1}", "meta": "attachfile-cmd", "score": 0.0018503938529945614}, {"caption": "\\citeN", "snippet": "\\citeN", "meta": "attachfile-cmd", "score": 0.0018503938529945614}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "attachfile-cmd", "score": 0.07503475348393239}, {"caption": "\\subsectionautorefname", "snippet": "\\subsectionautorefname", "meta": "attachfile-cmd", "score": 0.0012546605780895737}, {"caption": "\\subsectionautorefname{}", "snippet": "\\subsectionautorefname{$1}", "meta": "attachfile-cmd", "score": 0.0012546605780895737}, {"caption": "\\hyperref[]{}", "snippet": "\\hyperref[$1]{$2}", "meta": "attachfile-cmd", "score": 0.004515152477030062}, {"caption": "\\arabic{}", "snippet": "\\arabic{$1}", "meta": "attachfile-cmd", "score": 0.02445837629741638}, {"caption": "\\arabic", "snippet": "\\arabic", "meta": "attachfile-cmd", "score": 0.02445837629741638}, {"caption": "\\newline", "snippet": "\\newline", "meta": "attachfile-cmd", "score": 0.3311721696201715}, {"caption": "\\hypersetup{}", "snippet": "\\hypersetup{$1}", "meta": "attachfile-cmd", "score": 0.06967310843464661}, {"caption": "\\subsubsectionautorefname", "snippet": "\\subsubsectionautorefname", "meta": "attachfile-cmd", "score": 0.0012064581899162352}, {"caption": "\\subsubsectionautorefname{}", "snippet": "\\subsubsectionautorefname{$1}", "meta": "attachfile-cmd", "score": 0.0012064581899162352}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "attachfile-cmd", "score": 0.9202908262245683}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "attachfile-cmd", "score": 0.00926923425734719}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "attachfile-cmd", "score": 0.20852115286477566}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "attachfile-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "attachfile-cmd", "score": 0.0008147200475678891}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "attachfile-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "attachfile-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "attachfile-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "attachfile-cmd", "score": 0.2864294797053033}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "attachfile-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "attachfile-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "attachfile-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "attachfile-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "attachfile-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "attachfile-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "attachfile-cmd", "score": 0.028955796305270766}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "attachfile-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "attachfile-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "attachfile-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "attachfile-cmd", "score": 0.002958865219480927}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "attachfile-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "attachfile-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "attachfile-cmd", "score": 0.00530510025314411}], "doc": [{"caption": "\\do", "snippet": "\\do", "meta": "doc-cmd", "score": 0.009278344180101056}, {"caption": "\\verb", "snippet": "\\verb", "meta": "doc-cmd", "score": 0.1323269725886312}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "doc-cmd", "score": 0.7504160124360846}, {"caption": "\\verbatim", "snippet": "\\verbatim", "meta": "doc-cmd", "score": 0.0072203369120285256}], "tkz-fct": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-fct-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "tkz-fct-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "tkz-fct-cmd", "score": 0.00031058155311734754}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tkz-fct-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tkz-fct-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tkz-fct-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-fct-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tkz-fct-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-fct-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tkz-fct-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-fct-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tkz-fct-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tkz-fct-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-fct-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tkz-fct-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-fct-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tkz-fct-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-fct-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tkz-fct-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tkz-fct-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tkz-fct-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tkz-fct-cmd", "score": 0.2864294797053033}], "notes2bib": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "notes2bib-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "notes2bib-cmd", "score": 0.2864294797053033}], "stackengine": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "stackengine-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "stackengine-cmd", "score": 0.021170869458413965}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "stackengine-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "stackengine-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "stackengine-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "stackengine-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "stackengine-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "stackengine-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "stackengine-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "stackengine-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "stackengine-cmd", "score": 0.028955796305270766}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "stackengine-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "stackengine-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "stackengine-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "stackengine-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "stackengine-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "stackengine-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "stackengine-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "stackengine-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "stackengine-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "stackengine-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "stackengine-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "stackengine-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "stackengine-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "stackengine-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "stackengine-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "stackengine-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "stackengine-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "stackengine-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "stackengine-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "stackengine-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "stackengine-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "stackengine-cmd", "score": 0.008565354665444157}], "cellspace": [{"caption": "\\endtabular", "snippet": "\\endtabular", "meta": "cellspace-cmd", "score": 0.0005078239917067089}, {"caption": "\\multicolumn{}{}{}", "snippet": "\\multicolumn{$1}{$2}{$3}", "meta": "cellspace-cmd", "score": 0.5473606021405326}, {"caption": "\\array{}", "snippet": "\\array{$1}", "meta": "cellspace-cmd", "score": 2.650484574842396e-05}, {"caption": "\\arraybackslash", "snippet": "\\arraybackslash", "meta": "cellspace-cmd", "score": 0.014532521139459619}, {"caption": "\\tabular{}", "snippet": "\\tabular{$1}", "meta": "cellspace-cmd", "score": 0.0005078239917067089}, {"caption": "\\csname", "snippet": "\\csname", "meta": "cellspace-cmd", "score": 0.008565354665444157}, {"caption": "\\newcolumntype{}[]{}", "snippet": "\\newcolumntype{$1}[$2]{$3}", "meta": "cellspace-cmd", "score": 0.018615449342361392}, {"caption": "\\newcolumntype{}{}", "snippet": "\\newcolumntype{$1}{$2}", "meta": "cellspace-cmd", "score": 0.018615449342361392}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "cellspace-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "cellspace-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "cellspace-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "cellspace-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "cellspace-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "cellspace-cmd", "score": 0.0018957469739775527}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "cellspace-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "cellspace-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "cellspace-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "cellspace-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "cellspace-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "cellspace-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "cellspace-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "cellspace-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "cellspace-cmd", "score": 0.028955796305270766}], "zxjatype": [{"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "zxjatype-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "zxjatype-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "zxjatype-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "zxjatype-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "zxjatype-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "zxjatype-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "zxjatype-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "zxjatype-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "zxjatype-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "zxjatype-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "zxjatype-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "zxjatype-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "zxjatype-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "zxjatype-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "zxjatype-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "zxjatype-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zxjatype-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "zxjatype-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "zxjatype-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "zxjatype-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "zxjatype-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zxjatype-cmd", "score": 0.008565354665444157}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "zxjatype-cmd", "score": 0.00021116765384691477}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "zxjatype-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "zxjatype-cmd", "score": 0.2864294797053033}], "newclude": [{"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "newclude-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "newclude-cmd", "score": 1.4425339817971206}, {"caption": "\\include{}", "snippet": "\\include{$1}", "meta": "newclude-cmd", "score": 0.1547080054979312}], "pgf-umlcd": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlcd-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-umlcd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-umlcd-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgf-umlcd-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgf-umlcd-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgf-umlcd-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-umlcd-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgf-umlcd-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlcd-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgf-umlcd-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgf-umlcd-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgf-umlcd-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgf-umlcd-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgf-umlcd-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgf-umlcd-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgf-umlcd-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgf-umlcd-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgf-umlcd-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgf-umlcd-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgf-umlcd-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgf-umlcd-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgf-umlcd-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgf-umlcd-cmd", "score": 0.2864294797053033}], "thm-listof": [{"caption": "\\listtheoremname", "snippet": "\\listtheoremname", "meta": "thm-listof-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\thmtformatoptarg", "snippet": "\\thmtformatoptarg", "meta": "thm-listof-cmd", "score": 6.353668036093916e-05}, {"caption": "\\listoftheorems[]", "snippet": "\\listoftheorems[$1]", "meta": "thm-listof-cmd", "score": 1.9443373798666845e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thm-listof-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "thm-listof-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "thm-listof-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "thm-listof-cmd", "score": 0.008565354665444157}, {"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thm-listof-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thm-listof-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thm-listof-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thm-listof-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thm-listof-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thm-listof-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thm-listof-cmd", "score": 0.0006133100544751855}], "thm-autoref": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thm-autoref-cmd", "score": 0.00037306820619479756}, {"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thm-autoref-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thm-autoref-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thm-autoref-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thm-autoref-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thm-autoref-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thm-autoref-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thm-autoref-cmd", "score": 0.0006133100544751855}], "thm-patch": [{"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thm-patch-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thm-patch-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thm-patch-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thm-patch-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thm-patch-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thm-patch-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thm-patch-cmd", "score": 0.0006133100544751855}], "thm-kv": [{"caption": "\\declaretheoremstyle[]{}", "snippet": "\\declaretheoremstyle[$1]{$2}", "meta": "thm-kv-cmd", "score": 0.0001168034231635369}, {"caption": "\\declaretheorem[]{}", "snippet": "\\declaretheorem[$1]{$2}", "meta": "thm-kv-cmd", "score": 0.0004904790216915127}, {"caption": "\\theoremstyle{}", "snippet": "\\theoremstyle{$1}", "meta": "thm-kv-cmd", "score": 0.02533412165007986}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thm-kv-cmd", "score": 0.00037306820619479756}, {"caption": "\\proof{}", "snippet": "\\proof{$1}", "meta": "thm-kv-cmd", "score": 0.000701497773639073}, {"caption": "\\proof", "snippet": "\\proof", "meta": "thm-kv-cmd", "score": 0.000701497773639073}, {"caption": "\\newtheorem{}[]{}", "snippet": "\\newtheorem{$1}[$2]{$3}", "meta": "thm-kv-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}", "snippet": "\\newtheorem{$1}{$2}", "meta": "thm-kv-cmd", "score": 0.215689795055434}, {"caption": "\\newtheorem{}{}[]", "snippet": "\\newtheorem{$1}{$2}[$3]", "meta": "thm-kv-cmd", "score": 0.215689795055434}, {"caption": "\\endproof", "snippet": "\\endproof", "meta": "thm-kv-cmd", "score": 0.0006133100544751855}, {"caption": "\\endproof{}", "snippet": "\\endproof{$1}", "meta": "thm-kv-cmd", "score": 0.0006133100544751855}, {"caption": "\\empty", "snippet": "\\empty", "meta": "thm-kv-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "thm-kv-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "thm-kv-cmd", "score": 0.008565354665444157}], "onlyamsmath": [{"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "onlyamsmath-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "onlyamsmath-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "onlyamsmath-cmd", "score": 0.18137737738638837}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "onlyamsmath-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "onlyamsmath-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "onlyamsmath-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "onlyamsmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "onlyamsmath-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "onlyamsmath-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "onlyamsmath-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "onlyamsmath-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "onlyamsmath-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "onlyamsmath-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "onlyamsmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "onlyamsmath-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "onlyamsmath-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "onlyamsmath-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "onlyamsmath-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "onlyamsmath-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "onlyamsmath-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "onlyamsmath-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "onlyamsmath-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "onlyamsmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "onlyamsmath-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "onlyamsmath-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "onlyamsmath-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "onlyamsmath-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "onlyamsmath-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "onlyamsmath-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "onlyamsmath-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "onlyamsmath-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "onlyamsmath-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "onlyamsmath-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "onlyamsmath-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "onlyamsmath-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "onlyamsmath-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "onlyamsmath-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "onlyamsmath-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "onlyamsmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "onlyamsmath-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "onlyamsmath-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "onlyamsmath-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "onlyamsmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "onlyamsmath-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "onlyamsmath-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "onlyamsmath-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "onlyamsmath-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "onlyamsmath-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "onlyamsmath-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "onlyamsmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "onlyamsmath-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "onlyamsmath-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "onlyamsmath-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "onlyamsmath-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "onlyamsmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "onlyamsmath-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "onlyamsmath-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "onlyamsmath-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "onlyamsmath-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "onlyamsmath-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "onlyamsmath-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "onlyamsmath-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "onlyamsmath-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "onlyamsmath-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "onlyamsmath-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "onlyamsmath-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "onlyamsmath-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "onlyamsmath-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "onlyamsmath-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "onlyamsmath-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "onlyamsmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "onlyamsmath-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "onlyamsmath-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "onlyamsmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "onlyamsmath-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "onlyamsmath-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "onlyamsmath-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "onlyamsmath-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "onlyamsmath-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "onlyamsmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "onlyamsmath-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "onlyamsmath-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "onlyamsmath-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "onlyamsmath-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "onlyamsmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "onlyamsmath-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "onlyamsmath-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "onlyamsmath-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "onlyamsmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "onlyamsmath-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "onlyamsmath-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "onlyamsmath-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "onlyamsmath-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "onlyamsmath-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "onlyamsmath-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "onlyamsmath-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "onlyamsmath-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "onlyamsmath-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "onlyamsmath-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "onlyamsmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "onlyamsmath-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "onlyamsmath-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "onlyamsmath-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "onlyamsmath-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "onlyamsmath-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "onlyamsmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "onlyamsmath-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "onlyamsmath-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "onlyamsmath-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "onlyamsmath-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "onlyamsmath-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "onlyamsmath-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "onlyamsmath-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "onlyamsmath-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "onlyamsmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "onlyamsmath-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "onlyamsmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "onlyamsmath-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "onlyamsmath-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "onlyamsmath-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "onlyamsmath-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "onlyamsmath-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "onlyamsmath-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "onlyamsmath-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "onlyamsmath-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "onlyamsmath-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "onlyamsmath-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "onlyamsmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "onlyamsmath-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "onlyamsmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "onlyamsmath-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "onlyamsmath-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "onlyamsmath-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "onlyamsmath-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "onlyamsmath-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "onlyamsmath-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "onlyamsmath-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "onlyamsmath-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "onlyamsmath-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "onlyamsmath-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "onlyamsmath-cmd", "score": 0.0063276692758974925}], "arsclassica": [{"caption": "\\spacedlowsmallcaps{}", "snippet": "\\spacedlowsmallcaps{$1}", "meta": "arsclassica-cmd", "score": 0.002677188251799468}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "arsclassica-cmd", "score": 0.005008938879210868}, {"caption": "\\spacedallcaps{}", "snippet": "\\spacedallcaps{$1}", "meta": "arsclassica-cmd", "score": 0.0015281000475958944}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "arsclassica-cmd", "score": 0.3277033727934986}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "arsclassica-cmd", "score": 0.1789117552185788}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.00037306820619479756}, {"caption": "\\specialrule{}{}{}", "snippet": "\\specialrule{$1}{$2}{$3}", "meta": "arsclassica-cmd", "score": 0.004974385202605165}, {"caption": "\\cmidrule", "snippet": "\\cmidrule", "meta": "arsclassica-cmd", "score": 0.01894952272365088}, {"caption": "\\cmidrule{}", "snippet": "\\cmidrule{$1}", "meta": "arsclassica-cmd", "score": 0.01894952272365088}, {"caption": "\\bottomrule", "snippet": "\\bottomrule", "meta": "arsclassica-cmd", "score": 0.04533364657852219}, {"caption": "\\midrule", "snippet": "\\midrule", "meta": "arsclassica-cmd", "score": 0.07098077735912875}, {"caption": "\\addlinespace", "snippet": "\\addlinespace", "meta": "arsclassica-cmd", "score": 0.005865460617491447}, {"caption": "\\addlinespace[]", "snippet": "\\addlinespace[$1]", "meta": "arsclassica-cmd", "score": 0.005865460617491447}, {"caption": "\\toprule", "snippet": "\\toprule", "meta": "arsclassica-cmd", "score": 0.059857788139528495}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "arsclassica-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "arsclassica-cmd", "score": 0.02900783226643065}, {"caption": "\\captionof{}{}", "snippet": "\\captionof{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.018348594199161503}, {"caption": "\\string", "snippet": "\\string", "meta": "arsclassica-cmd", "score": 0.001042697111754002}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "arsclassica-cmd", "score": 0.047007158741781095}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "arsclassica-cmd", "score": 0.00530510025314411}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "arsclassica-cmd", "score": 0.0030745841706804776}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "arsclassica-cmd", "score": 0.422097569591803}, {"caption": "\\csname", "snippet": "\\csname", "meta": "arsclassica-cmd", "score": 0.008565354665444157}, {"caption": "\\hspace{}", "snippet": "\\hspace{$1}", "meta": "arsclassica-cmd", "score": 0.3147206476372336}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "arsclassica-cmd", "score": 1.2569477427490174}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "arsclassica-cmd", "score": 1.897791904799601}, {"caption": "\\ContinuedFloat", "snippet": "\\ContinuedFloat", "meta": "arsclassica-cmd", "score": 5.806935368083486e-05}, {"caption": "\\noindent", "snippet": "\\noindent", "meta": "arsclassica-cmd", "score": 0.42355747798114207}, {"caption": "\\titleclass{}{}[]", "snippet": "\\titleclass{$1}{$2}[$3]", "meta": "arsclassica-cmd", "score": 0.00028979763314974667}, {"caption": "\\titlelabel{}", "snippet": "\\titlelabel{$1}", "meta": "arsclassica-cmd", "score": 6.40387839367932e-06}, {"caption": "\\thetitle", "snippet": "\\thetitle", "meta": "arsclassica-cmd", "score": 0.0015531478302713473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\titleformat{}{}{}{}{}[]", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}[$6]", "meta": "arsclassica-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}[]{}{}{}{}", "snippet": "\\titleformat{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "arsclassica-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}", "snippet": "\\titleformat{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.03475519439740096}, {"caption": "\\titleformat{}{}{}{}{}", "snippet": "\\titleformat{$1}{$2}{$3}{$4}{$5}", "meta": "arsclassica-cmd", "score": 0.03475519439740096}, {"caption": "\\titlespacing{}{}{}{}", "snippet": "\\titlespacing{$1}{$2}{$3}{$4}", "meta": "arsclassica-cmd", "score": 0.023062744385192156}, {"caption": "\\markboth{}{}", "snippet": "\\markboth{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.038323601301945065}, {"caption": "\\markboth{}", "snippet": "\\markboth{$1}", "meta": "arsclassica-cmd", "score": 0.038323601301945065}, {"caption": "\\markright{}", "snippet": "\\markright{$1}", "meta": "arsclassica-cmd", "score": 0.007138622674767024}, {"caption": "\\markright{}{}", "snippet": "\\markright{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.007138622674767024}, {"caption": "\\filleft", "snippet": "\\filleft", "meta": "arsclassica-cmd", "score": 7.959989906732799e-05}, {"caption": "\\filcenter", "snippet": "\\filcenter", "meta": "arsclassica-cmd", "score": 0.0004835660211260246}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "arsclassica-cmd", "score": 0.2253056071787701}, {"caption": "\\cleardoublepage", "snippet": "\\cleardoublepage", "meta": "arsclassica-cmd", "score": 0.044016804142963585}, {"caption": "\\csname", "snippet": "\\csname", "meta": "arsclassica-cmd", "score": 0.008565354665444157}, {"caption": "\\chaptertitlename", "snippet": "\\chaptertitlename", "meta": "arsclassica-cmd", "score": 0.0016985007766926272}, {"caption": "\\newpage", "snippet": "\\newpage", "meta": "arsclassica-cmd", "score": 0.3277033727934986}, {"caption": "\\filright", "snippet": "\\filright", "meta": "arsclassica-cmd", "score": 7.959989906732799e-05}, {"caption": "\\titlerule", "snippet": "\\titlerule", "meta": "arsclassica-cmd", "score": 0.019273712561461216}, {"caption": "\\titlerule[]{}", "snippet": "\\titlerule[$1]{$2}", "meta": "arsclassica-cmd", "score": 0.019273712561461216}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "arsclassica-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "arsclassica-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "arsclassica-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "arsclassica-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "arsclassica-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "arsclassica-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "arsclassica-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "arsclassica-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "arsclassica-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "arsclassica-cmd", "score": 0.021473212893597875}, {"caption": "\\marginpar{}", "snippet": "\\marginpar{$1}", "meta": "arsclassica-cmd", "score": 0.003400158497921723}, {"caption": "\\marginpar", "snippet": "\\marginpar", "meta": "arsclassica-cmd", "score": 0.003400158497921723}, {"caption": "\\cftsecleader", "snippet": "\\cftsecleader", "meta": "arsclassica-cmd", "score": 0.0011340882025681251}, {"caption": "\\cftsubsecleader", "snippet": "\\cftsubsecleader", "meta": "arsclassica-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\spacedlowsmallcaps{}", "snippet": "\\spacedlowsmallcaps{$1}", "meta": "arsclassica-cmd", "score": 0.002677188251799468}, {"caption": "\\sectionmark", "snippet": "\\sectionmark", "meta": "arsclassica-cmd", "score": 0.005008938879210868}, {"caption": "\\chaptermark", "snippet": "\\chaptermark", "meta": "arsclassica-cmd", "score": 0.005924520024686584}, {"caption": "\\chaptermark{}", "snippet": "\\chaptermark{$1}", "meta": "arsclassica-cmd", "score": 0.005924520024686584}, {"caption": "\\part{}", "snippet": "\\part{$1}", "meta": "arsclassica-cmd", "score": 0.022180129487444723}, {"caption": "\\tocEntry{}", "snippet": "\\tocEntry{$1}", "meta": "arsclassica-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\graffito{}", "snippet": "\\graffito{$1}", "meta": "arsclassica-cmd", "score": 1.1006799670632527e-05}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "arsclassica-cmd", "score": 0.422097569591803}, {"caption": "\\spacedallcaps{}", "snippet": "\\spacedallcaps{$1}", "meta": "arsclassica-cmd", "score": 0.0015281000475958944}, {"caption": "\\cftchapleader", "snippet": "\\cftchapleader", "meta": "arsclassica-cmd", "score": 1.0644172549700836e-05}, {"caption": "\\myVersion", "snippet": "\\myVersion", "meta": "arsclassica-cmd", "score": 0.00018029288638573757}, {"caption": "\\ctparttext{}", "snippet": "\\ctparttext{$1}", "meta": "arsclassica-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\addtokomafont{}{}", "snippet": "\\addtokomafont{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.0008555564394100388}, {"caption": "\\setkomafont{}{}", "snippet": "\\setkomafont{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.012985816912639263}, {"caption": "\\KOMAoptions{}", "snippet": "\\KOMAoptions{$1}", "meta": "arsclassica-cmd", "score": 0.000396664302361659}, {"caption": "\\cite{}", "snippet": "\\cite{$1}", "meta": "arsclassica-cmd", "score": 2.341195220791228}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "arsclassica-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "arsclassica-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "arsclassica-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "arsclassica-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "arsclassica-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "arsclassica-cmd", "score": 0.0018957469739775527}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "arsclassica-cmd", "score": 0.021170869458413965}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "arsclassica-cmd", "score": 0.00530510025314411}, {"caption": "\\lsstyle", "snippet": "\\lsstyle", "meta": "arsclassica-cmd", "score": 0.0023367519914345774}, {"caption": "\\space", "snippet": "\\space", "meta": "arsclassica-cmd", "score": 0.023010789853665694}, {"caption": "\\DisableLigatures[]{}", "snippet": "\\DisableLigatures[$1]{$2}", "meta": "arsclassica-cmd", "score": 0.0009805246614299932}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "arsclassica-cmd", "score": 0.00021116765384691477}], "blkarray": [{"caption": "\\small", "snippet": "\\small", "meta": "blkarray-cmd", "score": 0.2447632045426295}, {"caption": "\\small{}", "snippet": "\\small{$1}", "meta": "blkarray-cmd", "score": 0.2447632045426295}], "tkz-tab": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-tab-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-tab-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "tkz-tab-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "tkz-tab-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "tkz-tab-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-tab-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "tkz-tab-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-tab-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "tkz-tab-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "tkz-tab-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "tkz-tab-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "tkz-tab-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "tkz-tab-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "tkz-tab-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "tkz-tab-cmd", "score": 0.004719094298848707}, {"caption": "\\reserveinserts{}", "snippet": "\\reserveinserts{$1}", "meta": "tkz-tab-cmd", "score": 0.0018653410309739879}, {"caption": "\\newtoks", "snippet": "\\newtoks", "meta": "tkz-tab-cmd", "score": 0.00031058155311734754}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-tab-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "tkz-tab-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tkz-tab-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tkz-tab-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "tkz-tab-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tkz-tab-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "tkz-tab-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tkz-tab-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "tkz-tab-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "tkz-tab-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "tkz-tab-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "tkz-tab-cmd", "score": 0.2864294797053033}], "todo": [{"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "todo-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "todo-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "todo-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "todo-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "todo-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "todo-cmd", "score": 0.0006671850995492977}], "lcg": [{"caption": "\\rand", "snippet": "\\rand", "meta": "lcg-cmd", "score": 6.2350576842596716e-06}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "lcg-cmd", "score": 0.00037306820619479756}], "kantlipsum": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "kantlipsum-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "kantlipsum-cmd", "score": 0.2864294797053033}], "chappg": [{"caption": "\\pagenumbering{}", "snippet": "\\pagenumbering{$1}", "meta": "chappg-cmd", "score": 0.06731737633021802}], "chessboard": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "chessboard-cmd", "score": 0.00037306820619479756}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "chessboard-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "chessboard-cmd", "score": 0.009331077109224957}, {"caption": "\\setboardfontencoding{}", "snippet": "\\setboardfontencoding{$1}", "meta": "chessboard-cmd", "score": 0.00014668111964632249}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chessboard-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chessboard-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chessboard-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chessboard-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chessboard-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chessboard-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chessboard-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chessboard-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chessboard-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "chessboard-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "chessboard-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "chessboard-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "chessboard-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chessboard-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "chessboard-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "chessboard-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chessboard-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "chessboard-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chessboard-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chessboard-cmd", "score": 0.2864294797053033}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "chessboard-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "chessboard-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "chessboard-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chessboard-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "chessboard-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "chessboard-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "chessboard-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "chessboard-cmd", "score": 0.028955796305270766}, {"caption": "\\green", "snippet": "\\green", "meta": "chessboard-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "chessboard-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "chessboard-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "chessboard-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "chessboard-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "chessboard-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "chessboard-cmd", "score": 0.006520475264573554}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "chessboard-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "chessboard-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "chessboard-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "chessboard-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "chessboard-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "chessboard-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chessboard-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chessboard-cmd", "score": 0.008565354665444157}], "xskak": [{"caption": "\\mainline{}", "snippet": "\\mainline{$1}", "meta": "xskak-cmd", "score": 0.0010267678375242572}, {"caption": "\\newchessgame", "snippet": "\\newchessgame", "meta": "xskak-cmd", "score": 0.000880086717877935}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "xskak-cmd", "score": 0.00037306820619479756}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "xskak-cmd", "score": 0.01590723355124104}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "xskak-cmd", "score": 0.009331077109224957}, {"caption": "\\setboardfontencoding{}", "snippet": "\\setboardfontencoding{$1}", "meta": "xskak-cmd", "score": 0.00014668111964632249}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "xskak-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "xskak-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "xskak-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "xskak-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xskak-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "xskak-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xskak-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "xskak-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "xskak-cmd", "score": 0.004649150613625593}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "xskak-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "xskak-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "xskak-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "xskak-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xskak-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "xskak-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "xskak-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xskak-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "xskak-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xskak-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xskak-cmd", "score": 0.2864294797053033}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "xskak-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "xskak-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "xskak-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xskak-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "xskak-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "xskak-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "xskak-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "xskak-cmd", "score": 0.028955796305270766}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "xskak-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "xskak-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "xskak-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "xskak-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "xskak-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "xskak-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xskak-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "xskak-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "xskak-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "xskak-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "xskak-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "xskak-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "xskak-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "xskak-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "xskak-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "xskak-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "xskak-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "xskak-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "xskak-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "xskak-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xskak-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "xskak-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "xskak-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "xskak-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "xskak-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xskak-cmd", "score": 0.008565354665444157}, {"caption": "\\green", "snippet": "\\green", "meta": "xskak-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "xskak-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "xskak-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "xskak-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "xskak-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "xskak-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "xskak-cmd", "score": 0.006520475264573554}], "pgfheaps": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfheaps-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfheaps-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfheaps-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfheaps-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfheaps-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfheaps-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfheaps-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfheaps-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfheaps-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfheaps-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfheaps-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfheaps-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfheaps-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfheaps-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfheaps-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfheaps-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfheaps-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfheaps-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfheaps-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfheaps-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfheaps-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfheaps-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfheaps-cmd", "score": 0.2864294797053033}], "pgfshade": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfshade-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfshade-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "pgfshade-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "pgfshade-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "pgfshade-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfshade-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "pgfshade-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfshade-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "pgfshade-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "pgfshade-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "pgfshade-cmd", "score": 0.004719094298848707}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfshade-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "pgfshade-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pgfshade-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pgfshade-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "pgfshade-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pgfshade-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "pgfshade-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pgfshade-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "pgfshade-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "pgfshade-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "pgfshade-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "pgfshade-cmd", "score": 0.2864294797053033}], "showframe": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "showframe-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "showframe-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "showframe-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "showframe-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "showframe-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "showframe-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "showframe-cmd", "score": 0.008565354665444157}, {"caption": "\\AddToShipoutPictureFG{}", "snippet": "\\AddToShipoutPictureFG{$1}", "meta": "showframe-cmd", "score": 0.000325977535138643}, {"caption": "\\AddToShipoutPictureBG{}", "snippet": "\\AddToShipoutPictureBG{$1}", "meta": "showframe-cmd", "score": 0.0008957666085644653}, {"caption": "\\AtPageUpperLeft{}", "snippet": "\\AtPageUpperLeft{$1}", "meta": "showframe-cmd", "score": 0.0003608141410278152}, {"caption": "\\LenToUnit{}", "snippet": "\\LenToUnit{$1}", "meta": "showframe-cmd", "score": 0.0007216282820556304}, {"caption": "\\AddToShipoutPicture{}", "snippet": "\\AddToShipoutPicture{$1}", "meta": "showframe-cmd", "score": 0.0017658629469099734}], "psvectorian": [{"caption": "\\csname", "snippet": "\\csname", "meta": "psvectorian-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "psvectorian-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "psvectorian-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "psvectorian-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "psvectorian-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "psvectorian-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "psvectorian-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "psvectorian-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "psvectorian-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "psvectorian-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "psvectorian-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "psvectorian-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "psvectorian-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "psvectorian-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "psvectorian-cmd", "score": 0.004719094298848707}, {"caption": "\\green", "snippet": "\\green", "meta": "psvectorian-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "psvectorian-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "psvectorian-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "psvectorian-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "psvectorian-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "psvectorian-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "psvectorian-cmd", "score": 0.006520475264573554}], "pst-grad": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-grad-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-grad-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-grad-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-grad-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-grad-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-grad-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-grad-cmd", "score": 0.006520475264573554}], "cool": [{"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "cool-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "cool-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "cool-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "cool-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "cool-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "cool-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "cool-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "cool-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "cool-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "cool-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "cool-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "cool-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "cool-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "cool-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "cool-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "cool-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "cool-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "cool-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "cool-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "cool-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "cool-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "cool-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "cool-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "cool-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "cool-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "cool-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "cool-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "cool-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "cool-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "cool-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "cool-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "cool-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "cool-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "cool-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "cool-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "cool-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "cool-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "cool-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "cool-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "cool-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "cool-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "cool-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "cool-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "cool-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "cool-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "cool-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "cool-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "cool-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "cool-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "cool-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "cool-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "cool-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "cool-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "cool-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "cool-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "cool-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "cool-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "cool-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "cool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "cool-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "cool-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "cool-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "cool-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "cool-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "cool-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "cool-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "cool-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "cool-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "cool-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "cool-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "cool-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "cool-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "cool-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "cool-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "cool-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "cool-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "cool-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "cool-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "cool-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "cool-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "cool-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "cool-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "cool-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "cool-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "cool-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "cool-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "cool-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "cool-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "cool-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "cool-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "cool-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "cool-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "cool-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "cool-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "cool-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "cool-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "cool-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "cool-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "cool-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "cool-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "cool-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "cool-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "cool-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "cool-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "cool-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "cool-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "cool-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "cool-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "cool-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "cool-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "cool-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "cool-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "cool-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "cool-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "cool-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "cool-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "cool-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "cool-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "cool-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "cool-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "cool-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "cool-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "cool-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "cool-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "cool-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "cool-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "cool-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "cool-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "cool-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "cool-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "cool-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "cool-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "cool-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "cool-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "cool-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "cool-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "cool-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "cool-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "cool-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "cool-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "cool-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "cool-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "cool-cmd", "score": 0.0004286136584068833}, {"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "cool-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "cool-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "cool-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "cool-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "cool-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "cool-cmd", "score": 0.0006671850995492977}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "cool-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "cool-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "cool-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "cool-cmd", "score": 0.008565354665444157}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "cool-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "cool-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "cool-cmd", "score": 0.18137737738638837}, {"caption": "\\forloop{}{}{}{}", "snippet": "\\forloop{$1}{$2}{$3}{$4}", "meta": "cool-cmd", "score": 0.00029867998381154486}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "cool-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "cool-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "cool-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "cool-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "cool-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "cool-cmd", "score": 0.0018957469739775527}, {"caption": "\\do", "snippet": "\\do", "meta": "cool-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "cool-cmd", "score": 0.0063276692758974925}], "xassoccnt": [{"caption": "\\NewTotalDocumentCounter{}", "snippet": "\\NewTotalDocumentCounter{$1}", "meta": "xassoccnt-cmd", "score": 1.5075186740106946e-05}, {"caption": "\\DeclareAssociatedCounters{}{}", "snippet": "\\DeclareAssociatedCounters{$1}{$2}", "meta": "xassoccnt-cmd", "score": 1.5075186740106946e-05}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xassoccnt-cmd", "score": 0.008565354665444157}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "xassoccnt-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "xassoccnt-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "xassoccnt-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "xassoccnt-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "xassoccnt-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "xassoccnt-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "xassoccnt-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "xassoccnt-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "xassoccnt-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "xassoccnt-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "xassoccnt-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xassoccnt-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "xassoccnt-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "xassoccnt-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "xassoccnt-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xassoccnt-cmd", "score": 0.008565354665444157}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xassoccnt-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xassoccnt-cmd", "score": 0.2864294797053033}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "xassoccnt-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xassoccnt-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xassoccnt-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "xassoccnt-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "xassoccnt-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "xassoccnt-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "xassoccnt-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "xassoccnt-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "xassoccnt-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "xassoccnt-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "xassoccnt-cmd", "score": 0.2864294797053033}], "chemscheme": [{"caption": "\\csname", "snippet": "\\csname", "meta": "chemscheme-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "chemscheme-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemscheme-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemscheme-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemscheme-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemscheme-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chemscheme-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chemscheme-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chemscheme-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chemscheme-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chemscheme-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemscheme-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chemscheme-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemscheme-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chemscheme-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chemscheme-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chemscheme-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chemscheme-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chemscheme-cmd", "score": 0.004649150613625593}, {"caption": "\\empty", "snippet": "\\empty", "meta": "chemscheme-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chemscheme-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemscheme-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chemscheme-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "chemscheme-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chemscheme-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chemscheme-cmd", "score": 0.021170869458413965}], "pst-all": [{"caption": "\\green", "snippet": "\\green", "meta": "pst-all-cmd", "score": 0.0016005722621532548}, {"caption": "\\green{}", "snippet": "\\green{$1}", "meta": "pst-all-cmd", "score": 0.0016005722621532548}, {"caption": "\\documentclass[]{}", "snippet": "\\documentclass[$1]{$2}", "meta": "pst-all-cmd", "score": 1.4425339817971206}, {"caption": "\\documentclass{}", "snippet": "\\documentclass{$1}", "meta": "pst-all-cmd", "score": 1.4425339817971206}, {"caption": "\\gray", "snippet": "\\gray", "meta": "pst-all-cmd", "score": 0.0005786730478266738}, {"caption": "\\red{}", "snippet": "\\red{$1}", "meta": "pst-all-cmd", "score": 0.006520475264573554}, {"caption": "\\red", "snippet": "\\red", "meta": "pst-all-cmd", "score": 0.006520475264573554}], "regexpatch": [{"caption": "\\xpatchcmd{}{}{}{}{}", "snippet": "\\xpatchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "regexpatch-cmd", "score": 0.0019344877752147675}, {"caption": "\\xpatchcmd", "snippet": "\\xpatchcmd", "meta": "regexpatch-cmd", "score": 0.0019344877752147675}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "regexpatch-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "regexpatch-cmd", "score": 0.2864294797053033}], "chronosys": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "chronosys-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronosys-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chronosys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chronosys-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chronosys-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chronosys-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chronosys-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chronosys-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chronosys-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chronosys-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chronosys-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronosys-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chronosys-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chronosys-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chronosys-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "chronosys-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chronosys-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chronosys-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "chronosys-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "chronosys-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "chronosys-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "chronosys-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "chronosys-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chronosys-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "chronosys-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "chronosys-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronosys-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "chronosys-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "chronosys-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chronosys-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chronosys-cmd", "score": 0.2864294797053033}], "newfloat": [{"caption": "\\DeclareFloatingEnvironment[]{}", "snippet": "\\DeclareFloatingEnvironment[$1]{$2}", "meta": "newfloat-cmd", "score": 2.603029874713569e-05}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "newfloat-cmd", "score": 0.00037306820619479756}], "zref": [{"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "zref-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "zref-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "zref-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "zref-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "zref-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "zref-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "zref-cmd", "score": 0.002958865219480927}], "bmpsize": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "bmpsize-cmd", "score": 0.00037306820619479756}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bmpsize-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bmpsize-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "bmpsize-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "bmpsize-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "bmpsize-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "bmpsize-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "bmpsize-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bmpsize-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "bmpsize-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bmpsize-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "bmpsize-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "bmpsize-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "bmpsize-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "bmpsize-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "bmpsize-cmd", "score": 0.004649150613625593}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bmpsize-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bmpsize-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "bmpsize-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "bmpsize-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "bmpsize-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bmpsize-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bmpsize-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bmpsize-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bmpsize-cmd", "score": 0.021170869458413965}], "steinmetz": [{"caption": "\\Line", "snippet": "\\Line", "meta": "steinmetz-cmd", "score": 0.0006078790177929149}, {"caption": "\\polygon", "snippet": "\\polygon", "meta": "steinmetz-cmd", "score": 0.0008987552240147395}, {"caption": "\\line", "snippet": "\\line", "meta": "steinmetz-cmd", "score": 0.014519741542622297}, {"caption": "\\polyline", "snippet": "\\polyline", "meta": "steinmetz-cmd", "score": 0.00022468880600368487}, {"caption": "\\vector", "snippet": "\\vector", "meta": "steinmetz-cmd", "score": 0.002970308722584179}], "pageslts": [{"caption": "\\thepage", "snippet": "\\thepage", "meta": "pageslts-cmd", "score": 0.0591555998103519}, {"caption": "\\pagenumbering{}", "snippet": "\\pagenumbering{$1}", "meta": "pageslts-cmd", "score": 0.06731737633021802}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "pageslts-cmd", "score": 0.1789117552185788}, {"caption": "\\global", "snippet": "\\global", "meta": "pageslts-cmd", "score": 0.006609629561859019}, {"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "pageslts-cmd", "score": 0.010304996748556729}, {"caption": "\\index{}", "snippet": "\\index{$1}", "meta": "pageslts-cmd", "score": 0.013774721817648336}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pageslts-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "pageslts-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "pageslts-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pageslts-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pageslts-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pageslts-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pageslts-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pageslts-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pageslts-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pageslts-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pageslts-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pageslts-cmd", "score": 0.008565354665444157}], "chronology": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "chronology-cmd", "score": 0.00037306820619479756}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "chronology-cmd", "score": 0.010241823778997489}, {"caption": "\\setlength{}{}", "snippet": "\\setlength{$1}{$2}", "meta": "chronology-cmd", "score": 0.354445763583904}, {"caption": "\\setlength", "snippet": "\\setlength", "meta": "chronology-cmd", "score": 0.354445763583904}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "chronology-cmd", "score": 0.0030745841706804776}, {"caption": "\\setcounter{}{}", "snippet": "\\setcounter{$1}{$2}", "meta": "chronology-cmd", "score": 0.10068045662118841}, {"caption": "\\addtolength{}{}", "snippet": "\\addtolength{$1}{$2}", "meta": "chronology-cmd", "score": 0.028955796305270766}, {"caption": "\\addtolength", "snippet": "\\addtolength", "meta": "chronology-cmd", "score": 0.028955796305270766}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronology-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "chronology-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "chronology-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "chronology-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "chronology-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "chronology-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chronology-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "chronology-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronology-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "chronology-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "chronology-cmd", "score": 0.004649150613625593}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "chronology-cmd", "score": 0.004719094298848707}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chronology-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chronology-cmd", "score": 0.2864294797053033}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "chronology-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "chronology-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "chronology-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "chronology-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "chronology-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "chronology-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "chronology-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "chronology-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "chronology-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "chronology-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "chronology-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "chronology-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "chronology-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "chronology-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "chronology-cmd", "score": 0.2864294797053033}], "spreadtab": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "spreadtab-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "spreadtab-cmd", "score": 0.021170869458413965}], "algpascal": [{"caption": "\\algrenewcommand", "snippet": "\\algrenewcommand", "meta": "algpascal-cmd", "score": 0.0019861803661869416}, {"caption": "\\Statex", "snippet": "\\Statex", "meta": "algpascal-cmd", "score": 0.008622777195102994}, {"caption": "\\BState{}", "snippet": "\\BState{$1}", "meta": "algpascal-cmd", "score": 0.0008685861525307122}, {"caption": "\\BState", "snippet": "\\BState", "meta": "algpascal-cmd", "score": 0.0008685861525307122}, {"caption": "\\algloopdefx{}[][]{}", "snippet": "\\algloopdefx{$1}[$2][$3]{$4}", "meta": "algpascal-cmd", "score": 0.00025315185701145097}, {"caption": "\\algnewcommand", "snippet": "\\algnewcommand", "meta": "algpascal-cmd", "score": 0.0030209395012065327}, {"caption": "\\algnewcommand{}[]{}", "snippet": "\\algnewcommand{$1}[$2]{$3}", "meta": "algpascal-cmd", "score": 0.0030209395012065327}, {"caption": "\\Comment{}", "snippet": "\\Comment{$1}", "meta": "algpascal-cmd", "score": 0.005178604573219454}, {"caption": "\\algblockdefx{}{}[]", "snippet": "\\algblockdefx{$1}{$2}[$3]", "meta": "algpascal-cmd", "score": 0.00025315185701145097}, {"caption": "\\algrenewtext{}{}", "snippet": "\\algrenewtext{$1}{$2}", "meta": "algpascal-cmd", "score": 0.0024415580558825975}, {"caption": "\\algrenewtext{}[]{}", "snippet": "\\algrenewtext{$1}[$2]{$3}", "meta": "algpascal-cmd", "score": 0.0024415580558825975}, {"caption": "\\algblock{}{}", "snippet": "\\algblock{$1}{$2}", "meta": "algpascal-cmd", "score": 0.0007916858220314837}, {"caption": "\\csname", "snippet": "\\csname", "meta": "algpascal-cmd", "score": 0.008565354665444157}, {"caption": "\\algdef{}[]{}{}{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}{$5}{$6}", "meta": "algpascal-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}{}[]{}{}", "snippet": "\\algdef{$1}[$2]{$3}{$4}[$5]{$6}{$7}", "meta": "algpascal-cmd", "score": 0.0003102486920966127}, {"caption": "\\algdef{}[]{}[]{}", "snippet": "\\algdef{$1}[$2]{$3}[$4]{$5}", "meta": "algpascal-cmd", "score": 0.0003102486920966127}, {"caption": "\\algtext{}", "snippet": "\\algtext{$1}", "meta": "algpascal-cmd", "score": 0.0005463612015579842}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "algpascal-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "algpascal-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "algpascal-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "algpascal-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "algpascal-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "algpascal-cmd", "score": 0.0018957469739775527}], "cabin": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "cabin-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "cabin-cmd", "score": 0.008565354665444157}], "erewhon": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "erewhon-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "erewhon-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "erewhon-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "erewhon-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "erewhon-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "erewhon-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "erewhon-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "erewhon-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "erewhon-cmd", "score": 0.0018957469739775527}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "erewhon-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "erewhon-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "erewhon-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "erewhon-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "erewhon-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "erewhon-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "erewhon-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "erewhon-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "erewhon-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "erewhon-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "erewhon-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "erewhon-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "erewhon-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "erewhon-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "erewhon-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "erewhon-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "erewhon-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "erewhon-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "erewhon-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "erewhon-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "erewhon-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "erewhon-cmd", "score": 0.008565354665444157}], "tgcursor": [{"caption": "\\empty", "snippet": "\\empty", "meta": "tgcursor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgcursor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgcursor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgcursor-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "tgcursor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgcursor-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "tgcursor-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "tgcursor-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "tgcursor-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "tgcursor-cmd", "score": 0.021170869458413965}], "ifvtex": [{"caption": "\\csname", "snippet": "\\csname", "meta": "ifvtex-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "ifvtex-cmd", "score": 0.002958865219480927}], "memhfixc": [{"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "memhfixc-cmd", "score": 1.2569477427490174}], "longfigure": [{"caption": "\\newpage", "snippet": "\\newpage", "meta": "longfigure-cmd", "score": 0.3277033727934986}], "lato": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "lato-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "lato-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "lato-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "lato-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "lato-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "lato-cmd", "score": 0.0018957469739775527}, {"caption": "\\scshape", "snippet": "\\scshape", "meta": "lato-cmd", "score": 0.05364108855914402}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "lato-cmd", "score": 0.00037306820619479756}], "authoraftertitle": [{"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "authoraftertitle-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "authoraftertitle-cmd", "score": 0.8973590434087177}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "authoraftertitle-cmd", "score": 0.9202908262245683}], "listofsymbols": [{"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "listofsymbols-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "listofsymbols-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "listofsymbols-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "listofsymbols-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "listofsymbols-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "listofsymbols-cmd", "score": 0.0018957469739775527}], "hvfloat": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hvfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "hvfloat-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "hvfloat-cmd", "score": 0.02900783226643065}, {"caption": "\\captionof{}{}", "snippet": "\\captionof{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.018348594199161503}, {"caption": "\\string", "snippet": "\\string", "meta": "hvfloat-cmd", "score": 0.001042697111754002}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "hvfloat-cmd", "score": 0.047007158741781095}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hvfloat-cmd", "score": 0.00530510025314411}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "hvfloat-cmd", "score": 0.0030745841706804776}, {"caption": "\\chapter{}", "snippet": "\\chapter{$1}", "meta": "hvfloat-cmd", "score": 0.422097569591803}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hvfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\hspace{}", "snippet": "\\hspace{$1}", "meta": "hvfloat-cmd", "score": 0.3147206476372336}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "hvfloat-cmd", "score": 1.2569477427490174}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "hvfloat-cmd", "score": 1.897791904799601}, {"caption": "\\ContinuedFloat", "snippet": "\\ContinuedFloat", "meta": "hvfloat-cmd", "score": 5.806935368083486e-05}, {"caption": "\\noindent", "snippet": "\\noindent", "meta": "hvfloat-cmd", "score": 0.42355747798114207}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hvfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hvfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "hvfloat-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "hvfloat-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "hvfloat-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "hvfloat-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hvfloat-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "hvfloat-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hvfloat-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "hvfloat-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "hvfloat-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "hvfloat-cmd", "score": 0.004649150613625593}, {"caption": "\\DeclareCaptionJustification{}{}", "snippet": "\\DeclareCaptionJustification{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.0001872850414971473}, {"caption": "\\DeclareCaptionLabelSeparator{}{}", "snippet": "\\DeclareCaptionLabelSeparator{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.0003890810058478364}, {"caption": "\\DeclareCaptionFormat{}{}", "snippet": "\\DeclareCaptionFormat{$1}{$2}", "meta": "hvfloat-cmd", "score": 0.0004717618449370015}, {"caption": "\\DeclareCaptionFont{}{}", "snippet": "\\DeclareCaptionFont{$1}{$2}", "meta": "hvfloat-cmd", "score": 5.0133404990680195e-05}, {"caption": "\\DeclareCaptionSubType[]{}", "snippet": "\\DeclareCaptionSubType[$1]{$2}", "meta": "hvfloat-cmd", "score": 0.0001872850414971473}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "hvfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "hvfloat-cmd", "score": 0.021170869458413965}, {"caption": "\\captionsetup{}", "snippet": "\\captionsetup{$1}", "meta": "hvfloat-cmd", "score": 0.02900783226643065}, {"caption": "\\captionsetup[]{}", "snippet": "\\captionsetup[$1]{$2}", "meta": "hvfloat-cmd", "score": 0.02900783226643065}, {"caption": "\\string", "snippet": "\\string", "meta": "hvfloat-cmd", "score": 0.001042697111754002}, {"caption": "\\DeclareCaptionType{}[][]", "snippet": "\\DeclareCaptionType{$1}[$2][$3]", "meta": "hvfloat-cmd", "score": 0.00015256647321237863}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hvfloat-cmd", "score": 0.00530510025314411}, {"caption": "\\footnote{}", "snippet": "\\footnote{$1}", "meta": "hvfloat-cmd", "score": 0.2253056071787701}, {"caption": "\\footnotemark[]", "snippet": "\\footnotemark[$1]", "meta": "hvfloat-cmd", "score": 0.021473212893597875}, {"caption": "\\footnotemark", "snippet": "\\footnotemark", "meta": "hvfloat-cmd", "score": 0.021473212893597875}], "thmbox": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "thmbox-cmd", "score": 0.00037306820619479756}], "proba": [{"caption": "\\frak{}", "snippet": "\\frak{$1}", "meta": "proba-cmd", "score": 0.0017966000518546787}, {"caption": "\\checkmark", "snippet": "\\checkmark", "meta": "proba-cmd", "score": 0.025060530944368123}, {"caption": "\\bold", "snippet": "\\bold", "meta": "proba-cmd", "score": 0.0014358547624941567}, {"caption": "\\bold{}", "snippet": "\\bold{$1}", "meta": "proba-cmd", "score": 0.0014358547624941567}, {"caption": "\\Bbb{}", "snippet": "\\Bbb{$1}", "meta": "proba-cmd", "score": 0.0006671850995492977}, {"caption": "\\Bbb", "snippet": "\\Bbb", "meta": "proba-cmd", "score": 0.0006671850995492977}], "datatool": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "datatool-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "datatool-cmd", "score": 0.021170869458413965}, {"caption": "\\longmapsto", "snippet": "\\longmapsto", "meta": "datatool-cmd", "score": 0.0017755897148012264}, {"caption": "\\Check{}", "snippet": "\\Check{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "datatool-cmd", "score": 0.006963729684667191}, {"caption": "\\do", "snippet": "\\do", "meta": "datatool-cmd", "score": 0.009278344180101056}, {"caption": "\\iff", "snippet": "\\iff", "meta": "datatool-cmd", "score": 0.004209937150980285}, {"caption": "\\And", "snippet": "\\And", "meta": "datatool-cmd", "score": 0.0011582952152188854}, {"caption": "\\And{}", "snippet": "\\And{$1}", "meta": "datatool-cmd", "score": 0.0011582952152188854}, {"caption": "\\oint", "snippet": "\\oint", "meta": "datatool-cmd", "score": 0.0028650540724050534}, {"caption": "\\boxed{}", "snippet": "\\boxed{$1}", "meta": "datatool-cmd", "score": 0.0035536135737312827}, {"caption": "\\Ddot{}", "snippet": "\\Ddot{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ignorespacesafterend", "snippet": "\\ignorespacesafterend", "meta": "datatool-cmd", "score": 0.0010893680553454854}, {"caption": "\\nonumber", "snippet": "\\nonumber", "meta": "datatool-cmd", "score": 0.051980653969641216}, {"caption": "\\Breve{}", "snippet": "\\Breve{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\mapsto", "snippet": "\\mapsto", "meta": "datatool-cmd", "score": 0.006473769486518971}, {"caption": "\\over{}", "snippet": "\\over{$1}", "meta": "datatool-cmd", "score": 0.0054372322008878786}, {"caption": "\\over", "snippet": "\\over", "meta": "datatool-cmd", "score": 0.0054372322008878786}, {"caption": "\\bigotimes", "snippet": "\\bigotimes", "meta": "datatool-cmd", "score": 0.000984722260624791}, {"caption": "\\bigoplus", "snippet": "\\bigoplus", "meta": "datatool-cmd", "score": 0.0011508785476242003}, {"caption": "\\theequation", "snippet": "\\theequation", "meta": "datatool-cmd", "score": 0.002995924112493351}, {"caption": "\\bigcap", "snippet": "\\bigcap", "meta": "datatool-cmd", "score": 0.005709261168797874}, {"caption": "\\xrightarrow{}", "snippet": "\\xrightarrow{$1}", "meta": "datatool-cmd", "score": 0.004163642482777231}, {"caption": "\\xrightarrow[]{}", "snippet": "\\xrightarrow[$1]{$2}", "meta": "datatool-cmd", "score": 0.004163642482777231}, {"caption": "\\atop", "snippet": "\\atop", "meta": "datatool-cmd", "score": 0.0006518541515279979}, {"caption": "\\dfrac{}{}", "snippet": "\\dfrac{$1}{$2}", "meta": "datatool-cmd", "score": 0.05397545277891961}, {"caption": "\\pmod", "snippet": "\\pmod", "meta": "datatool-cmd", "score": 0.0011773327219377148}, {"caption": "\\pmod{}", "snippet": "\\pmod{$1}", "meta": "datatool-cmd", "score": 0.0011773327219377148}, {"caption": "\\notag", "snippet": "\\notag", "meta": "datatool-cmd", "score": 0.00322520920930312}, {"caption": "\\int", "snippet": "\\int", "meta": "datatool-cmd", "score": 0.11946660537765894}, {"caption": "\\Vec{}", "snippet": "\\Vec{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\bigvee", "snippet": "\\bigvee", "meta": "datatool-cmd", "score": 0.0011677288242806726}, {"caption": "\\sum", "snippet": "\\sum", "meta": "datatool-cmd", "score": 0.42607994509619934}, {"caption": "\\hookrightarrow", "snippet": "\\hookrightarrow", "meta": "datatool-cmd", "score": 0.0015607282046545064}, {"caption": "\\bigsqcup", "snippet": "\\bigsqcup", "meta": "datatool-cmd", "score": 0.0003468284144579442}, {"caption": "\\hookleftarrow", "snippet": "\\hookleftarrow", "meta": "datatool-cmd", "score": 0.0016498799924012809}, {"caption": "\\Dot{}", "snippet": "\\Dot{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\dots", "snippet": "\\dots", "meta": "datatool-cmd", "score": 0.0847414497955395}, {"caption": "\\genfrac{}{}{}{}{}{}", "snippet": "\\genfrac{$1}{$2}{$3}{$4}{$5}{$6}", "meta": "datatool-cmd", "score": 0.004820143328295316}, {"caption": "\\genfrac", "snippet": "\\genfrac", "meta": "datatool-cmd", "score": 0.004820143328295316}, {"caption": "\\cfrac{}{}", "snippet": "\\cfrac{$1}{$2}", "meta": "datatool-cmd", "score": 0.006765684097139381}, {"caption": "\\Acute{}", "snippet": "\\Acute{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\ldots", "snippet": "\\ldots", "meta": "datatool-cmd", "score": 0.11585556755884258}, {"caption": "\\coprod", "snippet": "\\coprod", "meta": "datatool-cmd", "score": 0.00011383372700282614}, {"caption": "\\impliedby", "snippet": "\\impliedby", "meta": "datatool-cmd", "score": 2.3482915591834053e-05}, {"caption": "\\big", "snippet": "\\big", "meta": "datatool-cmd", "score": 0.05613164277964739}, {"caption": "\\idotsint", "snippet": "\\idotsint", "meta": "datatool-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\Longrightarrow", "snippet": "\\Longrightarrow", "meta": "datatool-cmd", "score": 0.002459139437356601}, {"caption": "\\allowdisplaybreaks", "snippet": "\\allowdisplaybreaks", "meta": "datatool-cmd", "score": 0.005931777024772073}, {"caption": "\\eqref{}", "snippet": "\\eqref{$1}", "meta": "datatool-cmd", "score": 0.06345266254167037}, {"caption": "\\mod", "snippet": "\\mod", "meta": "datatool-cmd", "score": 0.0015181439193121889}, {"caption": "\\mod{}", "snippet": "\\mod{$1}", "meta": "datatool-cmd", "score": 0.0015181439193121889}, {"caption": "\\arraystretch", "snippet": "\\arraystretch", "meta": "datatool-cmd", "score": 0.022224283488673075}, {"caption": "\\arraystretch{}", "snippet": "\\arraystretch{$1}", "meta": "datatool-cmd", "score": 0.022224283488673075}, {"caption": "\\bigg", "snippet": "\\bigg", "meta": "datatool-cmd", "score": 0.04318078602869565}, {"caption": "\\underset{}{}", "snippet": "\\underset{$1}{$2}", "meta": "datatool-cmd", "score": 0.012799893214578391}, {"caption": "\\dotsc", "snippet": "\\dotsc", "meta": "datatool-cmd", "score": 0.0008555101484119994}, {"caption": "\\doteq", "snippet": "\\doteq", "meta": "datatool-cmd", "score": 3.164631070474435e-05}, {"caption": "\\leftroot{}", "snippet": "\\leftroot{$1}", "meta": "datatool-cmd", "score": 6.625561928497235e-05}, {"caption": "\\substack{}", "snippet": "\\substack{$1}", "meta": "datatool-cmd", "score": 0.0037482529712850755}, {"caption": "\\Hat{}", "snippet": "\\Hat{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\frac{}{}", "snippet": "\\frac{$1}{$2}", "meta": "datatool-cmd", "score": 1.4341091141105058}, {"caption": "\\mspace{}", "snippet": "\\mspace{$1}", "meta": "datatool-cmd", "score": 3.423236656565836e-05}, {"caption": "\\Bar{}", "snippet": "\\Bar{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\Grave{}", "snippet": "\\Grave{$1}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\implies", "snippet": "\\implies", "meta": "datatool-cmd", "score": 0.021828316911576096}, {"caption": "\\tbinom", "snippet": "\\tbinom", "meta": "datatool-cmd", "score": 1.3908704929884828e-05}, {"caption": "\\dotsi", "snippet": "\\dotsi", "meta": "datatool-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\bigwedge", "snippet": "\\bigwedge", "meta": "datatool-cmd", "score": 0.000347742918592393}, {"caption": "\\sideset{}{}", "snippet": "\\sideset{$1}{$2}", "meta": "datatool-cmd", "score": 5.563481971953931e-05}, {"caption": "\\smash{}", "snippet": "\\smash{$1}", "meta": "datatool-cmd", "score": 0.008197171096663127}, {"caption": "\\smash[]{}", "snippet": "\\smash[$1]{$2}", "meta": "datatool-cmd", "score": 0.008197171096663127}, {"caption": "\\colon", "snippet": "\\colon", "meta": "datatool-cmd", "score": 0.005300291684408929}, {"caption": "\\intertext{}", "snippet": "\\intertext{$1}", "meta": "datatool-cmd", "score": 0.0016148076375871775}, {"caption": "\\Longleftarrow", "snippet": "\\Longleftarrow", "meta": "datatool-cmd", "score": 8.477207854183949e-05}, {"caption": "\\prod", "snippet": "\\prod", "meta": "datatool-cmd", "score": 0.02549889375975901}, {"caption": "\\AmS", "snippet": "\\AmS", "meta": "datatool-cmd", "score": 0.00047859486202980376}, {"caption": "\\overline{}", "snippet": "\\overline{$1}", "meta": "datatool-cmd", "score": 0.11280487530505384}, {"caption": "\\tfrac{}{}", "snippet": "\\tfrac{$1}{$2}", "meta": "datatool-cmd", "score": 0.0005923542426657187}, {"caption": "\\uproot{}", "snippet": "\\uproot{$1}", "meta": "datatool-cmd", "score": 6.625561928497235e-05}, {"caption": "\\bmod", "snippet": "\\bmod", "meta": "datatool-cmd", "score": 0.002022594681005002}, {"caption": "\\bmod{}", "snippet": "\\bmod{$1}", "meta": "datatool-cmd", "score": 0.002022594681005002}, {"caption": "\\pod{}", "snippet": "\\pod{$1}", "meta": "datatool-cmd", "score": 2.7817409859769657e-05}, {"caption": "\\label{}", "snippet": "\\label{$1}", "meta": "datatool-cmd", "score": 1.897791904799601}, {"caption": "\\longrightarrow", "snippet": "\\longrightarrow", "meta": "datatool-cmd", "score": 0.013399422292458848}, {"caption": "\\xleftarrow[]{}", "snippet": "\\xleftarrow[$1]{$2}", "meta": "datatool-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\xleftarrow{}", "snippet": "\\xleftarrow{$1}", "meta": "datatool-cmd", "score": 3.5779964196240445e-05}, {"caption": "\\mathaccentV", "snippet": "\\mathaccentV", "meta": "datatool-cmd", "score": 6.216218551413489e-05}, {"caption": "\\hdotsfor{}", "snippet": "\\hdotsfor{$1}", "meta": "datatool-cmd", "score": 0.00024247684499275043}, {"caption": "\\hdotsfor[]{}", "snippet": "\\hdotsfor[$1]{$2}", "meta": "datatool-cmd", "score": 0.00024247684499275043}, {"caption": "\\Bigg", "snippet": "\\Bigg", "meta": "datatool-cmd", "score": 0.015507614799858266}, {"caption": "\\Bigg[]", "snippet": "\\Bigg[$1]", "meta": "datatool-cmd", "score": 0.015507614799858266}, {"caption": "\\overset{}{}", "snippet": "\\overset{$1}{$2}", "meta": "datatool-cmd", "score": 0.007611544955294224}, {"caption": "\\Big", "snippet": "\\Big", "meta": "datatool-cmd", "score": 0.050370758781422345}, {"caption": "\\longleftrightarrow", "snippet": "\\longleftrightarrow", "meta": "datatool-cmd", "score": 0.0002851769278703356}, {"caption": "\\Longleftrightarrow", "snippet": "\\Longleftrightarrow", "meta": "datatool-cmd", "score": 0.0004896780659212191}, {"caption": "\\Longleftrightarrow{}", "snippet": "\\Longleftrightarrow{$1}", "meta": "datatool-cmd", "score": 0.0004896780659212191}, {"caption": "\\binom{}{}", "snippet": "\\binom{$1}{$2}", "meta": "datatool-cmd", "score": 0.013010882180364367}, {"caption": "\\longleftarrow", "snippet": "\\longleftarrow", "meta": "datatool-cmd", "score": 0.0011096532692473691}, {"caption": "\\dbinom{}{}", "snippet": "\\dbinom{$1}{$2}", "meta": "datatool-cmd", "score": 0.006800272303210672}, {"caption": "\\Tilde{}", "snippet": "\\Tilde{$1}", "meta": "datatool-cmd", "score": 7.874446783586035e-05}, {"caption": "\\bigcup", "snippet": "\\bigcup", "meta": "datatool-cmd", "score": 0.0058847868741168765}, {"caption": "\\sinh", "snippet": "\\sinh", "meta": "datatool-cmd", "score": 0.0006435164702005918}, {"caption": "\\sinh{}", "snippet": "\\sinh{$1}", "meta": "datatool-cmd", "score": 0.0006435164702005918}, {"caption": "\\operatorname{}", "snippet": "\\operatorname{$1}", "meta": "datatool-cmd", "score": 0.02181954887028883}, {"caption": "\\max", "snippet": "\\max", "meta": "datatool-cmd", "score": 0.04116833357968482}, {"caption": "\\liminf", "snippet": "\\liminf", "meta": "datatool-cmd", "score": 0.0015513861600956144}, {"caption": "\\liminf{}", "snippet": "\\liminf{$1}", "meta": "datatool-cmd", "score": 0.0015513861600956144}, {"caption": "\\operatornamewithlimits{}", "snippet": "\\operatornamewithlimits{$1}", "meta": "datatool-cmd", "score": 0.0022415507993352067}, {"caption": "\\exp", "snippet": "\\exp", "meta": "datatool-cmd", "score": 0.02404262443651467}, {"caption": "\\exp{}", "snippet": "\\exp{$1}", "meta": "datatool-cmd", "score": 0.02404262443651467}, {"caption": "\\lim", "snippet": "\\lim", "meta": "datatool-cmd", "score": 0.05285123457928509}, {"caption": "\\sin", "snippet": "\\sin", "meta": "datatool-cmd", "score": 0.040463088537699636}, {"caption": "\\sin{}", "snippet": "\\sin{$1}", "meta": "datatool-cmd", "score": 0.040463088537699636}, {"caption": "\\arg", "snippet": "\\arg", "meta": "datatool-cmd", "score": 0.007190995792600074}, {"caption": "\\cos", "snippet": "\\cos", "meta": "datatool-cmd", "score": 0.050370402546134785}, {"caption": "\\cos{}", "snippet": "\\cos{$1}", "meta": "datatool-cmd", "score": 0.050370402546134785}, {"caption": "\\varliminf", "snippet": "\\varliminf", "meta": "datatool-cmd", "score": 6.204977642542802e-05}, {"caption": "\\hom", "snippet": "\\hom", "meta": "datatool-cmd", "score": 8.180643329881783e-05}, {"caption": "\\tan", "snippet": "\\tan", "meta": "datatool-cmd", "score": 0.006176447465423192}, {"caption": "\\det", "snippet": "\\det", "meta": "datatool-cmd", "score": 0.005640718203101287}, {"caption": "\\ln", "snippet": "\\ln", "meta": "datatool-cmd", "score": 0.025366949660913504}, {"caption": "\\ln{}", "snippet": "\\ln{$1}", "meta": "datatool-cmd", "score": 0.025366949660913504}, {"caption": "\\cosh", "snippet": "\\cosh", "meta": "datatool-cmd", "score": 0.0008896391580266903}, {"caption": "\\cosh{}", "snippet": "\\cosh{$1}", "meta": "datatool-cmd", "score": 0.0008896391580266903}, {"caption": "\\gcd", "snippet": "\\gcd", "meta": "datatool-cmd", "score": 0.002254008371792865}, {"caption": "\\limsup", "snippet": "\\limsup", "meta": "datatool-cmd", "score": 0.002354950225950599}, {"caption": "\\limsup{}", "snippet": "\\limsup{$1}", "meta": "datatool-cmd", "score": 0.002354950225950599}, {"caption": "\\inf", "snippet": "\\inf", "meta": "datatool-cmd", "score": 0.00340470256994063}, {"caption": "\\arccos", "snippet": "\\arccos", "meta": "datatool-cmd", "score": 0.001781687642431819}, {"caption": "\\arccos{}", "snippet": "\\arccos{$1}", "meta": "datatool-cmd", "score": 0.001781687642431819}, {"caption": "\\ker", "snippet": "\\ker", "meta": "datatool-cmd", "score": 0.002475379242338094}, {"caption": "\\cot", "snippet": "\\cot", "meta": "datatool-cmd", "score": 0.0003640644365701238}, {"caption": "\\cot{}", "snippet": "\\cot{$1}", "meta": "datatool-cmd", "score": 0.0003640644365701238}, {"caption": "\\coth{}", "snippet": "\\coth{$1}", "meta": "datatool-cmd", "score": 0.00025939638266884963}, {"caption": "\\coth", "snippet": "\\coth", "meta": "datatool-cmd", "score": 0.00025939638266884963}, {"caption": "\\varlimsup", "snippet": "\\varlimsup", "meta": "datatool-cmd", "score": 6.204977642542802e-05}, {"caption": "\\log", "snippet": "\\log", "meta": "datatool-cmd", "score": 0.048131780413380156}, {"caption": "\\varinjlim", "snippet": "\\varinjlim", "meta": "datatool-cmd", "score": 0.000361814283649031}, {"caption": "\\deg", "snippet": "\\deg", "meta": "datatool-cmd", "score": 0.005542465148816408}, {"caption": "\\arctan", "snippet": "\\arctan", "meta": "datatool-cmd", "score": 0.0011971697553682045}, {"caption": "\\dim", "snippet": "\\dim", "meta": "datatool-cmd", "score": 0.0038210003967178293}, {"caption": "\\min", "snippet": "\\min", "meta": "datatool-cmd", "score": 0.03051120054363316}, {"caption": "\\Pr", "snippet": "\\Pr", "meta": "datatool-cmd", "score": 0.010227440663206161}, {"caption": "\\Pr[]", "snippet": "\\Pr[$1]", "meta": "datatool-cmd", "score": 0.010227440663206161}, {"caption": "\\tanh", "snippet": "\\tanh", "meta": "datatool-cmd", "score": 0.0021229156376192525}, {"caption": "\\tanh{}", "snippet": "\\tanh{$1}", "meta": "datatool-cmd", "score": 0.0021229156376192525}, {"caption": "\\arcsin", "snippet": "\\arcsin", "meta": "datatool-cmd", "score": 0.0007754886988089101}, {"caption": "\\arcsin{}", "snippet": "\\arcsin{$1}", "meta": "datatool-cmd", "score": 0.0007754886988089101}, {"caption": "\\DeclareMathOperator{}{}", "snippet": "\\DeclareMathOperator{$1}{$2}", "meta": "datatool-cmd", "score": 0.029440493885398676}, {"caption": "\\csc", "snippet": "\\csc", "meta": "datatool-cmd", "score": 0.00013963711107573638}, {"caption": "\\sup", "snippet": "\\sup", "meta": "datatool-cmd", "score": 0.009355514755312534}, {"caption": "\\sec", "snippet": "\\sec", "meta": "datatool-cmd", "score": 0.0005912636157903734}, {"caption": "\\varprojlim", "snippet": "\\varprojlim", "meta": "datatool-cmd", "score": 0.0004286136584068833}, {"caption": "\\stepcounter{}", "snippet": "\\stepcounter{$1}", "meta": "datatool-cmd", "score": 0.0030745841706804776}, {"caption": "\\addtocounter{}{}", "snippet": "\\addtocounter{$1}{$2}", "meta": "datatool-cmd", "score": 0.010241823778997489}, {"caption": "\\text{}", "snippet": "\\text{$1}", "meta": "datatool-cmd", "score": 0.3608680734736821}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datatool-cmd", "score": 0.008565354665444157}, {"caption": "\\pmb{}", "snippet": "\\pmb{$1}", "meta": "datatool-cmd", "score": 0.019171182556792562}, {"caption": "\\boldsymbol{}", "snippet": "\\boldsymbol{$1}", "meta": "datatool-cmd", "score": 0.18137737738638837}, {"caption": "\\boldsymbol", "snippet": "\\boldsymbol", "meta": "datatool-cmd", "score": 0.18137737738638837}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "datatool-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "datatool-cmd", "score": 0.021170869458413965}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "datatool-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "datatool-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "datatool-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "datatool-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "datatool-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "datatool-cmd", "score": 0.0018957469739775527}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "datatool-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "datatool-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "datatool-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "datatool-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "datatool-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "datatool-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "datatool-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "datatool-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "datatool-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "datatool-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "datatool-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "datatool-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "datatool-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "datatool-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "datatool-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "datatool-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "datatool-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "datatool-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "datatool-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "datatool-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "datatool-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "datatool-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "datatool-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "datatool-cmd", "score": 0.0063276692758974925}], "fmtcount": [{"caption": "\\csname", "snippet": "\\csname", "meta": "fmtcount-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "fmtcount-cmd", "score": 0.008565354665444157}, {"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "fmtcount-cmd", "score": 0.00037306820619479756}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "fmtcount-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "fmtcount-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "fmtcount-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "fmtcount-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "fmtcount-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "fmtcount-cmd", "score": 0.0018957469739775527}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "fmtcount-cmd", "score": 0.00021116765384691477}, {"caption": "\\robustify{}", "snippet": "\\robustify{$1}", "meta": "fmtcount-cmd", "score": 0.002671974990314091}, {"caption": "\\setbool{}{}", "snippet": "\\setbool{$1}{$2}", "meta": "fmtcount-cmd", "score": 0.00023171033119130004}, {"caption": "\\ifdefempty{}{}{}", "snippet": "\\ifdefempty{$1}{$2}{$3}", "meta": "fmtcount-cmd", "score": 7.482069221111606e-05}, {"caption": "\\apptocmd{}{}{}{}", "snippet": "\\apptocmd{$1}{$2}{$3}{$4}", "meta": "fmtcount-cmd", "score": 0.00035805058319299113}, {"caption": "\\ifstrequal{}{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}{$4}", "meta": "fmtcount-cmd", "score": 0.00041307691354437894}, {"caption": "\\ifstrequal{}{}{}", "snippet": "\\ifstrequal{$1}{$2}{$3}", "meta": "fmtcount-cmd", "score": 0.00041307691354437894}, {"caption": "\\string", "snippet": "\\string", "meta": "fmtcount-cmd", "score": 0.001042697111754002}, {"caption": "\\csedef{}{}", "snippet": "\\csedef{$1}{$2}", "meta": "fmtcount-cmd", "score": 0.00014933999190577243}, {"caption": "\\do", "snippet": "\\do", "meta": "fmtcount-cmd", "score": 0.009278344180101056}, {"caption": "\\newrobustcmd{}[]{}", "snippet": "\\newrobustcmd{$1}[$2]{$3}", "meta": "fmtcount-cmd", "score": 0.0006607703576475988}, {"caption": "\\ifdefstring{}{}{}{}", "snippet": "\\ifdefstring{$1}{$2}{$3}{$4}", "meta": "fmtcount-cmd", "score": 0.0006796212875843042}, {"caption": "\\ifbool{}{}{}", "snippet": "\\ifbool{$1}{$2}{$3}", "meta": "fmtcount-cmd", "score": 7.723677706376668e-05}, {"caption": "\\patchcmd{}{}{}{}{}", "snippet": "\\patchcmd{$1}{$2}{$3}{$4}{$5}", "meta": "fmtcount-cmd", "score": 0.002560998917940627}, {"caption": "\\patchcmd", "snippet": "\\patchcmd", "meta": "fmtcount-cmd", "score": 0.002560998917940627}, {"caption": "\\preto{}{}", "snippet": "\\preto{$1}{$2}", "meta": "fmtcount-cmd", "score": 8.860754525300578e-05}, {"caption": "\\ifnumcomp{}{}{}{}{}", "snippet": "\\ifnumcomp{$1}{$2}{$3}{$4}{$5}", "meta": "fmtcount-cmd", "score": 0.00029867998381154486}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "fmtcount-cmd", "score": 0.00530510025314411}, {"caption": "\\newbool{}", "snippet": "\\newbool{$1}", "meta": "fmtcount-cmd", "score": 7.723677706376668e-05}, {"caption": "\\AtBeginEnvironment{}{}", "snippet": "\\AtBeginEnvironment{$1}{$2}", "meta": "fmtcount-cmd", "score": 4.002553629215439e-05}, {"caption": "\\pretocmd{}{}{}{}", "snippet": "\\pretocmd{$1}{$2}{$3}{$4}", "meta": "fmtcount-cmd", "score": 0.00028992557275763024}, {"caption": "\\ifundef{}{}{}", "snippet": "\\ifundef{$1}{$2}{$3}", "meta": "fmtcount-cmd", "score": 0.00014933999190577243}, {"caption": "\\csname", "snippet": "\\csname", "meta": "fmtcount-cmd", "score": 0.008565354665444157}, {"caption": "\\do", "snippet": "\\do", "meta": "fmtcount-cmd", "score": 0.009278344180101056}, {"caption": "\\frenchspacing", "snippet": "\\frenchspacing", "meta": "fmtcount-cmd", "score": 0.0063276692758974925}], "aurl": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "aurl-cmd", "score": 0.00037306820619479756}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\AtBeginShipout{}", "snippet": "\\AtBeginShipout{$1}", "meta": "aurl-cmd", "score": 0.00047530324346933345}, {"caption": "\\AtBeginShipoutNext{}", "snippet": "\\AtBeginShipoutNext{$1}", "meta": "aurl-cmd", "score": 0.0005277905480209891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\UrlBreaks{}", "snippet": "\\UrlBreaks{$1}", "meta": "aurl-cmd", "score": 0.001030592515645366}, {"caption": "\\UrlBreaks", "snippet": "\\UrlBreaks", "meta": "aurl-cmd", "score": 0.001030592515645366}, {"caption": "\\Url", "snippet": "\\Url", "meta": "aurl-cmd", "score": 0.0002854206807593436}, {"caption": "\\UrlOrds{}", "snippet": "\\UrlOrds{$1}", "meta": "aurl-cmd", "score": 0.0006882563723629154}, {"caption": "\\UrlOrds", "snippet": "\\UrlOrds", "meta": "aurl-cmd", "score": 0.0006882563723629154}, {"caption": "\\urlstyle{}", "snippet": "\\urlstyle{$1}", "meta": "aurl-cmd", "score": 0.010515056688180681}, {"caption": "\\urldef{}", "snippet": "\\urldef{$1}", "meta": "aurl-cmd", "score": 0.008041789461944983}, {"caption": "\\UrlBigBreaks{}", "snippet": "\\UrlBigBreaks{$1}", "meta": "aurl-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlFont{}", "snippet": "\\UrlFont{$1}", "meta": "aurl-cmd", "score": 0.0032990580087398644}, {"caption": "\\UrlSpecials{}", "snippet": "\\UrlSpecials{$1}", "meta": "aurl-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\UrlNoBreaks", "snippet": "\\UrlNoBreaks", "meta": "aurl-cmd", "score": 3.7048287721105874e-05}, {"caption": "\\nameref{}", "snippet": "\\nameref{$1}", "meta": "aurl-cmd", "score": 0.009472569279662113}, {"caption": "\\pdfbookmark[]{}{}", "snippet": "\\pdfbookmark[$1]{$2}{$3}", "meta": "aurl-cmd", "score": 0.006492248863367502}, {"caption": "\\figureautorefname", "snippet": "\\figureautorefname", "meta": "aurl-cmd", "score": 0.00014582556188448738}, {"caption": "\\figureautorefname{}", "snippet": "\\figureautorefname{$1}", "meta": "aurl-cmd", "score": 0.00014582556188448738}, {"caption": "\\numberwithin{}{}", "snippet": "\\numberwithin{$1}{$2}", "meta": "aurl-cmd", "score": 0.006963729684667191}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\footnoteautorefname", "snippet": "\\footnoteautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\roman{}", "snippet": "\\roman{$1}", "meta": "aurl-cmd", "score": 0.005553384455935491}, {"caption": "\\roman", "snippet": "\\roman", "meta": "aurl-cmd", "score": 0.005553384455935491}, {"caption": "\\string", "snippet": "\\string", "meta": "aurl-cmd", "score": 0.001042697111754002}, {"caption": "\\MakeLowercase{}", "snippet": "\\MakeLowercase{$1}", "meta": "aurl-cmd", "score": 0.017289599800633146}, {"caption": "\\textunderscore", "snippet": "\\textunderscore", "meta": "aurl-cmd", "score": 0.001509072212764015}, {"caption": "\\do", "snippet": "\\do", "meta": "aurl-cmd", "score": 0.009278344180101056}, {"caption": "\\begin{}", "snippet": "\\begin{$1}", "meta": "aurl-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}[]", "snippet": "\\begin{$1}[$2]", "meta": "aurl-cmd", "score": 7.849662248028187}, {"caption": "\\begin{}{}", "snippet": "\\begin{$1}{$2}", "meta": "aurl-cmd", "score": 7.849662248028187}, {"caption": "\\FancyVerbLineautorefname", "snippet": "\\FancyVerbLineautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\hyperlink{}{}", "snippet": "\\hyperlink{$1}{$2}", "meta": "aurl-cmd", "score": 0.00978652043902115}, {"caption": "\\tableautorefname", "snippet": "\\tableautorefname", "meta": "aurl-cmd", "score": 0.00012704528567339081}, {"caption": "\\tableautorefname{}", "snippet": "\\tableautorefname{$1}", "meta": "aurl-cmd", "score": 0.00012704528567339081}, {"caption": "\\equationautorefname", "snippet": "\\equationautorefname", "meta": "aurl-cmd", "score": 0.00018777198999871106}, {"caption": "\\equationautorefname{}", "snippet": "\\equationautorefname{$1}", "meta": "aurl-cmd", "score": 0.00018777198999871106}, {"caption": "\\chapterautorefname", "snippet": "\\chapterautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\TeX", "snippet": "\\TeX", "meta": "aurl-cmd", "score": 0.02873756018238537}, {"caption": "\\TeX{}", "snippet": "\\TeX{$1}", "meta": "aurl-cmd", "score": 0.02873756018238537}, {"caption": "\\protect", "snippet": "\\protect", "meta": "aurl-cmd", "score": 0.0200686676229443}, {"caption": "\\appendixautorefname", "snippet": "\\appendixautorefname", "meta": "aurl-cmd", "score": 7.950698053641679e-05}, {"caption": "\\appendixautorefname{}", "snippet": "\\appendixautorefname{$1}", "meta": "aurl-cmd", "score": 7.950698053641679e-05}, {"caption": "\\newlabel{}{}", "snippet": "\\newlabel{$1}{$2}", "meta": "aurl-cmd", "score": 0.00029737672328168955}, {"caption": "\\texorpdfstring{}{}", "snippet": "\\texorpdfstring{$1}{$2}", "meta": "aurl-cmd", "score": 0.0073781967296121}, {"caption": "\\refstepcounter{}", "snippet": "\\refstepcounter{$1}", "meta": "aurl-cmd", "score": 0.002140559856649122}, {"caption": "\\alph", "snippet": "\\alph", "meta": "aurl-cmd", "score": 0.01034327266194849}, {"caption": "\\alph{}", "snippet": "\\alph{$1}", "meta": "aurl-cmd", "score": 0.01034327266194849}, {"caption": "\\pageref{}", "snippet": "\\pageref{$1}", "meta": "aurl-cmd", "score": 0.019788865471151957}, {"caption": "\\item", "snippet": "\\item", "meta": "aurl-cmd", "score": 3.800886892251021}, {"caption": "\\item[]", "snippet": "\\item[$1]", "meta": "aurl-cmd", "score": 3.800886892251021}, {"caption": "\\LaTeX", "snippet": "\\LaTeX", "meta": "aurl-cmd", "score": 0.2334089308452787}, {"caption": "\\LaTeX{}", "snippet": "\\LaTeX{$1}", "meta": "aurl-cmd", "score": 0.2334089308452787}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\itemautorefname", "snippet": "\\itemautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\caption{}", "snippet": "\\caption{$1}", "meta": "aurl-cmd", "score": 1.2569477427490174}, {"caption": "\\sectionautorefname", "snippet": "\\sectionautorefname", "meta": "aurl-cmd", "score": 0.0019832324299155183}, {"caption": "\\sectionautorefname{}", "snippet": "\\sectionautorefname{$1}", "meta": "aurl-cmd", "score": 0.0019832324299155183}, {"caption": "\\LaTeXe", "snippet": "\\LaTeXe", "meta": "aurl-cmd", "score": 0.007928096378157487}, {"caption": "\\LaTeXe{}", "snippet": "\\LaTeXe{$1}", "meta": "aurl-cmd", "score": 0.007928096378157487}, {"caption": "\\footref{}", "snippet": "\\footref{$1}", "meta": "aurl-cmd", "score": 0.0003680857021151614}, {"caption": "\\footref", "snippet": "\\footref", "meta": "aurl-cmd", "score": 0.0003680857021151614}, {"caption": "\\hypertarget{}{}", "snippet": "\\hypertarget{$1}{$2}", "meta": "aurl-cmd", "score": 0.009652820108904094}, {"caption": "\\theoremautorefname", "snippet": "\\theoremautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\maketitle", "snippet": "\\maketitle", "meta": "aurl-cmd", "score": 0.7504160124360846}, {"caption": "\\subparagraphautorefname", "snippet": "\\subparagraphautorefname", "meta": "aurl-cmd", "score": 0.0005446476945175932}, {"caption": "\\url{}", "snippet": "\\url{$1}", "meta": "aurl-cmd", "score": 0.13586474005868793}, {"caption": "\\author{}", "snippet": "\\author{$1}", "meta": "aurl-cmd", "score": 0.8973590434087177}, {"caption": "\\author[]{}", "snippet": "\\author[$1]{$2}", "meta": "aurl-cmd", "score": 0.8973590434087177}, {"caption": "\\href{}{}", "snippet": "\\href{$1}{$2}", "meta": "aurl-cmd", "score": 0.27111130260612365}, {"caption": "\\Roman{}", "snippet": "\\Roman{$1}", "meta": "aurl-cmd", "score": 0.0038703587462843594}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}, {"caption": "\\autoref{}", "snippet": "\\autoref{$1}", "meta": "aurl-cmd", "score": 0.03741172773691362}, {"caption": "\\nolinkurl{}", "snippet": "\\nolinkurl{$1}", "meta": "aurl-cmd", "score": 0.0004995635515943437}, {"caption": "\\end{}", "snippet": "\\end{$1}", "meta": "aurl-cmd", "score": 7.847906405228455}, {"caption": "\\phantomsection", "snippet": "\\phantomsection", "meta": "aurl-cmd", "score": 0.0174633138331273}, {"caption": "\\MakeUppercase{}", "snippet": "\\MakeUppercase{$1}", "meta": "aurl-cmd", "score": 0.006776001543888959}, {"caption": "\\MakeUppercase", "snippet": "\\MakeUppercase", "meta": "aurl-cmd", "score": 0.006776001543888959}, {"caption": "\\partautorefname", "snippet": "\\partautorefname", "meta": "aurl-cmd", "score": 1.8780276211096543e-05}, {"caption": "\\Itemautorefname{}", "snippet": "\\Itemautorefname{$1}", "meta": "aurl-cmd", "score": 6.006262128895586e-05}, {"caption": "\\halign{}", "snippet": "\\halign{$1}", "meta": "aurl-cmd", "score": 0.00017906650306643613}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "aurl-cmd", "score": 0.20852115286477566}, {"caption": "\\ref{}", "snippet": "\\ref{$1}", "meta": "aurl-cmd", "score": 1.4380093454211778}, {"caption": "\\Alph{}", "snippet": "\\Alph{$1}", "meta": "aurl-cmd", "score": 0.002233258780143355}, {"caption": "\\Alph", "snippet": "\\Alph", "meta": "aurl-cmd", "score": 0.002233258780143355}, {"caption": "\\appendix", "snippet": "\\appendix", "meta": "aurl-cmd", "score": 0.047007158741781095}, {"caption": "\\MP", "snippet": "\\MP", "meta": "aurl-cmd", "score": 0.00018344383742255004}, {"caption": "\\MP{}", "snippet": "\\MP{$1}", "meta": "aurl-cmd", "score": 0.00018344383742255004}, {"caption": "\\paragraphautorefname", "snippet": "\\paragraphautorefname", "meta": "aurl-cmd", "score": 0.0005446476945175932}, {"caption": "\\citeN{}", "snippet": "\\citeN{$1}", "meta": "aurl-cmd", "score": 0.0018503938529945614}, {"caption": "\\citeN", "snippet": "\\citeN", "meta": "aurl-cmd", "score": 0.0018503938529945614}, {"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "aurl-cmd", "score": 0.07503475348393239}, {"caption": "\\subsectionautorefname", "snippet": "\\subsectionautorefname", "meta": "aurl-cmd", "score": 0.0012546605780895737}, {"caption": "\\subsectionautorefname{}", "snippet": "\\subsectionautorefname{$1}", "meta": "aurl-cmd", "score": 0.0012546605780895737}, {"caption": "\\hyperref[]{}", "snippet": "\\hyperref[$1]{$2}", "meta": "aurl-cmd", "score": 0.004515152477030062}, {"caption": "\\arabic{}", "snippet": "\\arabic{$1}", "meta": "aurl-cmd", "score": 0.02445837629741638}, {"caption": "\\arabic", "snippet": "\\arabic", "meta": "aurl-cmd", "score": 0.02445837629741638}, {"caption": "\\newline", "snippet": "\\newline", "meta": "aurl-cmd", "score": 0.3311721696201715}, {"caption": "\\hypersetup{}", "snippet": "\\hypersetup{$1}", "meta": "aurl-cmd", "score": 0.06967310843464661}, {"caption": "\\subsubsectionautorefname", "snippet": "\\subsubsectionautorefname", "meta": "aurl-cmd", "score": 0.0012064581899162352}, {"caption": "\\subsubsectionautorefname{}", "snippet": "\\subsubsectionautorefname{$1}", "meta": "aurl-cmd", "score": 0.0012064581899162352}, {"caption": "\\title{}", "snippet": "\\title{$1}", "meta": "aurl-cmd", "score": 0.9202908262245683}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "aurl-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "aurl-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "aurl-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "aurl-cmd", "score": 0.002958865219480927}, {"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "aurl-cmd", "score": 0.00021116765384691477}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "aurl-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "aurl-cmd", "score": 0.00530510025314411}], "bchart": [{"caption": "\\setkeys{}{}", "snippet": "\\setkeys{$1}{$2}", "meta": "bchart-cmd", "score": 0.00037306820619479756}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bchart-cmd", "score": 0.008565354665444157}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bchart-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bchart-cmd", "score": 0.021170869458413965}, {"caption": "\\scalebox{}{}", "snippet": "\\scalebox{$1}{$2}", "meta": "bchart-cmd", "score": 0.015973401906548487}, {"caption": "\\reflectbox{}", "snippet": "\\reflectbox{$1}", "meta": "bchart-cmd", "score": 0.0005981923692899367}, {"caption": "\\reflectbox", "snippet": "\\reflectbox", "meta": "bchart-cmd", "score": 0.0005981923692899367}, {"caption": "\\resizebox{}{}{}", "snippet": "\\resizebox{$1}{$2}{$3}", "meta": "bchart-cmd", "score": 0.017834153815870245}, {"caption": "\\includegraphics[]{}", "snippet": "\\includegraphics[$1]{$2}", "meta": "bchart-cmd", "score": 1.4595731795525781}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bchart-cmd", "score": 0.00530510025314411}, {"caption": "\\DeclareGraphicsExtensions{}", "snippet": "\\DeclareGraphicsExtensions{$1}", "meta": "bchart-cmd", "score": 0.0055519509468004175}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bchart-cmd", "score": 0.008565354665444157}, {"caption": "\\graphicspath{}", "snippet": "\\graphicspath{$1}", "meta": "bchart-cmd", "score": 0.09973951908678011}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\DeclareGraphicsRule{}{}{}{}", "snippet": "\\DeclareGraphicsRule{$1}{$2}{$3}{$4}", "meta": "bchart-cmd", "score": 0.004649150613625593}, {"caption": "\\ifthenelse{}{}{}", "snippet": "\\ifthenelse{$1}{$2}{$3}", "meta": "bchart-cmd", "score": 0.009331077109224957}, {"caption": "\\ifthenelse{}", "snippet": "\\ifthenelse{$1}", "meta": "bchart-cmd", "score": 0.009331077109224957}, {"caption": "\\setboolean{}{}", "snippet": "\\setboolean{$1}{$2}", "meta": "bchart-cmd", "score": 0.0012203054938872515}, {"caption": "\\newboolean{}", "snippet": "\\newboolean{$1}", "meta": "bchart-cmd", "score": 0.0009170966832172938}, {"caption": "\\value{}", "snippet": "\\value{$1}", "meta": "bchart-cmd", "score": 0.01590723355124104}, {"caption": "\\boolean{}", "snippet": "\\boolean{$1}", "meta": "bchart-cmd", "score": 0.0018957469739775527}, {"caption": "\\rotatebox{}{}", "snippet": "\\rotatebox{$1}{$2}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox[]{}{}", "snippet": "\\rotatebox[$1]{$2}{$3}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\rotatebox{}", "snippet": "\\rotatebox{$1}", "meta": "bchart-cmd", "score": 0.004719094298848707}, {"caption": "\\definecolors{}", "snippet": "\\definecolors{$1}", "meta": "bchart-cmd", "score": 0.0003209840085766927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "bchart-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "bchart-cmd", "score": 0.021170869458413965}, {"caption": "\\fcolorbox{}{}{}", "snippet": "\\fcolorbox{$1}{$2}{$3}", "meta": "bchart-cmd", "score": 0.00926923425734719}, {"caption": "\\colorlet{}{}", "snippet": "\\colorlet{$1}{$2}", "meta": "bchart-cmd", "score": 0.03654388342026623}, {"caption": "\\textcolor{}{}", "snippet": "\\textcolor{$1}{$2}", "meta": "bchart-cmd", "score": 0.20852115286477566}, {"caption": "\\selectcolormodel{}", "snippet": "\\selectcolormodel{$1}", "meta": "bchart-cmd", "score": 0.000264339771769041}, {"caption": "\\rowcolors{}{}{}", "snippet": "\\rowcolors{$1}{$2}{$3}", "meta": "bchart-cmd", "score": 0.0014120076489723356}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "bchart-cmd", "score": 0.00530510025314411}, {"caption": "\\pagecolor{}", "snippet": "\\pagecolor{$1}", "meta": "bchart-cmd", "score": 0.0008147200475678891}, {"caption": "\\pagecolor{}{}", "snippet": "\\pagecolor{$1}{$2}", "meta": "bchart-cmd", "score": 0.0008147200475678891}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bchart-cmd", "score": 0.008565354665444157}, {"caption": "\\definecolor{}{}{}", "snippet": "\\definecolor{$1}{$2}{$3}", "meta": "bchart-cmd", "score": 0.16906710888680052}, {"caption": "\\colorbox{}{}", "snippet": "\\colorbox{$1}{$2}", "meta": "bchart-cmd", "score": 0.029302172361548254}, {"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "bchart-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "bchart-cmd", "score": 0.2864294797053033}], "pdftexcmds": [{"caption": "\\csname", "snippet": "\\csname", "meta": "pdftexcmds-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "pdftexcmds-cmd", "score": 0.002958865219480927}], "l3keys2e": [{"caption": "\\color[]{}", "snippet": "\\color[$1]{$2}", "meta": "l3keys2e-cmd", "score": 0.2864294797053033}, {"caption": "\\color{}", "snippet": "\\color{$1}", "meta": "l3keys2e-cmd", "score": 0.2864294797053033}], "xfor": [{"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "xfor-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "xfor-cmd", "score": 0.021170869458413965}], "accsupp": [{"caption": "\\RequireXeTeX", "snippet": "\\RequireXeTeX", "meta": "accsupp-cmd", "score": 0.00021116765384691477}, {"caption": "\\empty", "snippet": "\\empty", "meta": "accsupp-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "accsupp-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "accsupp-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "accsupp-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "accsupp-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "accsupp-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "accsupp-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "accsupp-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "accsupp-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "accsupp-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "accsupp-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "accsupp-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "accsupp-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "accsupp-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "accsupp-cmd", "score": 0.021170869458413965}], "trig": [{"caption": "\\csname", "snippet": "\\csname", "meta": "trig-cmd", "score": 0.008565354665444157}], "rerunfilecheck": [{"caption": "\\makeindex", "snippet": "\\makeindex", "meta": "rerunfilecheck-cmd", "score": 0.010304996748556729}, {"caption": "\\index{}", "snippet": "\\index{$1}", "meta": "rerunfilecheck-cmd", "score": 0.013774721817648336}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rerunfilecheck-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "rerunfilecheck-cmd", "score": 0.002958865219480927}, {"caption": "\\clearpage", "snippet": "\\clearpage", "meta": "rerunfilecheck-cmd", "score": 0.1789117552185788}, {"caption": "\\global", "snippet": "\\global", "meta": "rerunfilecheck-cmd", "score": 0.006609629561859019}, {"caption": "\\empty", "snippet": "\\empty", "meta": "rerunfilecheck-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "rerunfilecheck-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rerunfilecheck-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "rerunfilecheck-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "rerunfilecheck-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rerunfilecheck-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "rerunfilecheck-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "rerunfilecheck-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "rerunfilecheck-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rerunfilecheck-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "rerunfilecheck-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "rerunfilecheck-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "rerunfilecheck-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "rerunfilecheck-cmd", "score": 0.021170869458413965}], "pdfescape": [{"caption": "\\empty", "snippet": "\\empty", "meta": "pdfescape-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "pdfescape-cmd", "score": 0.00530510025314411}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "pdfescape-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "pdfescape-cmd", "score": 0.021170869458413965}, {"caption": "\\csname", "snippet": "\\csname", "meta": "pdfescape-cmd", "score": 0.008565354665444157}], "infwarerr": [{"caption": "\\empty", "snippet": "\\empty", "meta": "infwarerr-cmd", "score": 0.002958865219480927}, {"caption": "\\check{}", "snippet": "\\check{$1}", "meta": "infwarerr-cmd", "score": 0.0058342578961340175}, {"caption": "\\space", "snippet": "\\space", "meta": "infwarerr-cmd", "score": 0.023010789853665694}, {"caption": "\\csname", "snippet": "\\csname", "meta": "infwarerr-cmd", "score": 0.008565354665444157}], "kvsetkeys": [{"caption": "\\empty", "snippet": "\\empty", "meta": "kvsetkeys-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "kvsetkeys-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "kvsetkeys-cmd", "score": 0.008565354665444157}], "gettitlestring": [{"caption": "\\addcontentsline{}{}{}", "snippet": "\\addcontentsline{$1}{$2}{$3}", "meta": "gettitlestring-cmd", "score": 0.07503475348393239}, {"caption": "\\empty", "snippet": "\\empty", "meta": "gettitlestring-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "gettitlestring-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gettitlestring-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "gettitlestring-cmd", "score": 0.002958865219480927}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "gettitlestring-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gettitlestring-cmd", "score": 0.008565354665444157}, {"caption": "\\csname", "snippet": "\\csname", "meta": "gettitlestring-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "gettitlestring-cmd", "score": 0.002958865219480927}, {"caption": "\\expandafter", "snippet": "\\expandafter", "meta": "gettitlestring-cmd", "score": 0.021170869458413965}, {"caption": "\\expandafter{}", "snippet": "\\expandafter{$1}", "meta": "gettitlestring-cmd", "score": 0.021170869458413965}], "refcount": [{"caption": "\\thepage", "snippet": "\\thepage", "meta": "refcount-cmd", "score": 0.0591555998103519}], "bitset": [{"caption": "\\empty", "snippet": "\\empty", "meta": "bitset-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "bitset-cmd", "score": 0.008565354665444157}], "etexcmds": [{"caption": "\\csname", "snippet": "\\csname", "meta": "etexcmds-cmd", "score": 0.008565354665444157}, {"caption": "\\empty", "snippet": "\\empty", "meta": "etexcmds-cmd", "score": 0.002958865219480927}], "intcalc": [{"caption": "\\empty", "snippet": "\\empty", "meta": "intcalc-cmd", "score": 0.002958865219480927}, {"caption": "\\csname", "snippet": "\\csname", "meta": "intcalc-cmd", "score": 0.008565354665444157}], "hycolor": [{"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hycolor-cmd", "score": 0.00530510025314411}, {"caption": "\\csname", "snippet": "\\csname", "meta": "hycolor-cmd", "score": 0.008565354665444157}, {"caption": "\\noexpand", "snippet": "\\noexpand", "meta": "hycolor-cmd", "score": 0.00530510025314411}]}
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Newsletter/NewsletterManager.coffee b/services/web/app/coffee/Features/Newsletter/NewsletterManager.coffee
deleted file mode 100644
index d32ba6233f..0000000000
--- a/services/web/app/coffee/Features/Newsletter/NewsletterManager.coffee
+++ /dev/null
@@ -1,89 +0,0 @@
-async = require('async')
-logger = require 'logger-sharelatex'
-Settings = require 'settings-sharelatex'
-crypto = require('crypto')
-Mailchimp = require('mailchimp-api-v3')
-
-if !Settings.mailchimp?.api_key?
- logger.info "Using newsletter provider: none"
- mailchimp =
- request: (opts, cb)-> cb()
-else
- logger.info "Using newsletter provider: mailchimp"
- mailchimp = new Mailchimp(Settings.mailchimp?.api_key)
-
-module.exports =
-
- subscribe: (user, callback = () ->)->
- options = buildOptions(user, true)
- logger.log options:options, user:user, email:user.email, "subscribing user to the mailing list"
- mailchimp.request options, (err)->
- if err?
- logger.err err:err, user:user, "error subscribing person to newsletter"
- else
- logger.log user:user, "finished subscribing user to the newsletter"
- callback(err)
-
- unsubscribe: (user, callback = () ->)->
- logger.log user:user, email:user.email, "trying to unsubscribe user to the mailing list"
- options = buildOptions(user, false)
- mailchimp.request options, (err)->
- if err?
- logger.err err:err, user:user, "error unsubscribing person to newsletter"
- else
- logger.log user:user, "finished unsubscribing user to the newsletter"
- callback(err)
-
- changeEmail: (oldEmail, newEmail, callback = ()->)->
- options = buildOptions({email:oldEmail})
- delete options.body.status
- options.body.email_address = newEmail
- logger.log {oldEmail, newEmail, options}, "changing email in newsletter"
- mailchimp.request options, (err)->
- if err? and err?.message?.indexOf("merge fields were invalid") != -1
- logger.log {oldEmail, newEmail}, "unable to change email in newsletter, user has never subscribed"
- return callback()
- else if err? and err?.message?.indexOf("could not be validated") != -1
- logger.log {oldEmail, newEmail},
- "unable to change email in newsletter, user has previously unsubscribed or new email already exist on list"
- return callback()
- else if err? and err.message.indexOf("is already a list member") != -1
- logger.log {oldEmail, newEmail},
- "unable to change email in newsletter, new email is already on mailing list"
- return callback()
- else if err? and err?.message?.indexOf("looks fake or invalid") != -1
- logger.log {oldEmail, newEmail},
- "unable to change email in newsletter, email looks fake to mailchimp"
- return callback()
- else if err?
- logger.err {err, oldEmail, newEmail}, "error changing email in newsletter"
- return callback(err)
- else
- logger.log "finished changing email in the newsletter"
- return callback()
-
-hashEmail = (email)->
- crypto.createHash('md5').update(email.toLowerCase()).digest("hex")
-
-buildOptions = (user, is_subscribed)->
- subscriber_hash = hashEmail(user.email)
- status = if is_subscribed then "subscribed" else "unsubscribed"
- opts =
- method: "PUT"
- path: "/lists/#{Settings.mailchimp?.list_id}/members/#{subscriber_hash}"
- body:
- email_address:user.email
- status_if_new: status
-
- #only set status if we explictly want to set it
- if is_subscribed?
- opts.body.status = status
-
- if user._id?
- opts.body.merge_fields =
- FNAME: user.first_name
- LNAME: user.last_name
- MONGO_ID:user._id
-
- return opts
-
diff --git a/services/web/app/coffee/Features/Notifications/NotificationsBuilder.coffee b/services/web/app/coffee/Features/Notifications/NotificationsBuilder.coffee
deleted file mode 100644
index b787bcf91c..0000000000
--- a/services/web/app/coffee/Features/Notifications/NotificationsBuilder.coffee
+++ /dev/null
@@ -1,63 +0,0 @@
-logger = require("logger-sharelatex")
-NotificationsHandler = require("./NotificationsHandler")
-request = require "request"
-settings = require "settings-sharelatex"
-
-module.exports =
-# Note: notification keys should be url-safe
-
- featuresUpgradedByAffiliation: (affiliation, user) ->
- key: "features-updated-by=#{affiliation.institutionId}"
- create: (callback=()->) ->
- messageOpts =
- institutionName: affiliation.institutionName
- NotificationsHandler.createNotification user._id, @key, "notification_features_upgraded_by_affiliation", messageOpts, null, false, callback
- read: (callback=()->) ->
- NotificationsHandler.markAsRead @key, callback
-
- redundantPersonalSubscription: (affiliation, user) ->
- key: "redundant-personal-subscription-#{affiliation.institutionId}"
- create: (callback=()->) ->
- messageOpts =
- institutionName: affiliation.institutionName
- NotificationsHandler.createNotification user._id, @key, "notification_personal_subscription_not_required_due_to_affiliation", messageOpts, null, false, callback
- read: (callback=()->) ->
- NotificationsHandler.markAsRead @key, callback
-
- projectInvite: (invite, project, sendingUser, user) ->
- key: "project-invite-#{invite._id}"
- create: (callback=()->) ->
- messageOpts =
- userName: sendingUser.first_name
- projectName: project.name
- projectId: project._id.toString()
- token: invite.token
- logger.log {user_id: user._id, project_id: project._id, invite_id: invite._id, key: @key}, "creating project invite notification for user"
- NotificationsHandler.createNotification user._id, @key, "notification_project_invite", messageOpts, invite.expires, callback
- read: (callback=()->) ->
- NotificationsHandler.markAsReadByKeyOnly @key, callback
-
- ipMatcherAffiliation: (userId) ->
- create: (ip, callback=()->) ->
- return null unless settings?.apis?.v1?.url # service is not configured
- request {
- method: 'GET'
- url: "#{settings.apis.v1.url}/api/v2/users/#{userId}/ip_matcher"
- auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass }
- body: { ip: ip }
- json: true
- timeout: 20 * 1000
- }, (error, response, body) ->
- return error if error?
- return null unless response.statusCode == 200
-
- key = "ip-matched-affiliation-#{body.id}"
- messageOpts =
- university_name: body.name
- content: body.enrolment_ad_html
- logger.log user_id:userId, key:key, "creating notification key for user"
- NotificationsHandler.createNotification userId, key, "notification_ip_matched_affiliation", messageOpts, null, false, callback
-
- read: (university_id, callback = ->)->
- key = "ip-matched-affiliation-#{university_id}"
- NotificationsHandler.markAsReadWithKey userId, key, callback
diff --git a/services/web/app/coffee/Features/Notifications/NotificationsController.coffee b/services/web/app/coffee/Features/Notifications/NotificationsController.coffee
deleted file mode 100644
index 5b83a60248..0000000000
--- a/services/web/app/coffee/Features/Notifications/NotificationsController.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-NotificationsHandler = require("./NotificationsHandler")
-AuthenticationController = require("../Authentication/AuthenticationController")
-logger = require("logger-sharelatex")
-_ = require("underscore")
-
-module.exports =
-
- getAllUnreadNotifications: (req, res)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- NotificationsHandler.getUserNotifications user_id, (err, unreadNotifications)->
- unreadNotifications = _.map unreadNotifications, (notification)->
- notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
- return notification
- res.send(unreadNotifications)
-
- markNotificationAsRead: (req, res)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- notification_id = req.params.notification_id
- NotificationsHandler.markAsRead user_id, notification_id, ->
- res.send()
- logger.log user_id:user_id, notification_id:notification_id, "mark notification as read"
diff --git a/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee b/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee
deleted file mode 100644
index a0f6ae5c12..0000000000
--- a/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee
+++ /dev/null
@@ -1,80 +0,0 @@
-settings = require("settings-sharelatex")
-request = require("request")
-logger = require("logger-sharelatex")
-
-oneSecond = 1000
-
-makeRequest = (opts, callback)->
- if !settings.apis.notifications?.url?
- return callback(null, statusCode:200)
- else
- request(opts, callback)
-
-module.exports =
-
- getUserNotifications: (user_id, callback)->
- opts =
- uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
- json: true
- timeout: oneSecond
- method: "GET"
- makeRequest opts, (err, res, unreadNotifications)->
- statusCode = if res? then res.statusCode else 500
- if err? or statusCode != 200
- e = new Error("something went wrong getting notifications, #{err}, #{statusCode}")
- logger.err err:err, "something went wrong getting notifications"
- callback(null, [])
- else
- if !unreadNotifications?
- unreadNotifications = []
- callback(null, unreadNotifications)
-
- createNotification: (user_id, key, templateKey, messageOpts, expiryDateTime, forceCreate, callback)->
- if !callback
- callback = forceCreate
- forceCreate = true
- payload = {
- key:key
- messageOpts:messageOpts
- templateKey:templateKey
- forceCreate:forceCreate
- }
- if expiryDateTime?
- payload.expires = expiryDateTime
- opts =
- uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
- timeout: oneSecond
- method:"POST"
- json: payload
- logger.log opts:opts, "creating notification for user"
- makeRequest opts, callback
-
- markAsReadWithKey: (user_id, key, callback)->
- opts =
- uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
- method: "DELETE"
- timeout: oneSecond
- json: {
- key:key
- }
- logger.log user_id:user_id, key:key, "sending mark notification as read with key to notifications api"
- makeRequest opts, callback
-
-
- markAsRead: (user_id, notification_id, callback)->
- opts =
- method: "DELETE"
- uri: "#{settings.apis.notifications?.url}/user/#{user_id}/notification/#{notification_id}"
- timeout:oneSecond
- logger.log user_id:user_id, notification_id:notification_id, "sending mark notification as read to notifications api"
- makeRequest opts, callback
-
- # removes notification by key, without regard for user_id,
- # should not be exposed to user via ui/router
- markAsReadByKeyOnly: (key, callback)->
- opts =
- uri: "#{settings.apis.notifications?.url}/key/#{key}"
- method: "DELETE"
- timeout: oneSecond
- logger.log {key:key}, "sending mark notification as read with key-only to notifications api"
- makeRequest opts, callback
diff --git a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee b/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee
deleted file mode 100644
index d448a843cb..0000000000
--- a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee
+++ /dev/null
@@ -1,83 +0,0 @@
-PasswordResetHandler = require("./PasswordResetHandler")
-RateLimiter = require("../../infrastructure/RateLimiter")
-AuthenticationController = require("../Authentication/AuthenticationController")
-AuthenticationManager = require("../Authentication/AuthenticationManager")
-UserGetter = require("../User/UserGetter")
-UserUpdater = require("../User/UserUpdater")
-UserSessionsManager = require("../User/UserSessionsManager")
-logger = require "logger-sharelatex"
-Settings = require 'settings-sharelatex'
-
-module.exports =
-
- renderRequestResetForm: (req, res)->
- logger.log "rendering request reset form"
- res.render "user/passwordReset",
- title:"reset_password"
-
- requestReset: (req, res)->
- email = req.body.email.trim().toLowerCase()
- opts =
- endpointName: "password_reset_rate_limit"
- timeInterval: 60
- subjectName: req.ip
- throttle: 6
- RateLimiter.addCount opts, (err, canContinue)->
- if !canContinue
- return res.send 429, { message: req.i18n.translate("rate_limit_hit_wait")}
- PasswordResetHandler.generateAndEmailResetToken email, (err, status)->
- if err?
- res.send 500, {message:err?.message}
- else if status == 'primary'
- res.send 200, {message: {text: req.i18n.translate("password_reset_email_sent")}}
- else if status == 'secondary'
- res.send 404, {message: req.i18n.translate("secondary_email_password_reset")}
- else if status == 'sharelatex'
- res.send 404, {message: "#{req.i18n.translate("reset_from_sl")}"}
- else
- res.send 404, {message: req.i18n.translate("cant_find_email")}
-
- renderSetPasswordForm: (req, res)->
- if req.query.passwordResetToken?
- req.session.resetToken = req.query.passwordResetToken
- return res.redirect('/user/password/set')
- if !req.session.resetToken?
- return res.redirect('/user/password/reset')
- res.render "user/setPassword",
- title:"set_password"
- passwordResetToken: req.session.resetToken
-
- setNewUserPassword: (req, res, next)->
- {passwordResetToken, password} = req.body
- if !password? or password.length == 0 or !passwordResetToken? or passwordResetToken.length == 0 or AuthenticationManager.validatePassword(password?.trim())?
- return res.sendStatus 400
- delete req.session.resetToken
- PasswordResetHandler.setNewUserPassword passwordResetToken?.trim(), password?.trim(), (err, found, user_id) ->
- if err and err.name and err.name == "NotFoundError"
- res.status(404).send("NotFoundError")
- else if err and err.name and err.name == "NotInV2Error"
- res.status(403).send("NotInV2Error")
- else if err and err.name and err.name == "SLInV2Error"
- res.status(403).send("SLInV2Error")
- else if err and err.statusCode and err.statusCode == 500
- res.status(500)
- else if err and !err.statusCode
- res.status(500)
- else if found
- return res.sendStatus 200 if !user_id? # will not exist for v1-only users
- UserSessionsManager.revokeAllUserSessions {_id: user_id}, [], (err) ->
- return next(err) if err?
- UserUpdater.removeReconfirmFlag user_id, (err) ->
- return next(err) if err?
- if req.body.login_after
- UserGetter.getUser user_id, {email: 1}, (err, user) ->
- return next(err) if err?
- AuthenticationController.afterLoginSessionSetup req, user, (err) ->
- if err?
- logger.err {err, email: user.email}, "Error setting up session after setting password"
- return next(err)
- res.json {redir: AuthenticationController._getRedirectFromSession(req) || "/project"}
- else
- res.sendStatus 200
- else
- res.sendStatus 404
diff --git a/services/web/app/coffee/Features/PasswordReset/PasswordResetHandler.coffee b/services/web/app/coffee/Features/PasswordReset/PasswordResetHandler.coffee
deleted file mode 100644
index 169482ed9b..0000000000
--- a/services/web/app/coffee/Features/PasswordReset/PasswordResetHandler.coffee
+++ /dev/null
@@ -1,76 +0,0 @@
-settings = require("settings-sharelatex")
-async = require("async")
-UserGetter = require("../User/UserGetter")
-OneTimeTokenHandler = require("../Security/OneTimeTokenHandler")
-EmailHandler = require("../Email/EmailHandler")
-AuthenticationManager = require("../Authentication/AuthenticationManager")
-logger = require("logger-sharelatex")
-V1Api = require("../V1/V1Api")
-
-module.exports = PasswordResetHandler =
-
- generateAndEmailResetToken:(email, callback = (error, status) ->)->
- PasswordResetHandler._getPasswordResetData email, (error, exists, data) ->
- if error?
- return callback(error, null)
- else if exists
- OneTimeTokenHandler.getNewToken 'password', data, (err, token)->
- if err then return callback(err)
- emailOptions =
- to : email
- setNewPasswordUrl : "#{settings.siteUrl}/user/password/set?passwordResetToken=#{token}&email=#{encodeURIComponent(email)}"
- EmailHandler.sendEmail "passwordResetRequested", emailOptions, (error) ->
- return callback(error) if error?
- callback null, 'primary'
- else
- UserGetter.getUserByAnyEmail email, (err, user) ->
- if !user
- return callback(error, null)
- else if !user.overleaf?.id?
- return callback(error, 'sharelatex')
- else
- return callback(error, 'secondary')
-
- setNewUserPassword: (token, password, callback = (error, found, user_id) ->)->
- OneTimeTokenHandler.getValueFromTokenAndExpire 'password', token, (err, data)->
- if err then return callback(err)
- if !data?
- return callback null, false, null
- if typeof data == "string"
- # Backwards compatible with old format.
- # Tokens expire after 1h, so this can be removed soon after deploy.
- # Possibly we should keep this until we do an onsite release too.
- data = { user_id: data }
- if data.user_id?
- AuthenticationManager.setUserPassword data.user_id, password, (err, reset) ->
- if err then return callback(err)
- callback null, reset, data.user_id
- else if data.v1_user_id?
- AuthenticationManager.setUserPasswordInV1 data.v1_user_id, password, (error, reset) ->
- return callback(error) if error?
- UserGetter.getUser { 'overleaf.id': data.v1_user_id }, {_id:1}, (error, user) ->
- return callback(error) if error?
- callback null, reset, user?._id
-
- _getPasswordResetData: (email, callback = (error, exists, data) ->) ->
- if settings.overleaf?
- # Overleaf v2
- V1Api.request {
- url: "/api/v1/sharelatex/user_emails"
- qs:
- email: email
- expectedStatusCodes: [404]
- }, (error, response, body) ->
- return callback(error) if error?
- if response.statusCode == 404
- return callback null, false
- else
- return callback null, true, { v1_user_id: body.user_id }
- else
- # ShareLaTeX
- UserGetter.getUserByMainEmail email, (err, user)->
- if err then return callback(err)
- if !user? or user.holdingAccount or user.overleaf?
- logger.err email:email, "user could not be found for password reset"
- return callback(null, false)
- return callback null, true, { user_id: user._id }
diff --git a/services/web/app/coffee/Features/PasswordReset/PasswordResetRouter.coffee b/services/web/app/coffee/Features/PasswordReset/PasswordResetRouter.coffee
deleted file mode 100644
index d3591f8623..0000000000
--- a/services/web/app/coffee/Features/PasswordReset/PasswordResetRouter.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-PasswordResetController = require("./PasswordResetController")
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-module.exports =
- apply: (webRouter, apiRouter) ->
-
- webRouter.get '/user/password/reset', PasswordResetController.renderRequestResetForm
- webRouter.post '/user/password/reset', PasswordResetController.requestReset
- AuthenticationController.addEndpointToLoginWhitelist '/user/password/reset'
-
- webRouter.get '/user/password/set', PasswordResetController.renderSetPasswordForm
- webRouter.post '/user/password/set', PasswordResetController.setNewUserPassword
- AuthenticationController.addEndpointToLoginWhitelist '/user/password/set'
-
- webRouter.post '/user/reconfirm', PasswordResetController.requestReset
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Project/DocLinesComparitor.coffee b/services/web/app/coffee/Features/Project/DocLinesComparitor.coffee
deleted file mode 100644
index 4a286e66c7..0000000000
--- a/services/web/app/coffee/Features/Project/DocLinesComparitor.coffee
+++ /dev/null
@@ -1,10 +0,0 @@
-_ = require "underscore"
-
-module.exports =
-
- areSame: (lines1, lines2)->
- if !Array.isArray(lines1) or !Array.isArray(lines2)
- return false
-
- return _.isEqual(lines1, lines2)
-
diff --git a/services/web/app/coffee/Features/Project/ProjectApiController.coffee b/services/web/app/coffee/Features/Project/ProjectApiController.coffee
deleted file mode 100644
index f832a75b54..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectApiController.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-ProjectDetailsHandler = require("./ProjectDetailsHandler")
-logger = require("logger-sharelatex")
-
-
-module.exports =
-
- getProjectDetails : (req, res, next)->
- {project_id} = req.params
- ProjectDetailsHandler.getDetails project_id, (err, projDetails)->
- return next(err) if err?
- res.json(projDetails)
-
diff --git a/services/web/app/coffee/Features/Project/ProjectCollabratecDetailsHandler.coffee b/services/web/app/coffee/Features/Project/ProjectCollabratecDetailsHandler.coffee
deleted file mode 100644
index e4b47c9da9..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectCollabratecDetailsHandler.coffee
+++ /dev/null
@@ -1,73 +0,0 @@
-ObjectId = require("mongojs").ObjectId
-Project = require("../../models/Project").Project
-
-module.exports = ProjectCollabratecDetailsHandler =
- initializeCollabratecProject: (project_id, user_id, collabratec_document_id, collabratec_privategroup_id, callback=(err)->) ->
- ProjectCollabratecDetailsHandler.setCollabratecUsers project_id, [ { user_id, collabratec_document_id, collabratec_privategroup_id } ], callback
-
- isLinkedCollabratecUserProject: (project_id, user_id, callback=(err, isLinked)->) ->
- try
- project_id = ObjectId project_id
- user_id = ObjectId user_id
- catch err
- return callback err
- query =
- _id: project_id
- collabratecUsers: $elemMatch:
- user_id: user_id
- Project.findOne query, {_id: 1}, (err, project) ->
- callback err if err?
- callback null, project?
-
- linkCollabratecUserProject: (project_id, user_id, collabratec_document_id, callback=(err)->) ->
- try
- project_id = ObjectId project_id
- user_id = ObjectId user_id
- catch err
- return callback err
- query =
- _id: project_id
- collabratecUsers: $not: $elemMatch:
- collabratec_document_id: collabratec_document_id
- user_id: user_id
- update = $push: collabratecUsers:
- collabratec_document_id: collabratec_document_id
- user_id: user_id
- Project.update query, update, callback
-
- setCollabratecUsers: (project_id, collabratec_users, callback=(err)->) ->
- try
- project_id = ObjectId project_id
- catch err
- return callback err
- callback(new Error "collabratec_users must be array") unless Array.isArray(collabratec_users)
- for collabratec_user in collabratec_users
- try
- collabratec_user.user_id = ObjectId(collabratec_user.user_id)
- catch err
- return callback err
- update = $set: { collabratecUsers: collabratec_users }
- Project.update { _id: project_id }, update, callback
-
- unlinkCollabratecUserProject: (project_id, user_id, callback=(err)->) ->
- try
- project_id = ObjectId project_id
- user_id = ObjectId user_id
- catch err
- return callback err
- query =
- _id: project_id
- update = $pull: collabratecUsers:
- user_id: user_id
- Project.update query, update, callback
-
- updateCollabratecUserIds: (old_user_id, new_user_id, callback=(err)->) ->
- try
- old_user_id = ObjectId old_user_id
- new_user_id = ObjectId new_user_id
- catch err
- return callback err
- query = "collabratecUsers.user_id": old_user_id
- update = $set: "collabratecUsers.$.user_id": new_user_id
- options = multi: true
- Project.update query, update, options, callback
diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee
deleted file mode 100644
index 508c742299..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectController.coffee
+++ /dev/null
@@ -1,533 +0,0 @@
-async = require("async")
-logger = require("logger-sharelatex")
-projectDeleter = require("./ProjectDeleter")
-projectDuplicator = require("./ProjectDuplicator")
-projectCreationHandler = require("./ProjectCreationHandler")
-editorController = require("../Editor/EditorController")
-metrics = require('metrics-sharelatex')
-User = require('../../models/User').User
-TagsHandler = require("../Tags/TagsHandler")
-SubscriptionLocator = require("../Subscription/SubscriptionLocator")
-NotificationsHandler = require("../Notifications/NotificationsHandler")
-LimitationsManager = require("../Subscription/LimitationsManager")
-underscore = require("underscore")
-Settings = require("settings-sharelatex")
-AuthorizationManager = require("../Authorization/AuthorizationManager")
-fs = require "fs"
-InactiveProjectManager = require("../InactiveData/InactiveProjectManager")
-ProjectUpdateHandler = require("./ProjectUpdateHandler")
-ProjectGetter = require("./ProjectGetter")
-PrivilegeLevels = require("../Authorization/PrivilegeLevels")
-AuthenticationController = require("../Authentication/AuthenticationController")
-PackageVersions = require("../../infrastructure/PackageVersions")
-AnalyticsManager = require "../Analytics/AnalyticsManager"
-Sources = require "../Authorization/Sources"
-TokenAccessHandler = require '../TokenAccess/TokenAccessHandler'
-CollaboratorsHandler = require '../Collaborators/CollaboratorsHandler'
-Modules = require '../../infrastructure/Modules'
-ProjectEntityHandler = require './ProjectEntityHandler'
-UserGetter = require("../User/UserGetter")
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-crypto = require 'crypto'
-{ V1ConnectionError } = require '../Errors/Errors'
-Features = require('../../infrastructure/Features')
-BrandVariationsHandler = require("../BrandVariations/BrandVariationsHandler")
-{ getUserAffiliations } = require("../Institutions/InstitutionsAPI")
-V1Handler = require "../V1/V1Handler"
-
-module.exports = ProjectController =
-
- _isInPercentageRollout: (rolloutName, objectId, percentage) ->
- if Settings.bypassPercentageRollouts == true
- return true
- data = "#{rolloutName}:#{objectId.toString()}"
- md5hash = crypto.createHash('md5').update(data).digest('hex')
- counter = parseInt(md5hash.slice(26, 32), 16)
- return (counter % 100) < percentage
-
- updateProjectSettings: (req, res, next) ->
- project_id = req.params.Project_id
-
- jobs = []
-
- if req.body.compiler?
- jobs.push (callback) ->
- editorController.setCompiler project_id, req.body.compiler, callback
-
- if req.body.imageName?
- jobs.push (callback) ->
- editorController.setImageName project_id, req.body.imageName, callback
-
- if req.body.name?
- jobs.push (callback) ->
- editorController.renameProject project_id, req.body.name, callback
-
- if req.body.spellCheckLanguage?
- jobs.push (callback) ->
- editorController.setSpellCheckLanguage project_id, req.body.spellCheckLanguage, callback
-
- if req.body.rootDocId?
- jobs.push (callback) ->
- editorController.setRootDoc project_id, req.body.rootDocId, callback
-
- async.series jobs, (error) ->
- return next(error) if error?
- res.sendStatus(204)
-
- updateProjectAdminSettings: (req, res, next) ->
- project_id = req.params.Project_id
-
- jobs = []
- if req.body.publicAccessLevel?
- jobs.push (callback) ->
- editorController.setPublicAccessLevel project_id, req.body.publicAccessLevel, callback
-
- async.series jobs, (error) ->
- return next(error) if error?
- res.sendStatus(204)
-
- deleteProject: (req, res) ->
- project_id = req.params.Project_id
- forever = req.query?.forever?
- logger.log project_id: project_id, forever: forever, "received request to archive project"
- user = AuthenticationController.getSessionUser(req)
- cb = (err)->
- if err?
- res.sendStatus 500
- else
- res.sendStatus 200
-
- if forever
- projectDeleter.deleteProject project_id, {deleterUser: user, ipAddress:req.ip} , cb
- else
- projectDeleter.archiveProject project_id, cb
-
- restoreProject: (req, res) ->
- project_id = req.params.Project_id
- logger.log project_id:project_id, "received request to restore project"
- projectDeleter.restoreProject project_id, (err)->
- if err?
- res.sendStatus 500
- else
- res.sendStatus 200
-
- cloneProject: (req, res, next)->
- res.setTimeout(5 * 60 * 1000) # allow extra time for the copy to complete
- metrics.inc "cloned-project"
- project_id = req.params.Project_id
- projectName = req.body.projectName
- logger.log project_id:project_id, projectName:projectName, "cloning project"
- if !AuthenticationController.isUserLoggedIn(req)
- return res.send redir:"/register"
- currentUser = AuthenticationController.getSessionUser(req)
- projectDuplicator.duplicate currentUser, project_id, projectName, (err, project)->
- if err?
- logger.error err:err, project_id: project_id, user_id: currentUser._id, "error cloning project"
- return next(err)
- res.send({name:project.name, project_id:project._id, owner_ref:project.owner_ref})
-
-
- newProject: (req, res, next)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- projectName = req.body.projectName?.trim()
- template = req.body.template
- logger.log user: user_id, projectType: template, name: projectName, "creating project"
- async.waterfall [
- (cb)->
- if template == 'example'
- projectCreationHandler.createExampleProject user_id, projectName, cb
- else
- projectCreationHandler.createBasicProject user_id, projectName, cb
- ], (err, project)->
- return next(err) if err?
- logger.log project: project, user: user_id, name: projectName, templateType: template, "created project"
- res.send {project_id:project._id}
-
-
- renameProject: (req, res, next)->
- project_id = req.params.Project_id
- newName = req.body.newProjectName
- editorController.renameProject project_id, newName, (err)->
- return next(err) if err?
- res.sendStatus 200
-
- userProjectsJson: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- ProjectGetter.findAllUsersProjects user_id,
- 'name lastUpdated publicAccesLevel archived owner_ref tokens', (err, projects) ->
- return next(err) if err?
- projects = ProjectController._buildProjectList(projects)
- .filter((p) -> !p.archived)
- .filter((p) -> !p.isV1Project)
- .map((p) -> {_id: p.id, name: p.name, accessLevel: p.accessLevel})
-
- res.json({projects: projects})
-
- projectEntitiesJson: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- project_id = req.params.Project_id
- ProjectGetter.getProject project_id, (err, project) ->
- return next(err) if err?
- ProjectEntityHandler.getAllEntitiesFromProject project, (err, docs, files) ->
- return next(err) if err?
- entities = docs.concat(files)
- .sort (a, b) -> a.path > b.path # Sort by path ascending
- .map (e) -> {
- path: e.path,
- type: if e.doc? then 'doc' else 'file'
- }
- res.json({project_id: project_id, entities: entities})
-
- projectListPage: (req, res, next)->
- timer = new metrics.Timer("project-list")
- user_id = AuthenticationController.getLoggedInUserId(req)
- currentUser = AuthenticationController.getSessionUser(req)
- async.parallel {
- tags: (cb)->
- TagsHandler.getAllTags user_id, cb
- notifications: (cb)->
- NotificationsHandler.getUserNotifications user_id, cb
- projects: (cb)->
- ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated lastUpdatedBy publicAccesLevel archived owner_ref tokens', cb
- v1Projects: (cb) ->
- Modules.hooks.fire "findAllV1Projects", user_id, (error, projects = []) ->
- if error? and error instanceof V1ConnectionError
- return cb(null, projects: [], tags: [], noConnection: true)
- return cb(error, projects[0]) # hooks.fire returns an array of results, only need first
- hasSubscription: (cb)->
- LimitationsManager.hasPaidSubscription currentUser, (error, hasPaidSubscription) ->
- if error? and error instanceof V1ConnectionError
- return cb(null, true)
- return cb(error, hasPaidSubscription)
- user: (cb) ->
- User.findById user_id, "featureSwitches overleaf awareOfV2 features", cb
- userAffiliations: (cb) ->
- getUserAffiliations user_id, cb
- }, (err, results)->
- if err?
- logger.err err:err, "error getting data for project list page"
- return next(err)
- logger.log results:results, user_id:user_id, "rendering project list"
- v1Tags = results.v1Projects?.tags or []
- tags = results.tags[0].concat(v1Tags)
- notifications = require("underscore").map results.notifications, (notification)->
- notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
- return notification
- portalTemplates = ProjectController._buildPortalTemplatesList results.userAffiliations
- projects = ProjectController._buildProjectList results.projects, results.v1Projects?.projects
- user = results.user
- userAffiliations = results.userAffiliations
- warnings = ProjectController._buildWarningsList results.v1Projects
-
- # in v2 add notifications for matching university IPs
- if Settings.overleaf?
- UserGetter.getUser user_id, { 'lastLoginIp': 1 }, (error, user) ->
- if req.ip != user.lastLoginIp
- NotificationsBuilder.ipMatcherAffiliation(user._id, req.ip).create()
-
- ProjectController._injectProjectUsers projects, (error, projects) ->
- return next(error) if error?
- viewModel = {
- title:'your_projects'
- priority_title: true
- projects: projects
- tags: tags
- notifications: notifications or []
- portalTemplates: portalTemplates
- user: user
- userAffiliations: userAffiliations
- hasSubscription: results.hasSubscription
- isShowingV1Projects: results.v1Projects?
- warnings: warnings
- zipFileSizeLimit: Settings.maxUploadSize
- }
-
- if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key?
- viewModel.showUserDetailsArea = true
- viewModel.algolia_api_key = Settings.algolia.read_only_api_key
- viewModel.algolia_app_id = Settings.algolia.app_id
- else
- viewModel.showUserDetailsArea = false
-
- paidUser = user.features?.github and user.features?.dropbox # use a heuristic for paid account
- freeUserProportion = 0.10
- sampleFreeUser = parseInt(user._id.toString().slice(-2), 16) < freeUserProportion * 255
- showFrontWidget = paidUser or sampleFreeUser
- logger.log {paidUser, sampleFreeUser, showFrontWidget}, 'deciding whether to show front widget'
- if showFrontWidget
- viewModel.frontChatWidgetRoomId = Settings.overleaf?.front_chat_widget_room_id
-
- res.render 'project/list', viewModel
- timer.done()
-
-
- loadEditor: (req, res, next)->
- timer = new metrics.Timer("load-editor")
- if !Settings.editorIsOpen
- return res.render("general/closed", {title:"updating_site"})
-
- if AuthenticationController.isUserLoggedIn(req)
- user_id = AuthenticationController.getLoggedInUserId(req)
- anonymous = false
- else
- anonymous = true
- user_id = null
-
- project_id = req.params.Project_id
- logger.log project_id:project_id, anonymous:anonymous, user_id:user_id, "loading editor"
-
- # record failures to load the custom websocket
- if req.query?.ws is 'fallback'
- metrics.inc "load-editor-ws-fallback"
-
- async.auto {
- project: (cb)->
- ProjectGetter.getProject(
- project_id,
- { name: 1, lastUpdated: 1, track_changes: 1, owner_ref: 1, brandVariationId: 1, overleaf: 1, tokens: 1 },
- (err, project) ->
- return cb(err) if err?
- return cb(null, project) unless project.overleaf?.id? and project.tokens?.readAndWrite? and Settings.projectImportingCheckMaxCreateDelta?
- createDelta = (new Date().getTime() - new Date(project._id.getTimestamp()).getTime()) / 1000
- return cb(null, project) unless createDelta < Settings.projectImportingCheckMaxCreateDelta
- V1Handler.getDocExported project.tokens.readAndWrite, (err, doc_exported) ->
- return next err if err?
- project.exporting = doc_exported.exporting
- cb(null, project)
- )
- user: (cb)->
- if !user_id?
- cb null, defaultSettingsForAnonymousUser(user_id)
- else
- User.findById user_id, (err, user)->
- logger.log project_id:project_id, user_id:user_id, "got user"
- cb err, user
- subscription: (cb)->
- if !user_id?
- return cb()
- SubscriptionLocator.getUsersSubscription user_id, cb
- activate: (cb)->
- InactiveProjectManager.reactivateProjectIfRequired project_id, cb
- markAsOpened: (cb)->
- #don't need to wait for this to complete
- ProjectUpdateHandler.markAsOpened project_id, ->
- cb()
- isTokenMember: (cb) ->
- cb = underscore.once(cb)
- if !user_id?
- return cb()
- CollaboratorsHandler.userIsTokenMember user_id, project_id, cb
- brandVariation: [ "project", (cb, results) ->
- if !results.project?.brandVariationId?
- return cb()
- BrandVariationsHandler.getBrandVariationById results.project.brandVariationId, (error, brandVariationDetails) ->
- cb(error, brandVariationDetails)
- ]
- }, (err, results)->
- if err?
- logger.err err:err, "error getting details for project page"
- return next err
- project = results.project
- user = results.user
- subscription = results.subscription
- brandVariation = results.brandVariation
-
- daysSinceLastUpdated = (new Date() - project.lastUpdated) / 86400000
- logger.log project_id:project_id, daysSinceLastUpdated:daysSinceLastUpdated, "got db results for loading editor"
-
- token = TokenAccessHandler.getRequestToken(req, project_id)
- isTokenMember = results.isTokenMember
- AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel)->
- return next(error) if error?
- if !privilegeLevel? or privilegeLevel == PrivilegeLevels.NONE
- return res.sendStatus 401
-
- if project.exporting
- res.render 'project/importing',
- bodyClasses: ["editor"]
- return
-
- if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt?
- allowedFreeTrial = !!subscription.freeTrial.allowed || true
-
- logger.log project_id:project_id, "rendering editor page"
- res.render 'project/editor',
- title: project.name
- priority_title: true
- bodyClasses: ["editor"]
- project_id : project._id
- user : {
- id : user_id
- email : user.email
- first_name : user.first_name
- last_name : user.last_name
- referal_id : user.referal_id
- signUpDate : user.signUpDate
- subscription :
- freeTrial: {allowed: allowedFreeTrial}
- featureSwitches: user.featureSwitches
- features: user.features
- refProviders: user.refProviders
- betaProgram: user.betaProgram
- isAdmin: user.isAdmin
- }
- userSettings: {
- mode : user.ace.mode
- editorTheme : user.ace.theme
- fontSize : user.ace.fontSize
- autoComplete: user.ace.autoComplete
- autoPairDelimiters: user.ace.autoPairDelimiters
- pdfViewer : user.ace.pdfViewer
- syntaxValidation: user.ace.syntaxValidation
- fontFamily: user.ace.fontFamily
- lineHeight: user.ace.lineHeight
- overallTheme: user.ace.overallTheme
- }
- trackChangesState: project.track_changes
- privilegeLevel: privilegeLevel
- chatUrl: Settings.apis.chat.url
- anonymous: anonymous
- anonymousAccessToken: req._anonymousAccessToken
- isTokenMember: isTokenMember
- languages: Settings.languages
- editorThemes: THEME_LIST
- maxDocLength: Settings.max_doc_length
- useV2History: !!project.overleaf?.history?.display
- richTextTrackChangesEnabled: req.query?.rttc == 'true' || user.betaProgram
- showTestControls: req.query?.tc == 'true' || user.isAdmin
- brandVariation: brandVariation
- allowedImageNames: Settings.allowedImageNames || []
- gitBridgePublicBaseUrl: Settings.gitBridgePublicBaseUrl
- timer.done()
-
- _buildProjectList: (allProjects, v1Projects = [])->
- {owned, readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly} = allProjects
- projects = []
- for project in owned
- projects.push ProjectController._buildProjectViewModel(project, "owner", Sources.OWNER)
- # Invite-access
- for project in readAndWrite
- projects.push ProjectController._buildProjectViewModel(project, "readWrite", Sources.INVITE)
- for project in readOnly
- projects.push ProjectController._buildProjectViewModel(project, "readOnly", Sources.INVITE)
- for project in v1Projects
- projects.push ProjectController._buildV1ProjectViewModel(project)
- # Token-access
- # Only add these projects if they're not already present, this gives us cascading access
- # from 'owner' => 'token-read-only'
- for project in tokenReadAndWrite
- if projects.filter((p) -> p.id.toString() == project._id.toString()).length == 0
- projects.push ProjectController._buildProjectViewModel(project, "readAndWrite", Sources.TOKEN)
- for project in tokenReadOnly
- if projects.filter((p) -> p.id.toString() == project._id.toString()).length == 0
- projects.push ProjectController._buildProjectViewModel(project, "readOnly", Sources.TOKEN)
-
- return projects
-
- _buildProjectViewModel: (project, accessLevel, source) ->
- TokenAccessHandler.protectTokens(project, accessLevel)
- model = {
- id: project._id
- name: project.name
- lastUpdated: project.lastUpdated
- lastUpdatedBy: project.lastUpdatedBy
- publicAccessLevel: project.publicAccesLevel
- accessLevel: accessLevel
- source: source
- archived: !!project.archived
- owner_ref: project.owner_ref
- tokens: project.tokens
- isV1Project: false
- }
- return model
-
- _buildV1ProjectViewModel: (project) ->
- projectViewModel = {
- id: project.id
- name: project.title
- lastUpdated: new Date(project.updated_at * 1000) # Convert from epoch
- archived: project.removed || project.archived
- isV1Project: true
- }
- if (project.owner? and project.owner.user_is_owner) or (project.creator? and project.creator.user_is_creator)
- projectViewModel.accessLevel = "owner"
- else
- projectViewModel.accessLevel = "readOnly"
- if project.owner?
- projectViewModel.owner = {
- first_name: project.owner.name
- }
- else if project.creator?
- projectViewModel.owner = {
- first_name: project.creator.name
- }
- return projectViewModel
-
-
- _injectProjectUsers: (projects, callback = (error, projects) ->) ->
- users = {}
- for project in projects
- if project.owner_ref?
- users[project.owner_ref.toString()] = true
- if project.lastUpdatedBy?
- users[project.lastUpdatedBy.toString()] = true
-
- jobs = []
- for user_id, _ of users
- do (user_id) ->
- jobs.push (callback) ->
- UserGetter.getUserOrUserStubById user_id, { first_name: 1, last_name: 1, email: 1 }, (error, user) ->
- return callback(error) if error?
- users[user_id] = user
- callback()
-
- async.series jobs, (error) ->
- for project in projects
- if project.owner_ref?
- project.owner = users[project.owner_ref.toString()]
- if project.lastUpdatedBy?
- project.lastUpdatedBy = users[project.lastUpdatedBy.toString()] or null
- callback null, projects
-
- _buildWarningsList: (v1ProjectData = {}) ->
- warnings = []
- if v1ProjectData.noConnection
- warnings.push 'No V1 Connection'
- if v1ProjectData.hasHiddenV1Projects
- warnings.push "Looks like you've got a lot of V1 projects! Some of them may be hidden on V2. To view them all, use the V1 dashboard."
- return warnings
-
- _buildPortalTemplatesList: (affiliations = []) ->
- portalTemplates = []
- for aff in affiliations
- if aff.portal && aff.portal.slug && aff.portal.templates_count && aff.portal.templates_count > 0
- portalPath = if aff.institution.isUniversity then '/edu/' else '/org/'
- portalTemplates.push({
- name: aff.institution.name
- url: Settings.siteUrl + portalPath + aff.portal.slug
- })
- return portalTemplates
-
-defaultSettingsForAnonymousUser = (user_id)->
- id : user_id
- ace:
- mode:'none'
- theme:'textmate'
- fontSize: '12'
- autoComplete: true
- spellCheckLanguage: ""
- pdfViewer: ""
- syntaxValidation: true
- subscription:
- freeTrial:
- allowed: true
- featureSwitches:
- github: false
-
-THEME_LIST = []
-do generateThemeList = () ->
- files = fs.readdirSync __dirname + '/../../../../public/js/' + PackageVersions.lib('ace')
- for file in files
- if file.slice(-2) == "js" and /^theme-/.test(file)
- cleanName = file.slice(0,-3).slice(6)
- THEME_LIST.push cleanName
diff --git a/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee b/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee
deleted file mode 100644
index a11e1ba93d..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee
+++ /dev/null
@@ -1,131 +0,0 @@
-logger = require('logger-sharelatex')
-async = require("async")
-metrics = require('metrics-sharelatex')
-Settings = require('settings-sharelatex')
-ObjectId = require('mongoose').Types.ObjectId
-Project = require('../../models/Project').Project
-Folder = require('../../models/Folder').Folder
-ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
-ProjectDetailsHandler = require('./ProjectDetailsHandler')
-HistoryManager = require('../History/HistoryManager')
-User = require('../../models/User').User
-fs = require('fs')
-Path = require "path"
-_ = require "underscore"
-AnalyticsManger = require("../Analytics/AnalyticsManager")
-
-module.exports = ProjectCreationHandler =
-
- createBlankProject : (owner_id, projectName, attributes, callback = (error, project) ->)->
- metrics.inc("project-creation")
- if arguments.length == 3
- callback = attributes
- attributes = null
-
- ProjectDetailsHandler.validateProjectName projectName, (error) ->
- return callback(error) if error?
- logger.log owner_id:owner_id, projectName:projectName, "creating blank project"
- if attributes?
- ProjectCreationHandler._createBlankProject owner_id, projectName, attributes, (error, project) ->
- return callback(error) if error?
- AnalyticsManger.recordEvent(
- owner_id, 'project-imported', { projectId: project._id, attributes: attributes }
- )
- callback(error, project)
- else
- HistoryManager.initializeProject (error, history) ->
- return callback(error) if error?
- attributes = overleaf: history: id: history?.overleaf_id
- ProjectCreationHandler._createBlankProject owner_id, projectName, attributes, (error, project) ->
- return callback(error) if error?
- AnalyticsManger.recordEvent(
- owner_id, 'project-created', { projectId: project._id }
- )
- callback(error, project)
-
- _createBlankProject : (owner_id, projectName, attributes, callback = (error, project) ->)->
- rootFolder = new Folder {'name':'rootFolder'}
-
- attributes.owner_ref = new ObjectId(owner_id)
- attributes.name = projectName
- project = new Project attributes
-
- Object.assign(project, attributes)
-
- if Settings.apis?.project_history?.displayHistoryForNewProjects
- project.overleaf.history.display = true
- if Settings.currentImageName?
- # avoid clobbering any imageName already set in attributes (e.g. importedImageName)
- project.imageName ?= Settings.currentImageName
- project.rootFolder[0] = rootFolder
- User.findById owner_id, "ace.spellCheckLanguage", (err, user)->
- if user? # It's possible the owner_id is a UserStub
- project.spellCheckLanguage = user.ace.spellCheckLanguage
- project.save (err)->
- return callback(err) if err?
- callback err, project
-
- createProjectFromSnippet : (owner_id, projectName, docLines, callback = (error, project) ->)->
- @createBlankProject owner_id, projectName, (error, project)->
- return callback(error) if error?
- ProjectCreationHandler._createRootDoc project, owner_id, docLines, callback
-
- createBasicProject : (owner_id, projectName, callback = (error, project) ->)->
- self = @
- @createBlankProject owner_id, projectName, (error, project)->
- return callback(error) if error?
- self._buildTemplate "mainbasic.tex", owner_id, projectName, (error, docLines)->
- return callback(error) if error?
- ProjectCreationHandler._createRootDoc project, owner_id, docLines, callback
-
- createExampleProject: (owner_id, projectName, callback = (error, project) ->)->
- self = @
- @createBlankProject owner_id, projectName, (error, project)->
- return callback(error) if error?
- async.series [
- (callback) ->
- self._buildTemplate "main.tex", owner_id, projectName, (error, docLines)->
- return callback(error) if error?
- ProjectCreationHandler._createRootDoc project, owner_id, docLines, callback
- (callback) ->
- self._buildTemplate "references.bib", owner_id, projectName, (error, docLines)->
- return callback(error) if error?
- ProjectEntityUpdateHandler.addDoc project._id, project.rootFolder[0]._id, "references.bib", docLines, owner_id, (error, doc)->
- callback(error)
- (callback) ->
- universePath = Path.resolve(__dirname + "/../../../templates/project_files/universe.jpg")
- ProjectEntityUpdateHandler.addFile project._id, project.rootFolder[0]._id, "universe.jpg", universePath, null, owner_id, callback
- ], (error) ->
- callback(error, project)
-
- _createRootDoc: (project, owner_id, docLines, callback = (error, project) ->)->
- ProjectEntityUpdateHandler.addDoc project._id, project.rootFolder[0]._id, "main.tex", docLines, owner_id, (error, doc)->
- if error?
- logger.err err:error, "error adding root doc when creating project"
- return callback(error)
- ProjectEntityUpdateHandler.setRootDoc project._id, doc._id, (error) ->
- callback(error, project)
-
- _buildTemplate: (template_name, user_id, project_name, callback = (error, output) ->)->
- User.findById user_id, "first_name last_name", (error, user)->
- return callback(error) if error?
- monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]
-
- templatePath = Path.resolve(__dirname + "/../../../templates/project_files/#{template_name}")
- fs.readFile templatePath, (error, template) ->
- return callback(error) if error?
- data =
- project_name: project_name
- user: user
- year: new Date().getUTCFullYear()
- month: monthNames[new Date().getUTCMonth()]
- output = _.template(template.toString(), data)
- callback null, output.split("\n")
-
-metrics.timeAsyncMethod(
- ProjectCreationHandler, 'createBlankProject',
- 'mongo.ProjectCreationHandler',
- logger
-)
-
-
diff --git a/services/web/app/coffee/Features/Project/ProjectDeleter.coffee b/services/web/app/coffee/Features/Project/ProjectDeleter.coffee
deleted file mode 100644
index 3ae188173f..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectDeleter.coffee
+++ /dev/null
@@ -1,92 +0,0 @@
-Project = require('../../models/Project').Project
-DeletedProject = require('../../models/DeletedProject').DeletedProject
-logger = require('logger-sharelatex')
-documentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-tagsHandler = require("../Tags/TagsHandler")
-async = require("async")
-FileStoreHandler = require("../FileStore/FileStoreHandler")
-CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler")
-
-module.exports = ProjectDeleter =
-
- markAsDeletedByExternalSource : (project_id, callback = (error) ->)->
- logger.log project_id:project_id, "marking project as deleted by external data source"
- conditions = {_id:project_id}
- update = {deletedByExternalDataSource:true}
-
- Project.update conditions, update, {}, (err)->
- require('../Editor/EditorController').notifyUsersProjectHasBeenDeletedOrRenamed project_id, ->
- callback()
-
- unmarkAsDeletedByExternalSource: (project_id, callback = (error) ->) ->
- logger.log project_id: project_id, "removing flag marking project as deleted by external data source"
- conditions = {_id:project_id.toString()}
- update = {deletedByExternalDataSource: false}
- Project.update conditions, update, {}, callback
-
- deleteUsersProjects: (user_id, callback) ->
- logger.log {user_id}, "deleting users projects"
-
- Project.find {owner_ref: user_id}, (error, projects) ->
- return callback(error) if error?
- async.each(
- projects,
- (project, cb) ->
- ProjectDeleter.deleteProject project._id, cb
- (err) ->
- return callback(err) if err?
- CollaboratorsHandler.removeUserFromAllProjets user_id, callback
- )
-
- deleteProject: (project_id, options = {}, callback = (error) ->) ->
- data = {}
- logger.log project_id: project_id, "deleting project"
-
- if typeof options == 'function'
- callback = options
- options = {}
-
- async.waterfall [
- (cb) ->
- Project.findOne {_id: project_id}, (err, project) -> cb(err, project)
- (project, cb) ->
- deletedProject = new DeletedProject()
- deletedProject.project = project
- deletedProject.deleterData =
- deletedAt: new Date()
- deleterId: options.deleterUser?._id
- deleterIpAddress: options.ipAddress
-
- return callback(new Errors.NotFoundError("project not found")) unless project?
-
- deletedProject.save (err) ->
- cb(err, deletedProject)
- (deletedProject, cb) ->
- documentUpdaterHandler.flushProjectToMongoAndDelete project_id, (err) ->
- cb(err, deletedProject)
- (deletedProject, cb) ->
- CollaboratorsHandler.getMemberIds project_id, (error, member_ids = []) ->
- for member_id in member_ids
- tagsHandler.removeProjectFromAllTags member_id, project_id, (err)->
- cb(null, deletedProject) #doesn't matter if this fails or the order it happens in
- (deletedProject, cb) ->
- Project.remove _id: project_id, (err) ->
- cb(err, deletedProject)
- ], (err, deletedProject) ->
- if err?
- logger.err err:err, "problem deleting project"
- return callback(err)
- logger.log project_id:project_id, "successfully deleting project from user request"
- callback(null, deletedProject)
-
- archiveProject: (project_id, callback = (error) ->)->
- logger.log project_id:project_id, "archived project from user request"
- Project.update {_id:project_id}, { $set: { archived: true }}, (err)->
- if err?
- logger.err err:err, "problem archived project"
- return callback(err)
- logger.log project_id:project_id, "successfully archived project from user request"
- callback()
-
- restoreProject: (project_id, callback = (error) ->) ->
- Project.update {_id:project_id}, { $unset: { archived: true }}, callback
diff --git a/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee b/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee
deleted file mode 100644
index 172b925425..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee
+++ /dev/null
@@ -1,184 +0,0 @@
-ProjectGetter = require("./ProjectGetter")
-UserGetter = require("../User/UserGetter")
-Project = require('../../models/Project').Project
-ObjectId = require("mongojs").ObjectId
-logger = require("logger-sharelatex")
-tpdsUpdateSender = require '../ThirdPartyDataStore/TpdsUpdateSender'
-_ = require("underscore")
-PublicAccessLevels = require("../Authorization/PublicAccessLevels")
-Errors = require("../Errors/Errors")
-ProjectTokenGenerator = require('./ProjectTokenGenerator')
-ProjectEntityHandler = require('./ProjectEntityHandler')
-ProjectHelper = require('./ProjectHelper')
-CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
-settings = require('settings-sharelatex')
-
-
-module.exports = ProjectDetailsHandler =
- getDetails: (project_id, callback)->
- ProjectGetter.getProject project_id, {name:true, description:true, compiler:true, features:true, owner_ref:true, overleaf:true}, (err, project)->
- if err?
- logger.err err:err, project_id:project_id, "error getting project"
- return callback(err)
- return callback(new Errors.NotFoundError("project not found")) if !project?
- UserGetter.getUser project.owner_ref, (err, user) ->
- return callback(err) if err?
- details =
- name : project.name
- description: project.description
- compiler: project.compiler
- features: user?.features or settings.defaultFeatures
-
- if project.overleaf?
- details.overleaf = project.overleaf
-
- logger.log project_id:project_id, details: details, "getting project details"
- callback(err, details)
-
- getProjectDescription: (project_id, callback)->
- ProjectGetter.getProject project_id, description: true, (err, project)->
- callback(err, project?.description)
-
- setProjectDescription: (project_id, description, callback)->
- conditions = _id:project_id
- update = description:description
- logger.log conditions:conditions, update:update, project_id:project_id, description:description, "setting project description"
- Project.update conditions, update, (err)->
- if err?
- logger.err err:err, "something went wrong setting project description"
- callback(err)
-
- transferOwnership: (project_id, user_id, suffix = "", callback)->
- if typeof suffix is 'function'
- callback = suffix
- suffix = ''
- ProjectGetter.getProject project_id, {owner_ref: true, name: true}, (err, project)->
- return callback(err) if err?
- return callback(new Errors.NotFoundError("project not found")) unless project?
- return callback() if project.owner_ref == user_id
-
- UserGetter.getUser user_id, (err, user) ->
- return callback(err) if err?
- return callback(new Errors.NotFoundError("user not found")) unless user?
-
- # we make sure the user to which the project is transferred is not a collaborator for the project,
- # this prevents any conflict during unique name generation
- CollaboratorsHandler.removeUserFromProject project_id, user_id, (err) ->
- return callback(err) if err?
- ProjectDetailsHandler.generateUniqueName user_id, project.name + suffix, (err, name) ->
- return callback(err) if err?
- Project.update {_id: project_id},
- {
- $set: {
- owner_ref: user_id,
- name: name
- }
- }, (err) ->
- return callback(err) if err?
- ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, callback
-
- renameProject: (project_id, newName, callback = ->)->
- ProjectDetailsHandler.validateProjectName newName, (error) ->
- return callback(error) if error?
- logger.log project_id: project_id, newName:newName, "renaming project"
- ProjectGetter.getProject project_id, {name:true}, (err, project)->
- if err? or !project?
- logger.err err:err, project_id:project_id, "error getting project or could not find it todo project rename"
- return callback(err)
- oldProjectName = project.name
- Project.update _id:project_id, {name: newName}, (err, project)=>
- if err?
- return callback(err)
- tpdsUpdateSender.moveEntity {project_id:project_id, project_name:oldProjectName, newProjectName:newName}, callback
-
- MAX_PROJECT_NAME_LENGTH: 150
- validateProjectName: (name, callback = (error) ->) ->
- if !name? or name.length == 0
- return callback(new Errors.InvalidNameError("Project name cannot be blank"))
- else if name.length > @MAX_PROJECT_NAME_LENGTH
- return callback(new Errors.InvalidNameError("Project name is too long"))
- else if name.indexOf("/") > -1
- return callback(new Errors.InvalidNameError("Project name cannot contain / characters"))
- else if name.indexOf("\\") > -1
- return callback(new Errors.InvalidNameError("Project name cannot contain \\ characters"))
- else
- return callback()
-
- generateUniqueName: (user_id, name, suffixes = [], callback = (error, newName) -> ) ->
- if arguments.length is 3 && typeof suffixes is 'function' # make suffixes an optional argument
- callback = suffixes
- suffixes = []
- ProjectDetailsHandler.ensureProjectNameIsUnique user_id, name, suffixes, callback
-
- # FIXME: we should put a lock around this to make it completely safe, but we would need to do that at
- # the point of project creation, rather than just checking the name at the start of the import.
- # If we later move this check into ProjectCreationHandler we can ensure all new projects are created
- # with a unique name. But that requires thinking through how we would handle incoming projects from
- # dropbox for example.
- ensureProjectNameIsUnique: (user_id, name, suffixes = [], callback = (error, name, changed)->) ->
- ProjectGetter.findAllUsersProjects user_id, {name: 1}, (error, allUsersProjectNames) ->
- return callback(error) if error?
- # allUsersProjectNames is returned as a hash {owned: [name1, name2, ...], readOnly: [....]}
- # collect all of the names and flatten them into a single array
- projectNameList = _.pluck(_.flatten(_.values(allUsersProjectNames)),'name')
- ProjectHelper.ensureNameIsUnique projectNameList, name, suffixes, ProjectDetailsHandler.MAX_PROJECT_NAME_LENGTH, callback
-
- fixProjectName: (name) ->
- if name == "" || !name
- name = "Untitled"
- if name.indexOf('/') > -1
- # v2 does not allow / in a project name
- name = name.replace(/\//g, '-')
- if name.indexOf('\\') > -1
- # backslashes in project name will prevent syncing to dropbox
- name = name.replace(/\\/g, '')
- if name.length > @MAX_PROJECT_NAME_LENGTH
- name = name.substr(0, @MAX_PROJECT_NAME_LENGTH)
- return name
-
- setPublicAccessLevel : (project_id, newAccessLevel, callback = ->)->
- logger.log project_id: project_id, level: newAccessLevel, "set public access level"
- # DEPRECATED: `READ_ONLY` and `READ_AND_WRITE` are still valid in, but should no longer
- # be passed here. Remove after token-based access has been live for a while
- if project_id? && newAccessLevel? and _.include [
- PublicAccessLevels.READ_ONLY,
- PublicAccessLevels.READ_AND_WRITE,
- PublicAccessLevels.PRIVATE,
- PublicAccessLevels.TOKEN_BASED
- ], newAccessLevel
- Project.update {_id:project_id},{publicAccesLevel:newAccessLevel}, (err)->
- callback(err)
-
- ensureTokensArePresent: (project_id, callback=(err, tokens)->) ->
- ProjectGetter.getProject project_id, {tokens: 1}, (err, project) ->
- return callback(err) if err?
- if project.tokens? and project.tokens.readOnly? and project.tokens.readAndWrite?
- logger.log {project_id}, "project already has tokens"
- return callback(null, project.tokens)
- else
- logger.log {
- project_id,
- has_tokens: project.tokens?,
- has_readOnly: project?.tokens?.readOnly?,
- has_readAndWrite: project?.tokens?.readAndWrite?
- }, "generating tokens for project"
- ProjectDetailsHandler._generateTokens project, (err) ->
- return callback(err) if err?
- Project.update {_id: project_id}, {$set: {tokens: project.tokens}}, (err) ->
- return callback(err) if err?
- callback(null, project.tokens)
-
- _generateTokens: (project, callback=(err)->) ->
- project.tokens ||= {}
- tokens = project.tokens
- if !tokens.readAndWrite?
- { token, numericPrefix } = ProjectTokenGenerator.readAndWriteToken()
- tokens.readAndWrite = token
- tokens.readAndWritePrefix = numericPrefix
- if !tokens.readOnly?
- ProjectTokenGenerator.generateUniqueReadOnlyToken (err, token) ->
- return callback(err) if err?
- tokens.readOnly = token
- callback()
- else
- callback()
diff --git a/services/web/app/coffee/Features/Project/ProjectDuplicator.coffee b/services/web/app/coffee/Features/Project/ProjectDuplicator.coffee
deleted file mode 100644
index d461ed4699..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectDuplicator.coffee
+++ /dev/null
@@ -1,125 +0,0 @@
-projectCreationHandler = require('./ProjectCreationHandler')
-ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
-projectLocator = require('./ProjectLocator')
-projectOptionsHandler = require('./ProjectOptionsHandler')
-projectDeleter = require('./ProjectDeleter')
-DocumentUpdaterHandler = require("../DocumentUpdater/DocumentUpdaterHandler")
-DocstoreManager = require "../Docstore/DocstoreManager"
-ProjectGetter = require("./ProjectGetter")
-_ = require('underscore')
-async = require('async')
-logger = require("logger-sharelatex")
-
-
-module.exports = ProjectDuplicator =
-
- _copyDocs: (owner_id, newProject, originalRootDoc, originalFolder, desFolder, docContents, callback)->
- setRootDoc = _.once (doc_id)->
- ProjectEntityUpdateHandler.setRootDoc newProject._id, doc_id
- docs = originalFolder.docs or []
- jobs = docs.map (doc)->
- return (cb)->
- if !doc?._id?
- return callback()
- content = docContents[doc._id.toString()]
- ProjectEntityUpdateHandler.addDoc newProject._id, desFolder._id, doc.name, content.lines, owner_id, (err, newDoc)->
- if err?
- logger.err err:err, "error copying doc"
- return callback(err)
- if originalRootDoc? and newDoc.name == originalRootDoc.name
- setRootDoc newDoc._id
- cb()
-
- async.series jobs, callback
-
- _copyFiles: (owner_id, newProject, originalProject_id, originalFolder, desFolder, callback)->
- fileRefs = originalFolder.fileRefs or []
- firstError = null # track first error to exit gracefully from parallel copy
- jobs = fileRefs.map (file)->
- return (cb)->
- return async.setImmediate(cb) if firstError? # skip further copies if an error has occurred
- ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject newProject._id, newProject, desFolder._id, originalProject_id, file, owner_id, (err) ->
- firstError ||= err if err? # set the error flag if this copy failed
- return cb()
- # If one of these jobs fails then we wait until all running jobs have
- # finished, skipping those which have not started yet. We need to wait
- # for all the copy jobs to finish to avoid them writing to the project
- # entry in the background while we are deleting it.
- async.parallelLimit jobs, 5, (err) ->
- return callback(firstError) if firstError?
- return callback(err) if err? # shouldn't happen
- return callback()
-
-
- _copyFolderRecursivly: (owner_id, newProject_id, originalProject_id, originalRootDoc, originalFolder, desFolder, docContents, callback)->
- ProjectGetter.getProject newProject_id, {rootFolder:true, name:true}, (err, newProject)->
- if err?
- logger.err project_id:newProject_id, "could not get project"
- return callback(err)
-
- folders = originalFolder.folders or []
-
- jobs = folders.map (childFolder)->
- return (cb)->
- if !childFolder?._id?
- return cb()
- ProjectEntityUpdateHandler.addFolder newProject._id, desFolder?._id, childFolder.name, (err, newFolder)->
- return cb(err) if err?
- ProjectDuplicator._copyFolderRecursivly owner_id, newProject_id, originalProject_id, originalRootDoc, childFolder, newFolder, docContents, cb
-
- jobs.push (cb)->
- ProjectDuplicator._copyFiles owner_id, newProject, originalProject_id, originalFolder, desFolder, cb
- jobs.push (cb)->
- ProjectDuplicator._copyDocs owner_id, newProject, originalRootDoc, originalFolder, desFolder, docContents, cb
-
- async.series jobs, callback
-
- duplicate: (owner, originalProject_id, newProjectName, callback)->
-
- jobs =
- flush: (cb)->
- DocumentUpdaterHandler.flushProjectToMongo originalProject_id, cb
- originalProject: (cb)->
- ProjectGetter.getProject originalProject_id, {compiler:true, rootFolder:true, rootDoc_id:true}, cb
- originalRootDoc: (cb)->
- projectLocator.findRootDoc {project_id:originalProject_id}, cb
- docContentsArray: (cb)->
- DocstoreManager.getAllDocs originalProject_id, cb
-
- # Get the contents of the original project first
- async.series jobs, (err, results)->
- if err?
- logger.err err:err, originalProject_id:originalProject_id, "error duplicating project reading original project"
- return callback(err)
- {originalProject, originalRootDoc, docContentsArray} = results
-
- originalRootDoc = originalRootDoc?[0]
-
- docContents = {}
- for docContent in docContentsArray
- docContents[docContent._id] = docContent
-
- # Now create the new project, cleaning it up on failure if necessary
- projectCreationHandler.createBlankProject owner._id, newProjectName, (err, newProject) ->
- if err?
- logger.err err:err, originalProject_id:originalProject_id, "error duplicating project when creating new project"
- return callback(err)
-
- copyJobs =
- setCompiler: (cb) ->
- projectOptionsHandler.setCompiler newProject._id, originalProject.compiler, cb
- copyFiles: (cb) ->
- ProjectDuplicator._copyFolderRecursivly owner._id, newProject._id, originalProject_id, originalRootDoc, originalProject.rootFolder[0], newProject.rootFolder[0], docContents, cb
-
- # Copy the contents of the original project into the new project
- async.series copyJobs, (err) ->
- if err?
- logger.err err:err, originalProject_id:originalProject_id, newProjectName:newProjectName, newProject_id: newProject._id, "error cloning project, will delete broken clone"
- # Clean up broken clone on error.
- # Make sure we delete the new failed project, not the original one!
- projectDeleter.deleteProject newProject._id, (delete_err) ->
- if delete_err?
- logger.error newProject_id: newProject._id, delete_err:delete_err, "error deleting broken clone of project"
- callback(err)
- else
- callback(null, newProject)
diff --git a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee
deleted file mode 100644
index f81c59c399..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee
+++ /dev/null
@@ -1,93 +0,0 @@
-_ = require("underscore")
-Path = require 'path'
-
-module.exports = ProjectEditorHandler =
- trackChangesAvailable: false
-
- buildProjectModelView: (project, members, invites) ->
- result =
- _id : project._id
- name : project.name
- rootDoc_id : project.rootDoc_id
- rootFolder : [@buildFolderModelView project.rootFolder[0]]
- publicAccesLevel : project.publicAccesLevel
- dropboxEnabled : !!project.existsInDropbox
- compiler : project.compiler
- description: project.description
- spellCheckLanguage: project.spellCheckLanguage
- deletedByExternalDataSource : project.deletedByExternalDataSource || false
- deletedDocs: project.deletedDocs
- members: []
- invites: invites
- tokens: project.tokens
- imageName: if project.imageName? then Path.basename(project.imageName) else undefined
-
- if !result.invites?
- result.invites = []
-
- {owner, ownerFeatures, members} = @buildOwnerAndMembersViews(members)
- result.owner = owner
- result.members = members
-
- result.features = _.defaults(ownerFeatures or {}, {
- collaborators: -1 # Infinite
- versioning: false
- dropbox:false
- compileTimeout: 60
- compileGroup:"standard"
- templates: false
- references: false
- referencesSearch: false
- mendeley: false
- trackChanges: false
- trackChangesVisible: ProjectEditorHandler.trackChangesAvailable
- })
-
- # Originally these two feature flags were both signalled by the now-deprecated `references` flag.
- # For older users, the presence of the `references` feature flag should still turn on these features.
- result.features.referencesSearch = result.features.referencesSearch or result.features.references
- result.features.mendeley = result.features.mendeley or result.features.references
-
- return result
-
- buildOwnerAndMembersViews: (members) ->
- owner = null
- ownerFeatures = null
- filteredMembers = []
- for member in (members || [])
- if member.privilegeLevel == "owner"
- ownerFeatures = member.user.features
- owner = @buildUserModelView member.user, "owner"
- else
- filteredMembers.push @buildUserModelView member.user, member.privilegeLevel
- return {
- owner: owner,
- ownerFeatures: ownerFeatures,
- members: filteredMembers,
- }
-
- buildUserModelView: (user, privileges) ->
- _id : user._id
- first_name : user.first_name
- last_name : user.last_name
- email : user.email
- privileges : privileges
- signUpDate : user.signUpDate
-
- buildFolderModelView: (folder) ->
- fileRefs = _.filter (folder.fileRefs or []), (file)-> file?
- _id : folder._id
- name : folder.name
- folders : @buildFolderModelView childFolder for childFolder in (folder.folders or [])
- fileRefs : @buildFileModelView file for file in fileRefs
- docs : @buildDocModelView doc for doc in (folder.docs or [])
-
- buildFileModelView: (file) ->
- _id : file._id
- name : file.name
- linkedFileData: file.linkedFileData
- created: file.created
-
- buildDocModelView: (doc) ->
- _id : doc._id
- name : doc.name
diff --git a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee
deleted file mode 100644
index 55ce199312..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee
+++ /dev/null
@@ -1,136 +0,0 @@
-_ = require('underscore')
-async = require "async"
-path = require "path"
-logger = require('logger-sharelatex')
-DocstoreManager = require "../Docstore/DocstoreManager"
-DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
-Errors = require '../Errors/Errors'
-Project = require('../../models/Project').Project
-ProjectGetter = require "./ProjectGetter"
-TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-
-module.exports = ProjectEntityHandler = self =
- getAllDocs: (project_id, callback) ->
- logger.log project_id:project_id, "getting all docs for project"
-
- # We get the path and name info from the project, and the lines and
- # version info from the doc store.
- DocstoreManager.getAllDocs project_id, (error, docContentsArray) ->
- return callback(error) if error?
-
- # Turn array from docstore into a dictionary based on doc id
- docContents = {}
- for docContent in docContentsArray
- docContents[docContent._id] = docContent
-
- self._getAllFolders project_id, (error, folders = {}) ->
- return callback(error) if error?
- docs = {}
- for folderPath, folder of folders
- for doc in (folder.docs or [])
- content = docContents[doc._id.toString()]
- if content?
- docs[path.join(folderPath, doc.name)] = {
- _id: doc._id
- name: doc.name
- lines: content.lines
- rev: content.rev
- }
- logger.log count:_.keys(docs).length, project_id:project_id, "returning docs for project"
- callback null, docs
-
- getAllFiles: (project_id, callback) ->
- logger.log project_id:project_id, "getting all files for project"
- self._getAllFolders project_id, (err, folders = {}) ->
- return callback(err) if err?
- files = {}
- for folderPath, folder of folders
- for file in (folder.fileRefs or [])
- if file?
- files[path.join(folderPath, file.name)] = file
- callback null, files
-
- getAllEntities: (project_id, callback) ->
- ProjectGetter.getProject project_id, (err, project) ->
- return callback(err) if err?
- self.getAllEntitiesFromProject project, callback
-
- getAllEntitiesFromProject: (project, callback) ->
- logger.log project:project, "getting all entities for project"
- self._getAllFoldersFromProject project, (err, folders = {}) ->
- return callback(err) if err?
- docs = []
- files = []
- for folderPath, folder of folders
- for doc in (folder.docs or [])
- if doc?
- docs.push({path: path.join(folderPath, doc.name), doc:doc})
- for file in (folder.fileRefs or [])
- if file?
- files.push({path: path.join(folderPath, file.name), file:file})
- callback null, docs, files
-
- getAllDocPathsFromProjectById: (project_id, callback) ->
- ProjectGetter.getProjectWithoutDocLines project_id, (err, project) ->
- return callback(err) if err?
- return callback(Errors.NotFoundError("no project")) if !project?
- self.getAllDocPathsFromProject project, callback
-
- getAllDocPathsFromProject: (project, callback) ->
- logger.log project:project, "getting all docs for project"
- self._getAllFoldersFromProject project, (err, folders = {}) ->
- return callback(err) if err?
- docPath = {}
- for folderPath, folder of folders
- for doc in (folder.docs or [])
- docPath[doc._id] = path.join(folderPath, doc.name)
- logger.log count:_.keys(docPath).length, project_id:project._id, "returning docPaths for project"
- callback null, docPath
-
- flushProjectToThirdPartyDataStore: (project_id, callback) ->
- logger.log project_id:project_id, "flushing project to tpds"
- DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
- return callback(error) if error?
- ProjectGetter.getProject project_id, {name:true}, (error, project) ->
- return callback(error) if error?
- requests = []
- self.getAllDocs project_id, (error, docs) ->
- return callback(error) if error?
- for docPath, doc of docs
- do (docPath, doc) ->
- requests.push (cb) ->
- TpdsUpdateSender.addDoc {project_id:project_id, doc_id:doc._id, path:docPath, project_name:project.name, rev:doc.rev||0}, cb
- self.getAllFiles project_id, (error, files) ->
- return callback(error) if error?
- for filePath, file of files
- do (filePath, file) ->
- requests.push (cb) ->
- TpdsUpdateSender.addFile {project_id:project_id, file_id:file._id, path:filePath, project_name:project.name, rev:file.rev}, cb
- async.series requests, (err) ->
- logger.log project_id:project_id, "finished flushing project to tpds"
- callback(err)
-
- getDoc: (project_id, doc_id, options = {}, callback = (error, lines, rev) ->) ->
- if typeof(options) == "function"
- callback = options
- options = {}
-
- DocstoreManager.getDoc project_id, doc_id, options, callback
-
- _getAllFolders: (project_id, callback) ->
- logger.log project_id:project_id, "getting all folders for project"
- ProjectGetter.getProjectWithoutDocLines project_id, (err, project) ->
- return callback(err) if err?
- return callback(Errors.NotFoundError("no project")) if !project?
- self._getAllFoldersFromProject project, callback
-
- _getAllFoldersFromProject: (project, callback) ->
- folders = {}
- processFolder = (basePath, folder) ->
- folders[basePath] = folder
- for childFolder in (folder.folders or [])
- if childFolder.name?
- processFolder path.join(basePath, childFolder.name), childFolder
-
- processFolder "/", project.rootFolder[0]
- callback null, folders
diff --git a/services/web/app/coffee/Features/Project/ProjectEntityMongoUpdateHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityMongoUpdateHandler.coffee
deleted file mode 100644
index 74b52f5892..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectEntityMongoUpdateHandler.coffee
+++ /dev/null
@@ -1,386 +0,0 @@
-_ = require('underscore')
-async = require 'async'
-logger = require('logger-sharelatex')
-path = require('path')
-settings = require('settings-sharelatex')
-CooldownManager = require '../Cooldown/CooldownManager'
-Errors = require '../Errors/Errors'
-Folder = require('../../models/Folder').Folder
-LockManager = require('../../infrastructure/LockManager')
-Project = require('../../models/Project').Project
-ProjectEntityHandler = require('./ProjectEntityHandler')
-ProjectGetter = require('./ProjectGetter')
-ProjectLocator = require('./ProjectLocator')
-SafePath = require './SafePath'
-
-LOCK_NAMESPACE = "mongoTransaction"
-
-wrapWithLock = (methodWithoutLock) ->
- # This lock is used whenever we read or write to an existing project's
- # structure. Some operations to project structure cannot be done atomically
- # in mongo, this lock is used to prevent reading the structure between two
- # parts of a staged update.
- methodWithLock = (project_id, args..., callback) ->
- LockManager.runWithLock LOCK_NAMESPACE, project_id,
- (cb) -> methodWithoutLock project_id, args..., cb
- callback
- methodWithLock.withoutLock = methodWithoutLock
- methodWithLock
-
-module.exports = ProjectEntityMongoUpdateHandler = self =
- LOCK_NAMESPACE: LOCK_NAMESPACE
-
- addDoc: wrapWithLock (project_id, folder_id, doc, callback = (err, result) ->) ->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (err, project) ->
- if err?
- logger.err project_id:project_id, err:err, "error getting project for add doc"
- return callback(err)
- logger.log project_id: project_id, folder_id: folder_id, doc_name: doc.name, "adding doc to project with project"
- self._confirmFolder project, folder_id, (folder_id) =>
- self._putElement project, folder_id, doc, "doc", callback
-
- addFile: wrapWithLock (project_id, folder_id, fileRef, callback = (error, result, project) ->)->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (err, project) ->
- if err?
- logger.err project_id:project_id, err:err, "error getting project for add file"
- return callback(err)
- logger.log project_id: project._id, folder_id: folder_id, file_name: fileRef.name, "adding file"
- self._confirmFolder project, folder_id, (folder_id)->
- self._putElement project, folder_id, fileRef, "file", callback
-
- replaceFileWithNew: wrapWithLock (project_id, file_id, newFileRef, callback) ->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (err, project) ->
- return callback(err) if err?
- ProjectLocator.findElement {project:project, element_id: file_id, type: 'file'}, (err, fileRef, path)=>
- return callback(err) if err?
- ProjectEntityMongoUpdateHandler._insertDeletedFileReference project_id, fileRef, (err) ->
- return callback(err) if err?
- conditions = _id:project._id
- inc = {}
- # increment the project structure version as we are adding a new file here
- inc['version'] = 1
- set = {}
- set["#{path.mongo}._id"] = newFileRef._id
- set["#{path.mongo}.created"] = new Date()
- set["#{path.mongo}.linkedFileData"] = newFileRef.linkedFileData
- inc["#{path.mongo}.rev"] = 1
- set["#{path.mongo}.hash"] = newFileRef.hash
- update =
- "$inc": inc
- "$set": set
- # Note: Mongoose uses new:true to return the modified document
- # https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
- # but Mongo uses returnNewDocument:true instead
- # https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/
- # We are using Mongoose here, but if we ever switch to a direct mongo call
- # the next line will need to be updated.
- Project.findOneAndUpdate conditions, update, {new:true}, (err, newProject) ->
- return callback(err) if err?
- callback null, fileRef, project, path, newProject
-
- mkdirp: wrapWithLock (project_id, path, options, callback) ->
- # defaults to case insensitive paths, use options {exactCaseMatch:true}
- # to make matching case-sensitive
- folders = path.split('/')
- folders = _.select folders, (folder)->
- return folder.length != 0
-
- ProjectGetter.getProjectWithOnlyFolders project_id, (err, project)=>
- if path == '/'
- logger.log project_id: project._id, "mkdir is only trying to make path of / so sending back root folder"
- return callback(null, [], project.rootFolder[0])
- logger.log project_id: project._id, path:path, folders:folders, "running mkdirp"
-
- builtUpPath = ''
- procesFolder = (previousFolders, folderName, callback)=>
- previousFolders = previousFolders || []
- parentFolder = previousFolders[previousFolders.length-1]
- if parentFolder?
- parentFolder_id = parentFolder._id
- builtUpPath = "#{builtUpPath}/#{folderName}"
- ProjectLocator.findElementByPath project: project, path: builtUpPath, exactCaseMatch: options?.exactCaseMatch, (err, foundFolder)=>
- if !foundFolder?
- logger.log path:path, project_id:project._id, folderName:folderName, "making folder from mkdirp"
- self.addFolder.withoutLock project_id, parentFolder_id, folderName, (err, newFolder, parentFolder_id)->
- return callback(err) if err?
- newFolder.parentFolder_id = parentFolder_id
- previousFolders.push newFolder
- callback null, previousFolders
- else
- foundFolder.filterOut = true
- previousFolders.push foundFolder
- callback null, previousFolders
-
- async.reduce folders, [], procesFolder, (err, folders) ->
- return callback(err) if err?
- lastFolder = folders[folders.length-1]
- folders = _.select folders, (folder)->
- !folder.filterOut
- callback null, folders, lastFolder
-
- moveEntity: wrapWithLock (project_id, entity_id, destFolderId, entityType, callback = (error) ->) ->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (err, project) ->
- return callback(err) if err?
- ProjectLocator.findElement {project, element_id: entity_id, type: entityType}, (err, entity, entityPath)->
- return callback(err) if err?
- # Prevent top-level docs/files with reserved names (to match v1 behaviour)
- if self._blockedFilename entityPath, entityType
- return callback new Errors.InvalidNameError("blocked element name")
- self._checkValidMove project, entityType, entity, entityPath, destFolderId, (error) ->
- return callback(error) if error?
- ProjectEntityHandler.getAllEntitiesFromProject project, (error, oldDocs, oldFiles) ->
- return callback(error) if error?
- # For safety, insert the entity in the destination
- # location first, and then remove the original. If
- # there is an error the entity may appear twice. This
- # will cause some breakage but is better than being
- # lost, which is what happens if this is done in the
- # opposite order.
- self._putElement project, destFolderId, entity, entityType, (err, result)->
- return callback(err) if err?
- # Note: putElement always pushes onto the end of an
- # array so it will never change an existing mongo
- # path. Therefore it is safe to remove an element
- # from the project with an existing path after
- # calling putElement. But we must be sure that we
- # have not moved a folder subfolder of itself (which
- # is done by _checkValidMove above) because that
- # would lead to it being deleted.
- self._removeElementFromMongoArray Project, project_id, entityPath.mongo, entity_id, (err, newProject)->
- return callback(err) if err?
- ProjectEntityHandler.getAllEntitiesFromProject newProject, (err, newDocs, newFiles) ->
- return callback(err) if err?
- startPath = entityPath.fileSystem
- endPath = result.path.fileSystem
- changes = {oldDocs, newDocs, oldFiles, newFiles, newProject}
- # check that no files have been lost (or duplicated)
- if (oldFiles.length != newFiles.length) or (oldDocs.length != newDocs.length)
- logger.err {
- project_id: project_id
- oldDocs: oldDocs.length
- newDocs: newDocs.length
- oldFiles:oldFiles.length
- newFiles: newFiles.length
- origProject: project
- newProject: newProject
- }, "project corrupted moving files - shouldn't happen"
- return callback(new Error("unexpected change in project structure"))
- callback null, project, startPath, endPath, entity.rev, changes, callback
-
- deleteEntity: wrapWithLock (project_id, entity_id, entityType, callback) ->
- ProjectGetter.getProjectWithoutLock project_id, {name:true, rootFolder:true, overleaf:true}, (error, project) ->
- return callback(error) if error?
- ProjectLocator.findElement {project: project, element_id: entity_id, type: entityType}, (error, entity, path) ->
- return callback(error) if error?
- self._removeElementFromMongoArray Project, project_id, path.mongo, entity_id, (error, newProject) ->
- return callback(error) if error?
- callback null, entity, path, project, newProject
-
- renameEntity: wrapWithLock (project_id, entity_id, entityType, newName, callback) ->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (error, project)=>
- return callback(error) if error?
- ProjectEntityHandler.getAllEntitiesFromProject project, (error, oldDocs, oldFiles) =>
- return callback(error) if error?
- ProjectLocator.findElement {project:project, element_id:entity_id, type:entityType}, (error, entity, entPath, parentFolder)=>
- return callback(error) if error?
- endPath = path.join(path.dirname(entPath.fileSystem), newName)
- # Prevent top-level docs/files with reserved names (to match v1 behaviour)
- if self._blockedFilename {fileSystem: endPath}, entityType
- return callback new Errors.InvalidNameError("blocked element name")
- # check if the new name already exists in the current folder
- self._checkValidElementName parentFolder, newName, (error) =>
- return callback(error) if error?
- conditions = {_id:project_id}
- update = "$set":{}, "$inc":{}
- namePath = entPath.mongo+".name"
- update["$set"][namePath] = newName
- # we need to increment the project version number for any structure change
- update["$inc"]["version"] = 1
- Project.findOneAndUpdate conditions, update, { "new": true}, (error, newProject) ->
- return callback(error) if error?
- ProjectEntityHandler.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
- return callback(error) if error?
- startPath = entPath.fileSystem
- changes = {oldDocs, newDocs, oldFiles, newFiles, newProject}
- callback null, project, startPath, endPath, entity.rev, changes, callback
-
- addFolder: wrapWithLock (project_id, parentFolder_id, folderName, callback) ->
- ProjectGetter.getProjectWithoutLock project_id, {rootFolder:true, name:true, overleaf:true}, (err, project) ->
- if err?
- logger.err project_id:project_id, err:err, "error getting project for add folder"
- return callback(err)
- self._confirmFolder project, parentFolder_id, (parentFolder_id) =>
- folder = new Folder name: folderName
- logger.log project: project._id, parentFolder_id:parentFolder_id, folderName:folderName, "adding new folder"
- self._putElement project, parentFolder_id, folder, "folder", (err)=>
- if err?
- logger.err err:err, project_id:project._id, "error adding folder to project"
- return callback(err)
- callback null, folder, parentFolder_id
-
- _removeElementFromMongoArray: (model, model_id, path, element_id, callback = (err, project) ->)->
- conditions = {_id:model_id}
- pullUpdate = {"$pull":{}, "$inc":{}}
- nonArrayPath = path.slice(0, path.lastIndexOf("."))
- # remove specific element from array by id
- pullUpdate["$pull"][nonArrayPath] = {_id: element_id}
- # we need to increment the project version number for any structure change
- pullUpdate["$inc"]["version"] = 1
- model.findOneAndUpdate conditions, pullUpdate, {"new": true}, callback
-
- _countElements: (project)->
- countFolder = (folder)->
- total = 0
-
- for subfolder in folder?.folders or []
- total += countFolder(subfolder)
-
- if folder?.folders?.length?
- total += folder.folders.length
-
- if folder?.docs?.length?
- total += folder.docs.length
-
- if folder?.fileRefs?.length?
- total += folder.fileRefs.length
-
- total
-
- countFolder project.rootFolder[0]
-
- _putElement: (project, folder_id, element, type, callback = (err, path, project)->)->
- sanitizeTypeOfElement = (elementType)->
- lastChar = elementType.slice -1
- if lastChar != "s"
- elementType +="s"
- if elementType == "files"
- elementType = "fileRefs"
- return elementType
-
- if !element? or !element._id?
- e = new Error("no element passed to be inserted")
- logger.err project_id:project._id, folder_id:folder_id, element:element, type:type, "failed trying to insert element as it was null"
- return callback(e)
- type = sanitizeTypeOfElement type
-
- # original check path.resolve("/", element.name) isnt "/#{element.name}" or element.name.match("/")
- # check if name is allowed
- if not SafePath.isCleanFilename element.name
- e = new Errors.InvalidNameError("invalid element name")
- logger.err project_id:project._id, folder_id:folder_id, element:element, type:type, "failed trying to insert element as name was invalid"
- return callback(e)
-
- if !folder_id?
- folder_id = project.rootFolder[0]._id
-
- if self._countElements(project) > settings.maxEntitiesPerProject
- logger.warn project_id:project._id, "project too big, stopping insertions"
- CooldownManager.putProjectOnCooldown(project._id)
- return callback("project_has_to_many_files")
-
- ProjectLocator.findElement {project:project, element_id:folder_id, type:"folders"}, (err, folder, path)=>
- if err?
- logger.err err:err, project_id:project._id, folder_id:folder_id, type:type, element:element, "error finding folder for _putElement"
- return callback(err)
- newPath =
- fileSystem: "#{path.fileSystem}/#{element.name}"
- mongo: path.mongo
- # check if the path would be too long
- if not SafePath.isAllowedLength newPath.fileSystem
- return callback new Errors.InvalidNameError("path too long")
- # Prevent top-level docs/files with reserved names (to match v1 behaviour)
- if self._blockedFilename newPath, type
- return callback new Errors.InvalidNameError("blocked element name")
- self._checkValidElementName folder, element.name, (err) =>
- return callback(err) if err?
- id = element._id+''
- element._id = require('mongoose').Types.ObjectId(id)
- conditions = _id:project._id
- mongopath = "#{path.mongo}.#{type}"
- update = "$push":{}, "$inc":{}
- update["$push"][mongopath] = element
- # we need to increment the project version number for any structure change
- update["$inc"]["version"] = 1 # increment project version number
- logger.log project_id: project._id, element_id: element._id, fileType: type, folder_id: folder_id, mongopath:mongopath, "adding element to project"
- # We are using Mongoose here, but if we ever switch to a direct mongo call
- # the next line will need to be updated to {returnNewDocument:true}
- Project.findOneAndUpdate conditions, update, {"new": true}, (err, newProject)->
- if err?
- logger.err err: err, project_id: project._id, 'error saving in putElement project'
- return callback(err)
- callback(err, {path:newPath}, newProject)
-
- _blockedFilename: (entityPath, entityType) ->
- # check if name would be blocked in v1
- # javascript reserved names are forbidden for docs and files
- # at the top-level (but folders with reserved names are allowed).
- isFolder = (entityType in ['folder', 'folders'])
- [dir, file] = [path.dirname(entityPath.fileSystem), path.basename(entityPath.fileSystem)]
- isTopLevel = dir is '/'
- if isTopLevel and !isFolder && SafePath.isBlockedFilename file
- return true
- else
- return false
-
- _checkValidElementName: (folder, name, callback = (err) ->) ->
- # check if the name is already taken by a doc, file or
- # folder. If so, return an error "file already exists".
- err = new Errors.InvalidNameError("file already exists")
- for doc in folder?.docs or []
- return callback(err) if doc.name is name
- for file in folder?.fileRefs or []
- return callback(err) if file.name is name
- for folder in folder?.folders or []
- return callback(err) if folder.name is name
- callback()
-
- _confirmFolder: (project, folder_id, callback)->
- logger.log folder_id:folder_id, project_id:project._id, "confirming folder in project"
- if folder_id+'' == 'undefined'
- callback(project.rootFolder[0]._id)
- else if folder_id != null
- callback folder_id
- else
- callback(project.rootFolder[0]._id)
-
- _checkValidMove: (project, entityType, entity, entityPath, destFolderId, callback = (error) ->) ->
- ProjectLocator.findElement { project, element_id: destFolderId, type:"folder"}, (err, destEntity, destFolderPath) ->
- return callback(err) if err?
- # check if there is already a doc/file/folder with the same name
- # in the destination folder
- self._checkValidElementName destEntity, entity.name, (err)->
- return callback(err) if err?
- if /folder/.test(entityType)
- logger.log destFolderPath: destFolderPath.fileSystem, folderPath: entityPath.fileSystem, "checking folder is not moving into child folder"
- isNestedFolder = destFolderPath.fileSystem.slice(0, entityPath.fileSystem.length) == entityPath.fileSystem
- if isNestedFolder
- return callback(new Errors.InvalidNameError("destination folder is a child folder of me"))
- callback()
-
- _insertDeletedDocReference: (project_id, doc, callback = (error) ->) ->
- Project.update {
- _id: project_id
- }, {
- $push: {
- deletedDocs: {
- _id: doc._id
- name: doc.name
- deletedAt: new Date()
- }
- }
- }, {}, callback
-
- _insertDeletedFileReference: (project_id, fileRef, callback = (error) ->) ->
- Project.update {
- _id: project_id
- }, {
- $push: {
- deletedFiles: {
- _id: fileRef._id
- name: fileRef.name
- linkedFileData: fileRef.linkedFileData
- hash: fileRef.hash
- deletedAt: new Date()
- }
- }
- }, {}, callback
diff --git a/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee
deleted file mode 100644
index ba405b0b27..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee
+++ /dev/null
@@ -1,500 +0,0 @@
-_ = require 'lodash'
-async = require 'async'
-logger = require('logger-sharelatex')
-path = require('path')
-Doc = require('../../models/Doc').Doc
-DocstoreManager = require('../Docstore/DocstoreManager')
-DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
-Errors = require '../Errors/Errors'
-File = require('../../models/File').File
-FileStoreHandler = require('../FileStore/FileStoreHandler')
-LockManager = require('../../infrastructure/LockManager')
-Project = require('../../models/Project').Project
-ProjectEntityHandler = require('./ProjectEntityHandler')
-ProjectGetter = require('./ProjectGetter')
-ProjectLocator = require('./ProjectLocator')
-ProjectUpdateHandler = require('./ProjectUpdateHandler')
-ProjectEntityMongoUpdateHandler = require('./ProjectEntityMongoUpdateHandler')
-SafePath = require './SafePath'
-TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-
-LOCK_NAMESPACE = "sequentialProjectStructureUpdateLock"
-
-wrapWithLock = (methodWithoutLock) ->
- # This lock is used to make sure that the project structure updates are made
- # sequentially. In particular the updates must be made in mongo and sent to
- # the doc-updater in the same order.
- if typeof methodWithoutLock is 'function'
- methodWithLock = (project_id, args..., callback) ->
- LockManager.runWithLock LOCK_NAMESPACE, project_id,
- (cb) -> methodWithoutLock project_id, args..., cb
- callback
- methodWithLock.withoutLock = methodWithoutLock
- methodWithLock
- else
- # handle case with separate setup and locked stages
- wrapWithSetup = methodWithoutLock.beforeLock # a function to set things up before the lock
- mainTask = methodWithoutLock.withLock # function to execute inside the lock
- methodWithLock = wrapWithSetup (project_id, args..., callback) ->
- LockManager.runWithLock(LOCK_NAMESPACE, project_id, (cb) ->
- mainTask(project_id, args..., cb)
- callback)
- methodWithLock.withoutLock = wrapWithSetup mainTask
- methodWithLock.beforeLock = methodWithoutLock.beforeLock
- methodWithLock.mainTask = methodWithoutLock.withLock
- methodWithLock
-
-module.exports = ProjectEntityUpdateHandler = self =
- copyFileFromExistingProjectWithProject: wrapWithLock
- beforeLock: (next) ->
- (project_id, project, folder_id, originalProject_id, origonalFileRef, userId, callback = (error, fileRef, folder_id) ->)->
- logger.log { project_id, folder_id, originalProject_id, origonalFileRef }, "copying file in s3 with project"
- ProjectEntityMongoUpdateHandler._confirmFolder project, folder_id, (folder_id) ->
- if !origonalFileRef?
- logger.err { project_id, folder_id, originalProject_id, origonalFileRef }, "file trying to copy is null"
- return callback()
- # convert any invalid characters in original file to '_'
- fileProperties = name : SafePath.clean(origonalFileRef.name)
- if origonalFileRef.linkedFileData?
- fileProperties.linkedFileData = origonalFileRef.linkedFileData
- if origonalFileRef.hash?
- fileProperties.hash = origonalFileRef.hash
- fileRef = new File(fileProperties)
- FileStoreHandler.copyFile originalProject_id, origonalFileRef._id, project._id, fileRef._id, (err, fileStoreUrl)->
- if err?
- logger.err { err, project_id, folder_id, originalProject_id, origonalFileRef }, "error coping file in s3"
- return callback(err)
- next(project_id, project, folder_id, originalProject_id, origonalFileRef, userId, fileRef, fileStoreUrl, callback)
- withLock: (project_id, project, folder_id, originalProject_id, origonalFileRef, userId, fileRef, fileStoreUrl, callback = (error, fileRef, folder_id) ->)->
- projectHistoryId = project.overleaf?.history?.id
- ProjectEntityMongoUpdateHandler._putElement project, folder_id, fileRef, "file", (err, result, newProject) ->
- if err?
- logger.err { err, project_id, folder_id }, "error putting element as part of copy"
- return callback(err)
- TpdsUpdateSender.addFile { project_id, file_id:fileRef._id, path:result?.path?.fileSystem, rev:fileRef.rev, project_name:project.name}, (err) ->
- if err?
- logger.err { err, project_id, folder_id, originalProject_id, origonalFileRef }, "error sending file to tpds worker"
- newFiles = [
- file: fileRef
- path: result?.path?.fileSystem
- url: fileStoreUrl
- ]
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newFiles, newProject}, (error) ->
- return callback(error) if error?
- callback null, fileRef, folder_id
-
- updateDocLines: (project_id, doc_id, lines, version, ranges, lastUpdatedAt, lastUpdatedBy, callback = (error) ->)->
- ProjectGetter.getProjectWithoutDocLines project_id, (err, project)->
- return callback(err) if err?
- return callback(new Errors.NotFoundError("project not found")) if !project?
- logger.log project_id: project_id, doc_id: doc_id, "updating doc lines"
- ProjectLocator.findElement {project:project, element_id:doc_id, type:"docs"}, (err, doc, path)->
- isDeletedDoc = false
- if err?
- if err instanceof Errors.NotFoundError
- # We need to be able to update the doclines of deleted docs. This is
- # so the doc-updater can flush a doc's content to the doc-store after
- # the doc is deleted.
- isDeletedDoc = true
- doc = _.find project.deletedDocs, (doc) ->
- doc._id.toString() == doc_id.toString()
- else
- return callback(err)
-
- if !doc?
- # Do not allow an update to a doc which has never exist on this project
- logger.error {doc_id, project_id, lines}, "doc not found while updating doc lines"
- return callback(new Errors.NotFoundError('doc not found'))
-
- logger.log {project_id, doc_id}, "telling docstore manager to update doc"
- DocstoreManager.updateDoc project_id, doc_id, lines, version, ranges, (err, modified, rev) ->
- if err?
- logger.error {err, doc_id, project_id, lines}, "error sending doc to docstore"
- return callback(err)
- logger.log {project_id, doc_id, modified}, "finished updating doc lines"
- # path will only be present if the doc is not deleted
- if modified && !isDeletedDoc
- # Don't need to block for marking as updated
- ProjectUpdateHandler.markAsUpdated project_id, lastUpdatedAt, lastUpdatedBy
- TpdsUpdateSender.addDoc {project_id:project_id, path:path.fileSystem, doc_id:doc_id, project_name:project.name, rev:rev}, callback
- else
- callback()
-
- setRootDoc: (project_id, newRootDocID, callback = (error) ->)->
- logger.log project_id: project_id, rootDocId: newRootDocID, "setting root doc"
- Project.update {_id:project_id}, {rootDoc_id:newRootDocID}, {}, callback
-
- unsetRootDoc: (project_id, callback = (error) ->) ->
- logger.log project_id: project_id, "removing root doc"
- Project.update {_id:project_id}, {$unset: {rootDoc_id: true}}, {}, callback
-
- _addDocAndSendToTpds: (project_id, folder_id, doc, callback = (error, result, project) ->)->
- ProjectEntityMongoUpdateHandler.addDoc project_id, folder_id, doc, (err, result, project) ->
- if err?
- logger.err err:err, project_id: project_id, folder_id: folder_id, doc_name: doc?.name, doc_id:doc?._id, "error adding file with project"
- return callback(err)
- TpdsUpdateSender.addDoc {
- project_id: project_id,
- doc_id: doc?._id,
- path: result?.path?.fileSystem,
- project_name: project.name,
- rev: 0
- }, (err) ->
- return callback(err) if err?
- callback(null, result, project)
-
- addDoc: (project_id, folder_id, docName, docLines, userId, callback) ->
- self.addDocWithRanges(project_id, folder_id, docName, docLines, {}, userId, callback)
-
- addDocWithRanges: wrapWithLock
- beforeLock: (next) ->
- (project_id, folder_id, docName, docLines, ranges, userId, callback = (error, doc, folder_id) ->) ->
- if not SafePath.isCleanFilename docName
- return callback new Errors.InvalidNameError("invalid element name")
- # Put doc in docstore first, so that if it errors, we don't have a doc_id in the project
- # which hasn't been created in docstore.
- doc = new Doc name: docName
- DocstoreManager.updateDoc project_id.toString(), doc._id.toString(), docLines, 0, ranges, (err, modified, rev) ->
- return callback(err) if err?
- next(project_id, folder_id, doc, docName, docLines, ranges, userId, callback)
- withLock: (project_id, folder_id, doc, docName, docLines, ranges, userId, callback = (error, doc, folder_id) ->) ->
- ProjectEntityUpdateHandler._addDocAndSendToTpds project_id, folder_id, doc, (err, result, project) ->
- return callback(err) if err?
- docPath = result?.path?.fileSystem
- projectHistoryId = project.overleaf?.history?.id
- newDocs = [
- doc: doc
- path: docPath
- docLines: docLines.join('\n')
- ]
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newDocs, newProject: project}, (error) ->
- return callback(error) if error?
- callback null, doc, folder_id
-
- _uploadFile: (project_id, folder_id, fileName, fsPath, linkedFileData, callback = (error, fileStoreUrl, fileRef) ->)->
- if not SafePath.isCleanFilename fileName
- return callback new Errors.InvalidNameError("invalid element name")
- fileArgs =
- name: fileName
- linkedFileData: linkedFileData
- FileStoreHandler.uploadFileFromDisk project_id, fileArgs, fsPath, (err, fileStoreUrl, fileRef)->
- if err?
- logger.err err:err, project_id: project_id, folder_id: folder_id, file_name: fileName, fileRef:fileRef, "error uploading image to s3"
- return callback(err)
- callback(null, fileStoreUrl, fileRef)
-
- _addFileAndSendToTpds: (project_id, folder_id, fileRef, callback = (error) ->)->
- ProjectEntityMongoUpdateHandler.addFile project_id, folder_id, fileRef, (err, result, project) ->
- if err?
- logger.err err:err, project_id: project_id, folder_id: folder_id, file_name: fileRef.name, fileRef:fileRef, "error adding file with project"
- return callback(err)
- TpdsUpdateSender.addFile {project_id:project_id, file_id:fileRef._id, path:result?.path?.fileSystem, project_name:project.name, rev:fileRef.rev}, (err) ->
- return callback(err) if err?
- callback(null, result, project)
-
- addFile: wrapWithLock
- beforeLock: (next) ->
- (project_id, folder_id, fileName, fsPath, linkedFileData, userId, callback) ->
- if not SafePath.isCleanFilename fileName
- return callback new Errors.InvalidNameError("invalid element name")
- ProjectEntityUpdateHandler._uploadFile project_id, folder_id, fileName, fsPath, linkedFileData, (error, fileStoreUrl, fileRef) ->
- return callback(error) if error?
- next(project_id, folder_id, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback)
- withLock: (project_id, folder_id, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback = (error, fileRef, folder_id) ->)->
- ProjectEntityUpdateHandler._addFileAndSendToTpds project_id, folder_id, fileRef, (err, result, project) ->
- return callback(err) if err?
- projectHistoryId = project.overleaf?.history?.id
- newFiles = [
- file: fileRef
- path: result?.path?.fileSystem
- url: fileStoreUrl
- ]
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newFiles, newProject: project}, (error) ->
- return callback(error) if error?
- callback(null, fileRef, folder_id)
-
- replaceFile: wrapWithLock
- beforeLock: (next) ->
- (project_id, file_id, fsPath, linkedFileData, userId, callback)->
- # create a new file
- fileArgs =
- name: "dummy-upload-filename"
- linkedFileData: linkedFileData
- FileStoreHandler.uploadFileFromDisk project_id, fileArgs, fsPath, (err, fileStoreUrl, fileRef)->
- return callback(err) if err?
- next project_id, file_id, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback
- withLock: (project_id, file_id, fsPath, linkedFileData, userId, newFileRef, fileStoreUrl, callback)->
- ProjectEntityMongoUpdateHandler.replaceFileWithNew project_id, file_id, newFileRef, (err, oldFileRef, project, path, newProject) ->
- return callback(err) if err?
- oldFiles = [
- file: oldFileRef
- path: path.fileSystem
- ]
- newFiles = [
- file: newFileRef
- path: path.fileSystem
- url: fileStoreUrl
- ]
- projectHistoryId = project.overleaf?.history?.id
- # Increment the rev for an in-place update (with the same path) so the third-party-datastore
- # knows this is a new file.
- # Ideally we would get this from ProjectEntityMongoUpdateHandler.replaceFileWithNew
- # but it returns the original oldFileRef (after incrementing the rev value in mongo),
- # so we add 1 to the rev from that. This isn't atomic and relies on the lock
- # but it is acceptable for now.
- TpdsUpdateSender.addFile {project_id:project._id, file_id:newFileRef._id, path:path.fileSystem, rev:oldFileRef.rev + 1, project_name:project.name}, (err) ->
- return callback(err) if err?
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {oldFiles, newFiles, newProject}, callback
-
- upsertDoc: wrapWithLock (project_id, folder_id, docName, docLines, source, userId, callback = (err, doc, folder_id, isNewDoc)->)->
- if not SafePath.isCleanFilename docName
- return callback new Errors.InvalidNameError("invalid element name")
- ProjectLocator.findElement project_id: project_id, element_id: folder_id, type: "folder", (error, folder) ->
- return callback(error) if error?
- return callback(new Error("Couldn't find folder")) if !folder?
- existingDoc = null
- for doc in folder.docs
- if doc.name == docName
- existingDoc = doc
- break
- if existingDoc?
- DocumentUpdaterHandler.setDocument project_id, existingDoc._id, userId, docLines, source, (err)=>
- logger.log project_id:project_id, doc_id:existingDoc._id, "notifying users that the document has been updated"
- DocumentUpdaterHandler.flushDocToMongo project_id, existingDoc._id, (err) ->
- return callback(err) if err?
- callback null, existingDoc, !existingDoc?
- else
- self.addDocWithRanges.withoutLock project_id, folder_id, docName, docLines, {}, userId, (err, doc) ->
- return callback(err) if err?
- callback null, doc, !existingDoc?
-
- upsertFile: wrapWithLock
- beforeLock: (next) ->
- (project_id, folder_id, fileName, fsPath, linkedFileData, userId, callback)->
- if not SafePath.isCleanFilename fileName
- return callback new Errors.InvalidNameError("invalid element name")
- # create a new file
- fileArgs =
- name: fileName
- linkedFileData: linkedFileData
- FileStoreHandler.uploadFileFromDisk project_id, fileArgs, fsPath, (err, fileStoreUrl, fileRef)->
- return callback(err) if err?
- next(project_id, folder_id, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback)
- withLock: (project_id, folder_id, fileName, fsPath, linkedFileData, userId, newFileRef, fileStoreUrl, callback = (err, file, isNewFile, existingFile)->)->
- ProjectLocator.findElement project_id: project_id, element_id: folder_id, type: "folder", (error, folder) ->
- return callback(error) if error?
- return callback(new Error("Couldn't find folder")) if !folder?
- existingFile = null
- for fileRef in folder.fileRefs
- if fileRef.name == fileName
- existingFile = fileRef
- break
- if existingFile?
- # this calls directly into the replaceFile main task (without the beforeLock part)
- self.replaceFile.mainTask project_id, existingFile._id, fsPath, linkedFileData, userId, newFileRef, fileStoreUrl, (err) ->
- return callback(err) if err?
- callback null, newFileRef, !existingFile?, existingFile
- else
- # this calls directly into the addFile main task (without the beforeLock part)
- self.addFile.mainTask project_id, folder_id, fileName, fsPath, linkedFileData, userId, newFileRef, fileStoreUrl, (err) ->
- return callback(err) if err?
- callback null, newFileRef, !existingFile?, existingFile
-
- upsertDocWithPath: wrapWithLock (project_id, elementPath, docLines, source, userId, callback) ->
- if not SafePath.isCleanPath elementPath
- return callback new Errors.InvalidNameError("invalid element name")
- docName = path.basename(elementPath)
- folderPath = path.dirname(elementPath)
- self.mkdirp.withoutLock project_id, folderPath, (err, newFolders, folder) ->
- return callback(err) if err?
- self.upsertDoc.withoutLock project_id, folder._id, docName, docLines, source, userId, (err, doc, isNewDoc) ->
- return callback(err) if err?
- callback null, doc, isNewDoc, newFolders, folder
-
- upsertFileWithPath: wrapWithLock
- beforeLock: (next) ->
- (project_id, elementPath, fsPath, linkedFileData, userId, callback)->
- if not SafePath.isCleanPath elementPath
- return callback new Errors.InvalidNameError("invalid element name")
- fileName = path.basename(elementPath)
- folderPath = path.dirname(elementPath)
- # create a new file
- fileArgs =
- name: fileName
- linkedFileData: linkedFileData
- FileStoreHandler.uploadFileFromDisk project_id, fileArgs, fsPath, (err, fileStoreUrl, fileRef)->
- return callback(err) if err?
- next project_id, folderPath, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback
- withLock: (project_id, folderPath, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback) ->
- self.mkdirp.withoutLock project_id, folderPath, (err, newFolders, folder) ->
- return callback(err) if err?
- # this calls directly into the upsertFile main task (without the beforeLock part)
- self.upsertFile.mainTask project_id, folder._id, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, (err, newFile, isNewFile, existingFile) ->
- return callback(err) if err?
- callback null, newFile, isNewFile, existingFile, newFolders, folder
-
- deleteEntity: wrapWithLock (project_id, entity_id, entityType, userId, callback = (error) ->)->
- logger.log entity_id:entity_id, entityType:entityType, project_id:project_id, "deleting project entity"
- if !entityType?
- logger.err err: "No entityType set", project_id: project_id, entity_id: entity_id
- return callback("No entityType set")
- entityType = entityType.toLowerCase()
- ProjectEntityMongoUpdateHandler.deleteEntity project_id, entity_id, entityType, (error, entity, path, projectBeforeDeletion, newProject) ->
- return callback(error) if error?
- self._cleanUpEntity projectBeforeDeletion, newProject, entity, entityType, path.fileSystem, userId, (error) ->
- return callback(error) if error?
- TpdsUpdateSender.deleteEntity project_id:project_id, path:path.fileSystem, project_name:projectBeforeDeletion.name, (error) ->
- return callback(error) if error?
- callback null, entity_id
-
- deleteEntityWithPath: wrapWithLock (project_id, path, userId, callback) ->
- ProjectLocator.findElementByPath project_id: project_id, path: path, (err, element, type)->
- return callback(err) if err?
- return callback(new Errors.NotFoundError("project not found")) if !element?
- self.deleteEntity.withoutLock project_id, element._id, type, userId, callback
-
- mkdirp: wrapWithLock (project_id, path, callback = (err, newlyCreatedFolders, lastFolderInPath)->)->
- for folder in path.split('/')
- if folder.length > 0 and not SafePath.isCleanFilename folder
- return callback new Errors.InvalidNameError("invalid element name")
- ProjectEntityMongoUpdateHandler.mkdirp project_id, path, {exactCaseMatch: false}, callback
-
- mkdirpWithExactCase: wrapWithLock (project_id, path, callback = (err, newlyCreatedFolders, lastFolderInPath)->)->
- for folder in path.split('/')
- if folder.length > 0 and not SafePath.isCleanFilename folder
- return callback new Errors.InvalidNameError("invalid element name")
- ProjectEntityMongoUpdateHandler.mkdirp project_id, path, {exactCaseMatch: true}, callback
-
- addFolder: wrapWithLock (project_id, parentFolder_id, folderName, callback) ->
- if not SafePath.isCleanFilename folderName
- return callback new Errors.InvalidNameError("invalid element name")
- ProjectEntityMongoUpdateHandler.addFolder project_id, parentFolder_id, folderName, callback
-
- moveEntity: wrapWithLock (project_id, entity_id, destFolderId, entityType, userId, callback = (error) ->)->
- logger.log {entityType, entity_id, project_id, destFolderId}, "moving entity"
- if !entityType?
- logger.err {err: "No entityType set", project_id, entity_id}
- return callback("No entityType set")
- entityType = entityType.toLowerCase()
- ProjectEntityMongoUpdateHandler.moveEntity project_id, entity_id, destFolderId, entityType, (err, project, startPath, endPath, rev, changes) ->
- return callback(err) if err?
- projectHistoryId = project.overleaf?.history?.id
- TpdsUpdateSender.moveEntity { project_id, project_name: project.name, startPath, endPath, rev }
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback
-
- renameEntity: wrapWithLock (project_id, entity_id, entityType, newName, userId, callback)->
- if not SafePath.isCleanFilename newName
- return callback new Errors.InvalidNameError("invalid element name")
- logger.log(entity_id: entity_id, project_id: project_id, ('renaming '+entityType))
- if !entityType?
- logger.err err: "No entityType set", project_id: project_id, entity_id: entity_id
- return callback("No entityType set")
- entityType = entityType.toLowerCase()
-
- ProjectEntityMongoUpdateHandler.renameEntity project_id, entity_id, entityType, newName, (err, project, startPath, endPath, rev, changes) ->
- return callback(err) if err?
- projectHistoryId = project.overleaf?.history?.id
- TpdsUpdateSender.moveEntity { project_id, project_name: project.name, startPath, endPath, rev }
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback
-
- # This doesn't directly update project structure but we need to take the lock
- # to prevent anything else being queued before the resync update
- resyncProjectHistory: wrapWithLock (project_id, callback) ->
- ProjectGetter.getProject project_id, rootFolder: true, overleaf: true, (error, project) ->
- return callback(error) if error?
-
- projectHistoryId = project?.overleaf?.history?.id
- if !projectHistoryId?
- error = new Errors.ProjectHistoryDisabledError("project history not enabled for #{project_id}")
- return callback(error)
-
- ProjectEntityHandler.getAllEntitiesFromProject project, (error, docs, files) ->
- return callback(error) if error?
-
- docs = _.map docs, (doc) ->
- doc: doc.doc._id
- path: doc.path
-
- files = _.map files, (file) ->
- file: file.file._id
- path: file.path
- url: FileStoreHandler._buildUrl(project_id, file.file._id)
-
- DocumentUpdaterHandler.resyncProjectHistory project_id, projectHistoryId, docs, files, callback
-
- _cleanUpEntity: (project, newProject, entity, entityType, path, userId, callback = (error) ->) ->
- self._updateProjectStructureWithDeletedEntity project, newProject, entity, entityType, path, userId, (error) ->
- return callback(error) if error?
- if(entityType.indexOf("file") != -1)
- self._cleanUpFile project, entity, path, userId, callback
- else if (entityType.indexOf("doc") != -1)
- self._cleanUpDoc project, entity, path, userId, callback
- else if (entityType.indexOf("folder") != -1)
- self._cleanUpFolder project, entity, path, userId, callback
- else
- callback()
-
- # Note: the _cleanUpEntity code and _updateProjectStructureWithDeletedEntity
- # methods both need to recursively iterate over the entities in folder.
- # These are currently using separate implementations of the recursion. In
- # future, these could be simplified using a common project entity iterator.
- _updateProjectStructureWithDeletedEntity: (project, newProject, entity, entityType, entityPath, userId, callback = (error) ->) ->
- # compute the changes to the project structure
- if(entityType.indexOf("file") != -1)
- changes = oldFiles: [ {file: entity, path: entityPath} ]
- else if (entityType.indexOf("doc") != -1)
- changes = oldDocs: [ {doc: entity, path: entityPath} ]
- else if (entityType.indexOf("folder") != -1)
- changes = {oldDocs: [], oldFiles: []}
- _recurseFolder = (folder, folderPath) ->
- for doc in folder.docs
- changes.oldDocs.push {doc, path: path.join(folderPath, doc.name)}
- for file in folder.fileRefs
- changes.oldFiles.push {file, path: path.join(folderPath, file.name)}
- for childFolder in folder.folders
- _recurseFolder(childFolder, path.join(folderPath, childFolder.name))
- _recurseFolder entity, entityPath
- # now send the project structure changes to the docupdater
- changes.newProject = newProject
- project_id = project._id.toString()
- projectHistoryId = project.overleaf?.history?.id
- DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback
-
- _cleanUpDoc: (project, doc, path, userId, callback = (error) ->) ->
- project_id = project._id.toString()
- doc_id = doc._id.toString()
- unsetRootDocIfRequired = (callback) =>
- if project.rootDoc_id? and project.rootDoc_id.toString() == doc_id
- @unsetRootDoc project_id, callback
- else
- callback()
-
- unsetRootDocIfRequired (error) ->
- return callback(error) if error?
- ProjectEntityMongoUpdateHandler._insertDeletedDocReference project._id, doc, (error) ->
- return callback(error) if error?
- DocumentUpdaterHandler.deleteDoc project_id, doc_id, (error) ->
- return callback(error) if error?
- DocstoreManager.deleteDoc project_id, doc_id, callback
-
- _cleanUpFile: (project, file, path, userId, callback = (error) ->) ->
- ProjectEntityMongoUpdateHandler._insertDeletedFileReference project._id, file, callback
-
- _cleanUpFolder: (project, folder, folderPath, userId, callback = (error) ->) ->
- jobs = []
- for doc in folder.docs
- do (doc) ->
- docPath = path.join(folderPath, doc.name)
- jobs.push (callback) -> self._cleanUpDoc project, doc, docPath, userId, callback
-
- for file in folder.fileRefs
- do (file) ->
- filePath = path.join(folderPath, file.name)
- jobs.push (callback) -> self._cleanUpFile project, file, filePath, userId, callback
-
- for childFolder in folder.folders
- do (childFolder) ->
- folderPath = path.join(folderPath, childFolder.name)
- jobs.push (callback) -> self._cleanUpFolder project, childFolder, folderPath, userId, callback
-
- async.series jobs, callback
diff --git a/services/web/app/coffee/Features/Project/ProjectGetter.coffee b/services/web/app/coffee/Features/Project/ProjectGetter.coffee
deleted file mode 100644
index 81d2090bc0..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectGetter.coffee
+++ /dev/null
@@ -1,98 +0,0 @@
-mongojs = require("../../infrastructure/mongojs")
-metrics = require("metrics-sharelatex")
-db = mongojs.db
-ObjectId = mongojs.ObjectId
-async = require "async"
-Project = require("../../models/Project").Project
-logger = require("logger-sharelatex")
-LockManager = require("../../infrastructure/LockManager")
-
-module.exports = ProjectGetter =
- EXCLUDE_DEPTH: 8
-
- getProjectWithoutDocLines: (project_id, callback=(error, project) ->) ->
- excludes = {}
- for i in [1..ProjectGetter.EXCLUDE_DEPTH]
- excludes["rootFolder#{Array(i).join(".folders")}.docs.lines"] = 0
- ProjectGetter.getProject project_id, excludes, callback
-
- getProjectWithOnlyFolders: (project_id, callback=(error, project) ->) ->
- excludes = {}
- for i in [1..ProjectGetter.EXCLUDE_DEPTH]
- excludes["rootFolder#{Array(i).join(".folders")}.docs"] = 0
- excludes["rootFolder#{Array(i).join(".folders")}.fileRefs"] = 0
- ProjectGetter.getProject project_id, excludes, callback
-
- getProject: (project_id, projection, callback) ->
- if typeof(projection) == "function" && !callback?
- callback = projection
- projection = {}
- if !project_id?
- return callback(new Error("no project_id provided"))
- if typeof(projection) != "object"
- return callback(new Error("projection is not an object"))
-
- if projection?.rootFolder || Object.keys(projection).length == 0
- ProjectEntityMongoUpdateHandler = require './ProjectEntityMongoUpdateHandler'
- LockManager.runWithLock ProjectEntityMongoUpdateHandler.LOCK_NAMESPACE, project_id,
- (cb) -> ProjectGetter.getProjectWithoutLock project_id, projection, cb
- callback
- else
- ProjectGetter.getProjectWithoutLock project_id, projection, callback
-
- getProjectWithoutLock: (project_id, projection, callback) ->
- if typeof(projection) == "function" && !callback?
- callback = projection
- projection = {}
- if !project_id?
- return callback(new Error("no project_id provided"))
- if typeof(projection) != "object"
- return callback(new Error("projection is not an object"))
-
- if typeof project_id == "string"
- query = _id: ObjectId(project_id)
- else if project_id instanceof ObjectId
- query = _id: project_id
- else if project_id?.toString().length == 24 # sometimes mongoose ids are hard to identify, this will catch them
- query = _id: ObjectId(project_id.toString())
- else
- err = new Error("malformed get request")
- logger.log project_id:project_id, err:err, type:typeof(project_id), "malformed get request"
- return callback(err)
-
- db.projects.find query, projection, (err, project) ->
- if err?
- logger.err err:err, query:query, projection:projection, "error getting project"
- return callback(err)
- callback(null, project?[0])
-
- getProjectIdByReadAndWriteToken: (token, callback=(err, project_id)->) ->
- Project.findOne {'tokens.readAndWrite': token}, {_id: 1}, (err, project) ->
- return callback err if err?
- return callback() unless project?
- callback null, project._id
-
- findAllUsersProjects: (
- user_id,
- fields,
- callback = (error, projects={owned: [], readAndWrite: [], readOnly: [], tokenReadAndWrite: [], tokenReadOnly: []}) ->
- ) ->
- CollaboratorsHandler = require "../Collaborators/CollaboratorsHandler"
- Project.find {owner_ref: user_id}, fields, (error, ownedProjects) ->
- return callback(error) if error?
- CollaboratorsHandler.getProjectsUserIsMemberOf user_id, fields, (error, projects) ->
- return callback(error) if error?
- result = {
- owned: ownedProjects || [],
- readAndWrite: projects.readAndWrite || [],
- readOnly: projects.readOnly || [],
- tokenReadAndWrite: projects.tokenReadAndWrite || [],
- tokenReadOnly: projects.tokenReadOnly || []
- }
- callback null, result
-
-[
- 'getProject',
- 'getProjectWithoutDocLines'
-].map (method) ->
- metrics.timeAsyncMethod(ProjectGetter, method, 'mongo.ProjectGetter', logger)
diff --git a/services/web/app/coffee/Features/Project/ProjectHelper.coffee b/services/web/app/coffee/Features/Project/ProjectHelper.coffee
deleted file mode 100644
index 69b4daec5d..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectHelper.coffee
+++ /dev/null
@@ -1,56 +0,0 @@
-ENGINE_TO_COMPILER_MAP = {
- latex_dvipdf: "latex"
- pdflatex: "pdflatex"
- xelatex: "xelatex"
- lualatex: "lualatex"
-}
-
-module.exports = ProjectHelper =
- compilerFromV1Engine: (engine) ->
- return ENGINE_TO_COMPILER_MAP[engine]
-
- ensureNameIsUnique: (nameList, name, suffixes = [], maxLength, callback = (error, name, changed)->) ->
- # create a set of all project names
- allNames = new Set(nameList)
- isUnique = (x) -> !allNames.has(x)
- # check if the supplied name is already unique
- if isUnique(name)
- return callback(null, name, false)
- # the name already exists, try adding the user-supplied suffixes to generate a unique name
- for suffix in suffixes
- candidateName = ProjectHelper._addSuffixToProjectName(name, suffix, maxLength)
- if isUnique(candidateName)
- return callback(null, candidateName, true)
- # if there are no (more) suffixes, use a numeric one
- uniqueName = ProjectHelper._addNumericSuffixToProjectName(name, allNames, maxLength)
- if uniqueName?
- callback(null, uniqueName, true)
- else
- callback(new Error("Failed to generate a unique name for: #{name}"))
-
- _addSuffixToProjectName: (name, suffix = '', maxLength) ->
- # append the suffix and truncate the project title if needed
- truncatedLength = maxLength - suffix.length
- return name.substr(0, truncatedLength) + suffix
-
- _addNumericSuffixToProjectName: (name, allProjectNames, maxLength) ->
- NUMERIC_SUFFIX_MATCH = / \((\d+)\)$/
- suffixedName = (basename, number) ->
- suffix = " (#{number})"
- return basename.substr(0, maxLength - suffix.length) + suffix
-
- match = name.match(NUMERIC_SUFFIX_MATCH)
- basename = name
- n = 1
- last = allProjectNames.size + n
-
- if match?
- basename = name.replace(NUMERIC_SUFFIX_MATCH, '')
- n = parseInt(match[1])
-
- while n <= last
- candidate = suffixedName(basename, n)
- return candidate unless allProjectNames.has(candidate)
- n += 1
-
- return null
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Project/ProjectHistoryHandler.coffee b/services/web/app/coffee/Features/Project/ProjectHistoryHandler.coffee
deleted file mode 100644
index ab9ec77eb5..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectHistoryHandler.coffee
+++ /dev/null
@@ -1,55 +0,0 @@
-Project = require('../../models/Project').Project
-ProjectDetailsHandler = require "./ProjectDetailsHandler"
-logger = require('logger-sharelatex')
-settings = require("settings-sharelatex")
-HistoryManager = require "../History/HistoryManager"
-ProjectEntityUpdateHandler = require "./ProjectEntityUpdateHandler"
-
-module.exports = ProjectHistoryHandler =
-
- setHistoryId: (project_id, history_id, callback = (err) ->) ->
- # reject invalid history ids
- return callback(new Error("invalid history id")) if !history_id or typeof(history_id) isnt 'number'
- # use $exists:false to prevent overwriting any existing history id, atomically
- Project.update {_id: project_id, "overleaf.history.id": {$exists:false}}, {"overleaf.history.id":history_id}, (err, result)->
- return callback(err) if err?
- return callback(new Error("history exists")) if result?.n == 0
- callback()
-
- getHistoryId: (project_id, callback = (err, result) ->) ->
- ProjectDetailsHandler.getDetails project_id, (err, project) ->
- return callback(err) if err? # n.b. getDetails returns an error if the project doesn't exist
- callback(null, project?.overleaf?.history?.id)
-
- upgradeHistory: (project_id, callback = (err, result) ->) ->
- # project must have an overleaf.history.id before allowing display of new history
- Project.update {_id: project_id, "overleaf.history.id": {$exists:true}}, {"overleaf.history.display":true, "overleaf.history.upgradedAt": new Date()}, (err, result)->
- return callback(err) if err?
- # return an error if overleaf.history.id wasn't present
- return callback(new Error("history not upgraded")) if result?.n == 0
- callback()
-
- downgradeHistory: (project_id, callback = (err, result) ->) ->
- Project.update {_id: project_id, "overleaf.history.upgradedAt": {$exists:true}}, {"overleaf.history.display":false, $unset:{"overleaf.history.upgradedAt":1}}, (err, result)->
- return callback(err) if err?
- return callback(new Error("history not downgraded")) if result?.n == 0
- callback()
-
- ensureHistoryExistsForProject: (project_id, callback = (err) ->) ->
- # We can only set a history id for a project that doesn't have one. The
- # history id is cached in the project history service, and changing an
- # existing value corrupts the history, leaving it in an irrecoverable
- # state. Setting a history id when one wasn't present before is ok,
- # because undefined history ids aren't cached.
- ProjectHistoryHandler.getHistoryId project_id, (err, history_id) ->
- return callback(err) if err?
- return callback() if history_id? # history already exists, success
- HistoryManager.initializeProject (err, history) ->
- return callback(err) if err?
- return callback(new Error("failed to initialize history id")) if !history?.overleaf_id
- ProjectHistoryHandler.setHistoryId project_id, history.overleaf_id, (err) ->
- return callback(err) if err?
- ProjectEntityUpdateHandler.resyncProjectHistory project_id, (err) ->
- return callback(err) if err?
- logger.log {project_id: project_id, history_id: history.overleaf_id}, "started syncing project with new history id"
- HistoryManager.flushProject project_id, callback
diff --git a/services/web/app/coffee/Features/Project/ProjectLocator.coffee b/services/web/app/coffee/Features/Project/ProjectLocator.coffee
deleted file mode 100644
index c23faeff90..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectLocator.coffee
+++ /dev/null
@@ -1,193 +0,0 @@
-Project = require('../../models/Project').Project
-ProjectGetter = require("./ProjectGetter")
-Errors = require "../Errors/Errors"
-_ = require('underscore')
-logger = require('logger-sharelatex')
-async = require('async')
-
-module.exports = ProjectLocator =
- findElement: (options, _callback = (err, element, path, parentFolder)->)->
- callback = (args...) ->
- _callback(args...)
- _callback = () ->
-
- {project, project_id, element_id, type} = options
- elementType = sanitizeTypeOfElement type
-
- count = 0
- endOfBranch = ->
- if --count == 0
- logger.warn "element #{element_id} could not be found for project #{project_id || project._id}"
- return callback(new Errors.NotFoundError("entity not found"))
-
- search = (searchFolder, path)->
- count++
- element = _.find searchFolder[elementType], (el)-> el?._id+'' == element_id+'' #need to ToString both id's for robustness
- if !element? && searchFolder.folders? && searchFolder.folders.length != 0
- _.each searchFolder.folders, (folder, index)->
- if !folder?
- return
- newPath = {}
- newPath[key] = value for own key,value of path #make a value copy of the string
- newPath.fileSystem += "/#{folder.name}"
- newPath.mongo += ".folders.#{index}"
- search folder, newPath
- endOfBranch()
- return
- else if element?
- elementPlaceInArray = getIndexOf(searchFolder[elementType], element_id)
- path.fileSystem += "/#{element.name}"
- path.mongo +=".#{elementType}.#{elementPlaceInArray}"
- callback(null, element, path, searchFolder)
- else if !element?
- return endOfBranch()
-
- path = {fileSystem:'',mongo:'rootFolder.0'}
-
- startSearch = (project)->
- if element_id+'' == project.rootFolder[0]._id+''
- callback(null, project.rootFolder[0], path, null)
- else
- search project.rootFolder[0], path
-
- if project?
- startSearch(project)
- else
- ProjectGetter.getProject project_id, {rootFolder:true, rootDoc_id:true}, (err, project)->
- return callback(err) if err?
- if !project?
- return callback(new Errors.NotFoundError("project not found"))
- startSearch project
-
- findRootDoc : (opts, callback)->
- getRootDoc = (project)=>
- if project.rootDoc_id?
- @findElement {project:project, element_id:project.rootDoc_id, type:"docs"}, (error, args...) ->
- if error?
- if error instanceof Errors.NotFoundError
- return callback null, null
- else
- return callback error
- return callback null, args...
- else
- callback null, null
- {project, project_id} = opts
- if project?
- getRootDoc project
- else
- ProjectGetter.getProject project_id, {rootFolder:true, rootDoc_id:true}, (err, project)->
- if err?
- logger.err err:err, "error getting project"
- return callback(err)
- else
- getRootDoc project
-
- findElementByPath: (options, callback = (err, foundEntity, type)->)->
- {project, project_id, path, exactCaseMatch} = options
- if !path?
- return new Error('no path provided for findElementByPath')
-
- if project?
- ProjectLocator._findElementByPathWithProject project, path, exactCaseMatch, callback
- else
- ProjectGetter.getProject project_id, {rootFolder:true, rootDoc_id:true}, (err, project)->
- return callback(err) if err?
- ProjectLocator._findElementByPathWithProject project, path, exactCaseMatch, callback
-
- _findElementByPathWithProject: (project, needlePath, exactCaseMatch, callback = (err, foundEntity, type)->)->
- if exactCaseMatch
- matchFn = (a, b) -> (a == b)
- else
- matchFn = (a, b) -> (a?.toLowerCase() == b?.toLowerCase())
-
- getParentFolder = (haystackFolder, foldersList, level, cb)->
- if foldersList.length == 0
- return cb null, haystackFolder
- needleFolderName = foldersList[level]
- found = false
- for folder in haystackFolder.folders
- if matchFn(folder.name, needleFolderName)
- found = true
- if level == foldersList.length-1
- return cb null, folder
- else
- return getParentFolder(folder, foldersList, level+1, cb)
- if !found
- cb("not found project: #{project._id} search path: #{needlePath}, folder #{foldersList[level]} could not be found")
-
- getEntity = (folder, entityName, cb)->
- if !entityName?
- return cb null, folder, "folder"
- for file in folder.fileRefs or []
- if matchFn(file?.name, entityName)
- result = file
- type = "file"
- for doc in folder.docs or []
- if matchFn(doc?.name, entityName)
- result = doc
- type = "doc"
- for childFolder in folder.folders or []
- if matchFn(childFolder?.name, entityName)
- result = childFolder
- type = "folder"
-
- if result?
- cb null, result, type
- else
- cb("not found project: #{project._id} search path: #{needlePath}, entity #{entityName} could not be found")
-
-
- if err?
- logger.err err:err, project_id:project._id, "error getting project for finding element"
- return callback(err)
- if !project?
- return callback("project could not be found for finding a element #{project._id}")
- if needlePath == '' || needlePath == '/'
- return callback(null, project.rootFolder[0], "folder")
-
- if needlePath.indexOf('/') == 0
- needlePath = needlePath.substring(1)
- foldersList = needlePath.split('/')
- needleName = foldersList.pop()
- rootFolder = project.rootFolder[0]
-
- logger.log project_id:project._id, path:needlePath, foldersList:foldersList, "looking for element by path"
- jobs = new Array()
- jobs.push(
- (cb)->
- getParentFolder rootFolder, foldersList, 0, cb
- )
- jobs.push(
- (folder, cb)->
- getEntity folder, needleName, cb
- )
- async.waterfall jobs, callback
-
- findUsersProjectByName: (user_id, projectName, callback)->
- ProjectGetter.findAllUsersProjects user_id, 'name archived', (err, allProjects)->
- return callback(error) if error?
- {owned, readAndWrite} = allProjects
- projects = owned.concat(readAndWrite)
- projectName = projectName.toLowerCase()
- project = _.find projects, (project)->
- project.name.toLowerCase() == projectName and project.archived != true
- logger.log user_id:user_id, projectName:projectName, totalProjects:projects.length, project:project, "looking for project by name"
- callback(null, project)
-
-
-sanitizeTypeOfElement = (elementType)->
- lastChar = elementType.slice -1
- if lastChar != "s"
- elementType +="s"
- if elementType == "files"
- elementType = "fileRefs"
- return elementType
-
-
-getIndexOf = (searchEntity, id)->
- length = searchEntity.length
- count = 0
- while(count < length)
- if searchEntity[count]?._id+"" == id+""
- return count
- count++
diff --git a/services/web/app/coffee/Features/Project/ProjectOptionsHandler.coffee b/services/web/app/coffee/Features/Project/ProjectOptionsHandler.coffee
deleted file mode 100644
index 7bdad93b03..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectOptionsHandler.coffee
+++ /dev/null
@@ -1,69 +0,0 @@
-Project = require('../../models/Project').Project
-logger = require('logger-sharelatex')
-_ = require('underscore')
-settings = require("settings-sharelatex")
-
-safeCompilers = ["xelatex", "pdflatex", "latex", "lualatex"]
-
-module.exports =
- setCompiler : (project_id, compiler, callback = ()->)->
- logger.log project_id:project_id, compiler:compiler, "setting the compiler"
- compiler = compiler.toLowerCase()
- if !_.contains safeCompilers, compiler
- return callback()
- conditions = {_id:project_id}
- update = {compiler:compiler}
- Project.update conditions, update, {}, (err)->
- if callback?
- callback()
-
- setImageName : (project_id, imageName, callback = ()->)->
- logger.log project_id:project_id, imageName:imageName, "setting the imageName"
- imageName = imageName.toLowerCase()
- if ! _.some(settings.allowedImageNames, (allowed) -> imageName is allowed.imageName)
- return callback()
- conditions = {_id:project_id}
- update = {imageName: settings.imageRoot + '/' + imageName}
- Project.update conditions, update, {}, (err)->
- if callback?
- callback()
-
- setSpellCheckLanguage: (project_id, languageCode, callback = ()->)->
- logger.log project_id:project_id, languageCode:languageCode, "setting the spell check language"
- languageIsSafe = false
- settings.languages.forEach (safeLang)->
- if safeLang.code == languageCode
- languageIsSafe = true
-
- if languageCode == ""
- languageIsSafe = true
-
- if languageIsSafe
- conditions = {_id:project_id}
- update = {spellCheckLanguage:languageCode}
- Project.update conditions, update, {}, (err)->
- callback()
- else
- logger.err project_id:project_id, languageCode:languageCode, "tryed to set unsafe language"
- callback()
-
- setBrandVariationId: (project_id, brandVariationId, callback = ()->)->
- logger.log project_id:project_id, brandVariationId:brandVariationId, "setting the brand variation id"
- if !brandVariationId? or brandVariationId == ""
- return callback()
- conditions = {_id:project_id}
- update = {brandVariationId}
- Project.update conditions, update, {}, (err)->
- if err?
- logger.err err:err, "error setting brandVariationId"
- callback()
-
- unsetBrandVariationId: (project_id, callback = ()->)->
- logger.log project_id:project_id, "unsetting the brand variation id"
- conditions = {_id:project_id}
- update = {$unset: {brandVariationId: 1}}
- Project.update conditions, update, {}, (err)->
- if err?
- logger.err err:err, "error unsetting brandVariationId"
- return callback(err)
- callback()
diff --git a/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee b/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee
deleted file mode 100644
index edc39f7436..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee
+++ /dev/null
@@ -1,155 +0,0 @@
-ProjectEntityHandler = require "./ProjectEntityHandler"
-ProjectEntityUpdateHandler = require "./ProjectEntityUpdateHandler"
-ProjectGetter = require "./ProjectGetter"
-DocumentHelper = require "../Documents/DocumentHelper"
-Path = require "path"
-fs = require("fs")
-async = require("async")
-globby = require("globby")
-_ = require("underscore")
-
-module.exports = ProjectRootDocManager =
- setRootDocAutomatically: (project_id, callback = (error) ->) ->
- ProjectEntityHandler.getAllDocs project_id, (error, docs) ->
- return callback(error) if error?
-
- jobs = _.map docs, (doc, path)->
- return (cb)->
- if /\.R?tex$/.test(Path.extname(path)) && DocumentHelper.contentHasDocumentclass(doc.lines)
- cb(doc._id)
- else
- cb(null)
-
- async.series jobs, (root_doc_id)->
- if root_doc_id?
- ProjectEntityUpdateHandler.setRootDoc project_id, root_doc_id, callback
- else
- callback()
-
- findRootDocFileFromDirectory: (directoryPath, callback = (error, path, content) ->) ->
- filePathsPromise = globby([
- '**/*.{tex,Rtex}'
- ], {
- cwd: directoryPath,
- followSymlinkedDirectories: false,
- onlyFiles: true,
- case: false
- }
- )
-
- # the search order is such that we prefer files closer to the project root, then
- # we go by file size in ascending order, because people often have a main
- # file that just includes a bunch of other files; then we go by name, in
- # order to be deterministic
- filePathsPromise.then(
- (unsortedFiles) ->
- ProjectRootDocManager._sortFileList unsortedFiles, directoryPath, (err, files) ->
- return callback(err) if err?
- doc = null
-
- async.until(
- ->
- return doc? || files.length == 0
- (cb) ->
- file = files.shift()
- fs.readFile Path.join(directoryPath, file), 'utf8', (error, content) ->
- return cb(error) if error?
- content = (content || '').replace(/\r/g, '')
- if DocumentHelper.contentHasDocumentclass(content)
- doc = {path: file, content: content}
- cb(null)
- (err) ->
- callback(err, doc?.path, doc?.content)
- )
- (err) ->
- callback(err)
- )
-
- # coffeescript's implicit-return mechanism returns filePathsPromise from this method, which confuses mocha
- return null
-
- setRootDocFromName: (project_id, rootDocName, callback = (error) ->) ->
- ProjectEntityHandler.getAllDocPathsFromProjectById project_id, (error, docPaths) ->
- return callback(error) if error?
- # strip off leading and trailing quotes from rootDocName
- rootDocName = rootDocName.replace(/^\'|\'$/g,"")
- # prepend a slash for the root folder if not present
- rootDocName = "/#{rootDocName}" if rootDocName[0] isnt '/'
- # find the root doc from the filename
- root_doc_id = null
- for doc_id, path of docPaths
- # docpaths have a leading / so allow matching "folder/filename" and "/folder/filename"
- if path == rootDocName
- root_doc_id = doc_id
- # try a basename match if there was no match
- if !root_doc_id
- for doc_id, path of docPaths
- if Path.basename(path) == Path.basename(rootDocName)
- root_doc_id = doc_id
- # set the root doc id if we found a match
- if root_doc_id?
- ProjectEntityUpdateHandler.setRootDoc project_id, root_doc_id, callback
- else
- callback()
-
- ensureRootDocumentIsSet: (project_id, callback = (error) ->) ->
- ProjectGetter.getProject project_id, rootDoc_id: 1, (error, project) ->
- return callback(error) if error?
- if !project?
- return callback new Error("project not found")
-
- if project.rootDoc_id?
- callback()
- else
- ProjectRootDocManager.setRootDocAutomatically project_id, callback
-
- ensureRootDocumentIsValid: (project_id, callback = (error) ->) ->
- ProjectGetter.getProject project_id, rootDoc_id: 1, (error, project) ->
- return callback(error) if error?
- if !project?
- return callback new Error("project not found")
-
- if project.rootDoc_id?
- ProjectEntityHandler.getAllDocPathsFromProjectById project_id, (error, docPaths) ->
- return callback(error) if error?
- rootDocValid = false
- for doc_id, _path of docPaths
- if doc_id == project.rootDoc_id
- rootDocValid = true
- if rootDocValid
- callback()
- else
- ProjectEntityUpdateHandler.setRootDoc project_id, null, ->
- ProjectRootDocManager.setRootDocAutomatically project_id, callback
- else
- ProjectRootDocManager.setRootDocAutomatically project_id, callback
-
- _sortFileList: (listToSort, rootDirectory, callback = (error, result)->) ->
- async.mapLimit(
- listToSort
- 5
- (filePath, cb) ->
- fs.stat Path.join(rootDirectory, filePath), (err, stat) ->
- return cb(err) if err?
- cb(null,
- size: stat.size
- path: filePath
- elements: filePath.split(Path.sep).length
- name: Path.basename(filePath)
- )
- (err, files) ->
- return callback(err) if err?
-
- callback(null, _.map files.sort(ProjectRootDocManager._rootDocSort), (file)-> return file.path)
- )
-
- _rootDocSort: (a, b) ->
- # sort first by folder depth
- return a.elements - b.elements if a.elements != b.elements
- # ensure main.tex is at the start of each folder
- return -1 if (a.name == 'main.tex' && b.name != 'main.tex')
- return 1 if (a.name != 'main.tex' && b.name == 'main.tex')
- # prefer smaller files
- return a.size - b.size if a.size != b.size
- # otherwise, use the full path name
- return a.path.localeCompare(b.path)
diff --git a/services/web/app/coffee/Features/Project/ProjectTokenGenerator.coffee b/services/web/app/coffee/Features/Project/ProjectTokenGenerator.coffee
deleted file mode 100644
index 43c6a2b3fd..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectTokenGenerator.coffee
+++ /dev/null
@@ -1,66 +0,0 @@
-crypto = require 'crypto'
-V1Api = require('../V1/V1Api')
-Async = require('async')
-logger = require('logger-sharelatex')
-
-
-# This module mirrors the token generation in Overleaf (`random_token.rb`),
-# for the purposes of implementing token-based project access, like the
-# 'unlisted-projects' feature in Overleaf
-
-module.exports = ProjectTokenGenerator =
-
- # (From Overleaf `random_token.rb`)
- # Letters (not numbers! see generate_token) used in tokens. They're all
- # consonants, to avoid embarassing words (I can't think of any that use only
- # a y), and lower case "l" is omitted, because in many fonts it is
- # indistinguishable from an upper case "I" (and sometimes even the number 1).
- TOKEN_ALPHA: 'bcdfghjkmnpqrstvwxyz'
- TOKEN_NUMERICS: '123456789'
-
- _randomString: (length, alphabet) ->
- result = crypto.randomBytes(length).toJSON().data.map(
- (b) -> alphabet[b % alphabet.length]
- ).join('')
- return result
-
- # Generate a 12-char token with only characters from TOKEN_ALPHA,
- # suitable for use as a read-only token for a project
- readOnlyToken: () ->
- return ProjectTokenGenerator._randomString(
- 12,
- ProjectTokenGenerator.TOKEN_ALPHA
- )
-
- # Generate a longer token, with a numeric prefix,
- # suitable for use as a read-and-write token for a project
- readAndWriteToken: () ->
- numerics = ProjectTokenGenerator._randomString(
- 10,
- ProjectTokenGenerator.TOKEN_NUMERICS
- )
- token = ProjectTokenGenerator._randomString(
- 12,
- ProjectTokenGenerator.TOKEN_ALPHA
- )
- fullToken = "#{numerics}#{token}"
- return { token: fullToken, numericPrefix: numerics }
-
- generateUniqueReadOnlyToken: (callback=(err, token)->) ->
- Async.retry 10
- , (cb) ->
- token = ProjectTokenGenerator.readOnlyToken()
- logger.log {token}, "Generated read-only token"
- V1Api.request {
- url: "/api/v1/sharelatex/docs/read_token/#{token}/exists",
- json: true
- }, (err, response, body) ->
- return cb(err) if err?
- if response.statusCode != 200
- return cb(new Error("non-200 response from v1 read-token-exists api: #{response.statusCode}"))
- if body.exists == true
- cb(new Error("token already exists in v1: #{token}"))
- else
- logger.log {token}, "Read-only token does not exist in v1, good to use"
- cb(null, token)
- , callback
diff --git a/services/web/app/coffee/Features/Project/ProjectUpdateHandler.coffee b/services/web/app/coffee/Features/Project/ProjectUpdateHandler.coffee
deleted file mode 100644
index e0f2c5f7af..0000000000
--- a/services/web/app/coffee/Features/Project/ProjectUpdateHandler.coffee
+++ /dev/null
@@ -1,37 +0,0 @@
-Project = require('../../models/Project').Project
-logger = require('logger-sharelatex')
-
-module.exports =
- markAsUpdated : (projectId, lastUpdatedAt, lastUpdatedBy, callback = () ->)->
- lastUpdatedAt ?= new Date()
-
- conditions =
- _id: projectId
- lastUpdated: { $lt: lastUpdatedAt }
-
- update = {
- lastUpdated: lastUpdatedAt or (new Date()).getTime()
- lastUpdatedBy: lastUpdatedBy
- }
- Project.update conditions, update, {}, callback
-
- markAsOpened : (project_id, callback)->
- conditions = {_id:project_id}
- update = {lastOpened:Date.now()}
- Project.update conditions, update, {}, (err)->
- if callback?
- callback()
-
- markAsInactive: (project_id, callback)->
- conditions = {_id:project_id}
- update = {active:false}
- Project.update conditions, update, {}, (err)->
- if callback?
- callback()
-
- markAsActive: (project_id, callback)->
- conditions = {_id:project_id}
- update = {active:true}
- Project.update conditions, update, {}, (err)->
- if callback?
- callback()
diff --git a/services/web/app/coffee/Features/Project/SafePath.coffee b/services/web/app/coffee/Features/Project/SafePath.coffee
deleted file mode 100644
index 82aef24bb1..0000000000
--- a/services/web/app/coffee/Features/Project/SafePath.coffee
+++ /dev/null
@@ -1,97 +0,0 @@
-# This file is shared between the frontend and server code of web, so that
-# filename validation is the same in both implementations.
-# Both copies must be kept in sync:
-# app/coffee/Features/Project/SafePath.coffee
-# public/coffee/ide/directives/SafePath.coffee
-
-load = () ->
- BADCHAR_RX = ///
- [
- \/ # no forward slashes
- \\ # no back slashes
- \* # no asterisk
- \u0000-\u001F # no control characters (0-31)
- \u007F # no delete
- \u0080-\u009F # no unicode control characters (C1)
- \uD800-\uDFFF # no unicode surrogate characters
- ]
- ///g
-
- BADFILE_RX = ///
- (^\.$) # reject . as a filename
- | (^\.\.$) # reject .. as a filename
- | (^\s+) # reject leading space
- | (\s+$) # reject trailing space
- ///g
-
- # Put a block on filenames which match javascript property names, as they
- # can cause exceptions where the code puts filenames into a hash. This is a
- # temporary workaround until the code in other places is made safe against
- # property names.
- #
- # The list of property names is taken from
- # ['prototype'].concat(Object.getOwnPropertyNames(Object.prototype))
- BLOCKEDFILE_RX = ///
- ^(
- prototype
- |constructor
- |toString
- |toLocaleString
- |valueOf
- |hasOwnProperty
- |isPrototypeOf
- |propertyIsEnumerable
- |__defineGetter__
- |__lookupGetter__
- |__defineSetter__
- |__lookupSetter__
- |__proto__
- )$
- ///
-
- MAX_PATH = 1024 # Maximum path length, in characters. This is fairly arbitrary.
-
- SafePath =
- # convert any invalid characters to underscores in the given filename
- clean: (filename) ->
- filename = filename.replace BADCHAR_RX, '_'
- # for BADFILE_RX replace any matches with an equal number of underscores
- filename = filename.replace BADFILE_RX, (match) ->
- return new Array(match.length + 1).join("_")
- # replace blocked filenames 'prototype' with '@prototype'
- filename = filename.replace BLOCKEDFILE_RX, "@$1"
- return filename
-
- # returns whether the filename is 'clean' (does not contain any invalid
- # characters or reserved words)
- isCleanFilename: (filename) ->
- return SafePath.isAllowedLength(filename) &&
- !BADCHAR_RX.test(filename) &&
- !BADFILE_RX.test(filename)
-
- isBlockedFilename: (filename) ->
- return BLOCKEDFILE_RX.test(filename)
-
- # returns whether a full path is 'clean' - e.g. is a full or relative path
- # that points to a file, and each element passes the rules in 'isCleanFilename'
- isCleanPath: (path) ->
- elements = path.split('/')
-
- lastElementIsEmpty = elements[elements.length - 1].length == 0
- return false if lastElementIsEmpty
-
- for element in elements
- return false if element.length > 0 && !SafePath.isCleanFilename element
-
- # check for a top-level reserved name
- return false if BLOCKEDFILE_RX.test(path.replace(/^\/?/,'')) # remove leading slash if present
-
- return true
-
- isAllowedLength: (pathname) ->
- return pathname.length > 0 && pathname.length <= MAX_PATH
-
-if define?
- define [], load
-else
- module.exports = load()
diff --git a/services/web/app/coffee/Features/Publishers/PublishersGetter.coffee b/services/web/app/coffee/Features/Publishers/PublishersGetter.coffee
deleted file mode 100644
index 701da6cd3a..0000000000
--- a/services/web/app/coffee/Features/Publishers/PublishersGetter.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-UserMembershipsHandler = require "../UserMembership/UserMembershipsHandler"
-UserMembershipEntityConfigs = require "../UserMembership/UserMembershipEntityConfigs"
-logger = require 'logger-sharelatex'
-_ = require 'underscore'
-
-module.exports = PublishersGetter =
- getManagedPublishers: (user_id, callback = (error, managedPublishers) ->) ->
- UserMembershipsHandler.getEntitiesByUser UserMembershipEntityConfigs.publisher, user_id, (error, managedPublishers) ->
- callback(error, managedPublishers)
diff --git a/services/web/app/coffee/Features/RealTimeProxy/RealTimeProxyRouter.coffee b/services/web/app/coffee/Features/RealTimeProxy/RealTimeProxyRouter.coffee
deleted file mode 100644
index 0672520f31..0000000000
--- a/services/web/app/coffee/Features/RealTimeProxy/RealTimeProxyRouter.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-settings = require "settings-sharelatex"
-
-httpProxy = require('http-proxy');
-proxy = httpProxy.createProxyServer({
- target: settings.apis.realTime.url
-})
-wsProxy = httpProxy.createProxyServer({
- target: settings.apis.realTime.url.replace("http://", "ws://")
- ws: true
-})
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.all /\/socket\.io\/.*/, (req, res, next) ->
- proxy.web req, res, next
-
- setTimeout () ->
- Server = require "../../infrastructure/Server"
- Server.server.on "upgrade", (req, socket, head) ->
- wsProxy.ws req, socket, head
- , 0
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Referal/ReferalAllocator.coffee b/services/web/app/coffee/Features/Referal/ReferalAllocator.coffee
deleted file mode 100644
index cfee62fdfa..0000000000
--- a/services/web/app/coffee/Features/Referal/ReferalAllocator.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-_ = require("underscore")
-logger = require('logger-sharelatex')
-User = require('../../models/User').User
-Settings = require "settings-sharelatex"
-FeaturesUpdater = require "../Subscription/FeaturesUpdater"
-
-module.exports = ReferalAllocator =
- allocate: (referal_id, new_user_id, referal_source, referal_medium, callback = ->)->
- if !referal_id?
- logger.log new_user_id:new_user_id, "no referal for user"
- return callback(null)
-
- logger.log referal_id:referal_id, new_user_id:new_user_id, referal_source:referal_source, referal_medium:referal_medium, "allocating users referal"
-
- query = {"referal_id":referal_id}
- User.findOne query, (error, user) ->
- return callback(error) if error?
- if !user? or !user._id?
- logger.log new_user_id:new_user_id, referal_id:referal_id, "no user found for referal id"
- return callback(null)
-
- if referal_source == "bonus"
- User.update query, {
- $push:
- refered_users: new_user_id
- $inc:
- refered_user_count: 1
- }, {}, (err)->
- if err?
- logger.err err:err, referal_id:referal_id, new_user_id:new_user_id, "something went wrong allocating referal"
- return callback(err)
-
- FeaturesUpdater.refreshFeatures user._id, callback
- else
- callback()
diff --git a/services/web/app/coffee/Features/Referal/ReferalConnect.coffee b/services/web/app/coffee/Features/Referal/ReferalConnect.coffee
deleted file mode 100644
index e84474a47e..0000000000
--- a/services/web/app/coffee/Features/Referal/ReferalConnect.coffee
+++ /dev/null
@@ -1,34 +0,0 @@
-module.exports =
-
- use: (req, res, next)->
- if req.query?
- if req.query.referal?
- req.session.referal_id = req.query.referal
- else if req.query.r? # Short hand for referal
- req.session.referal_id = req.query.r
- else if req.query.fb_ref?
- req.session.referal_id = req.query.fb_ref
-
- if req.query.rm? # referal medium e.g. twitter, facebook, email
- switch req.query.rm
- when "fb"
- req.session.referal_medium = "facebook"
- when "t"
- req.session.referal_medium = "twitter"
- when "gp"
- req.session.referal_medium = "google_plus"
- when "e"
- req.session.referal_medium = "email"
- when "d"
- req.session.referal_medium = "direct"
-
- if req.query.rs? # referal source e.g. project share, bonus
- switch req.query.rs
- when "b"
- req.session.referal_source = "bonus"
- when "ps"
- req.session.referal_source = "public_share"
- when "ci"
- req.session.referal_source = "collaborator_invite"
-
- next()
diff --git a/services/web/app/coffee/Features/Referal/ReferalController.coffee b/services/web/app/coffee/Features/Referal/ReferalController.coffee
deleted file mode 100644
index 421a186a9f..0000000000
--- a/services/web/app/coffee/Features/Referal/ReferalController.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-logger = require('logger-sharelatex')
-ReferalHandler = require('./ReferalHandler')
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-module.exports =
- bonus: (req, res)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- ReferalHandler.getReferedUsers user_id, (err, refered_users, refered_user_count)->
- res.render "referal/bonus",
- title: "bonus_please_recommend_us"
- refered_users: refered_users
- refered_user_count: refered_user_count
diff --git a/services/web/app/coffee/Features/Referal/ReferalFeatures.coffee b/services/web/app/coffee/Features/Referal/ReferalFeatures.coffee
deleted file mode 100644
index 0980f06222..0000000000
--- a/services/web/app/coffee/Features/Referal/ReferalFeatures.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-_ = require("underscore")
-logger = require('logger-sharelatex')
-User = require('../../models/User').User
-Settings = require "settings-sharelatex"
-
-module.exports = ReferalFeatures =
- getBonusFeatures: (user_id, callback = (error) ->) ->
- query = _id: user_id
- User.findOne query, (error, user) ->
- return callback(error) if error
- return callback(new Error("user not found #{user_id} for assignBonus")) if !user?
- logger.log user_id: user_id, refered_user_count: user.refered_user_count, "assigning bonus"
- if user.refered_user_count? and user.refered_user_count > 0
- newFeatures = ReferalFeatures._calculateFeatures(user)
- callback null, newFeatures
- else
- callback null, {}
-
- _calculateFeatures : (user)->
- bonusLevel = ReferalFeatures._getBonusLevel(user)
- return Settings.bonus_features?["#{bonusLevel}"] or {}
-
- _getBonusLevel: (user)->
- highestBonusLevel = 0
- _.each _.keys(Settings.bonus_features), (level)->
- levelIsLessThanUser = level <= user.refered_user_count
- levelIsMoreThanCurrentHighest = level >= highestBonusLevel
- if levelIsLessThanUser and levelIsMoreThanCurrentHighest
- highestBonusLevel = level
- return highestBonusLevel
diff --git a/services/web/app/coffee/Features/Referal/ReferalHandler.coffee b/services/web/app/coffee/Features/Referal/ReferalHandler.coffee
deleted file mode 100644
index 6a959adb57..0000000000
--- a/services/web/app/coffee/Features/Referal/ReferalHandler.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-User = require('../../models/User').User
-
-module.exports =
- getReferedUsers: (user_id, callback)->
- User.findById user_id, (err, user)->
- refered_users = user.refered_users || []
- refered_user_count= user.refered_user_count || refered_users.length
- callback null, refered_users, refered_user_count
diff --git a/services/web/app/coffee/Features/References/ReferencesController.coffee b/services/web/app/coffee/Features/References/ReferencesController.coffee
deleted file mode 100644
index 305c4715b5..0000000000
--- a/services/web/app/coffee/Features/References/ReferencesController.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-logger = require('logger-sharelatex')
-ReferencesHandler = require('./ReferencesHandler')
-settings = require('settings-sharelatex')
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-
-module.exports = ReferencesController =
-
-
- index: (req, res) ->
- projectId = req.params.Project_id
- shouldBroadcast = req.body.shouldBroadcast
- docIds = req.body.docIds
- if (!docIds or !(docIds instanceof Array))
- logger.err {projectId, docIds}, "docIds is not valid, should be either Array or String 'ALL'"
- return res.sendStatus 400
- logger.log {projectId, docIds: docIds}, "index references for project"
- ReferencesHandler.index projectId, docIds, (err, data) ->
- if err?
- logger.err {err, projectId}, "error indexing all references"
- return res.sendStatus 500
- ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
-
- indexAll: (req, res) ->
- projectId = req.params.Project_id
- shouldBroadcast = req.body.shouldBroadcast
- logger.log {projectId}, "index all references for project"
- ReferencesHandler.indexAll projectId, (err, data) ->
- if err?
- logger.err {err, projectId}, "error indexing all references"
- return res.sendStatus 500
- ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
-
- _handleIndexResponse: (req, res, projectId, shouldBroadcast, data) ->
- if !data? or !data.keys?
- return res.json({projectId, keys: []})
- if shouldBroadcast
- logger.log {projectId}, "emitting new references keys to connected clients"
- EditorRealTimeController.emitToRoom projectId, 'references:keys:updated', data.keys
- return res.json data
diff --git a/services/web/app/coffee/Features/References/ReferencesHandler.coffee b/services/web/app/coffee/Features/References/ReferencesHandler.coffee
deleted file mode 100644
index 959833351f..0000000000
--- a/services/web/app/coffee/Features/References/ReferencesHandler.coffee
+++ /dev/null
@@ -1,108 +0,0 @@
-logger = require("logger-sharelatex")
-request = require("request")
-settings = require("settings-sharelatex")
-ProjectGetter = require "../Project/ProjectGetter"
-UserGetter = require "../User/UserGetter"
-DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-_ = require('underscore')
-Async = require('async')
-
-oneMinInMs = 60 * 1000
-fiveMinsInMs = oneMinInMs * 5
-
-if !settings.apis?.references?.url?
- logger.log "references search not enabled"
-
-module.exports = ReferencesHandler =
-
- _buildDocUrl: (projectId, docId) ->
- "#{settings.apis.docstore.url}/project/#{projectId}/doc/#{docId}/raw"
-
- _buildFileUrl: (projectId, fileId) ->
- "#{settings.apis.filestore.url}/project/#{projectId}/file/#{fileId}"
-
- _findBibFileIds: (project) ->
- ids = []
- _process = (folder) ->
- _.each (folder.fileRefs or []), (file) ->
- if file?.name?.match(/^.*\.bib$/)
- ids.push(file._id)
- _.each (folder.folders or []), (folder) ->
- _process(folder)
- _.each (project.rootFolder or []), (rootFolder) ->
- _process(rootFolder)
- return ids
-
- _findBibDocIds: (project) ->
- ids = []
- _process = (folder) ->
- _.each (folder.docs or []), (doc) ->
- if doc?.name?.match(/^.*\.bib$/)
- ids.push(doc._id)
- _.each (folder.folders or []), (folder) ->
- _process(folder)
- _.each (project.rootFolder or []), (rootFolder) ->
- _process(rootFolder)
- return ids
-
- _isFullIndex: (project, callback = (err, result) ->) ->
- UserGetter.getUser project.owner_ref, { features: true }, (err, owner) ->
- return callback(err) if err?
- features = owner?.features
- callback(null, features?.references == true || features?.referencesSearch == true)
-
- indexAll: (projectId, callback=(err, data)->) ->
- ProjectGetter.getProject projectId, {rootFolder: true, owner_ref: 1}, (err, project) ->
- if err
- logger.err {err, projectId}, "error finding project"
- return callback(err)
- logger.log {projectId}, "indexing all bib files in project"
- docIds = ReferencesHandler._findBibDocIds(project)
- fileIds = ReferencesHandler._findBibFileIds(project)
- ReferencesHandler._doIndexOperation(projectId, project, docIds, fileIds, callback)
-
- index: (projectId, docIds, callback=(err, data)->) ->
- ProjectGetter.getProject projectId, {rootFolder: true, owner_ref: 1}, (err, project) ->
- if err
- logger.err {err, projectId}, "error finding project"
- return callback(err)
- ReferencesHandler._doIndexOperation(projectId, project, docIds, [], callback)
-
- _doIndexOperation: (projectId, project, docIds, fileIds, callback) ->
- if !settings.apis?.references?.url?
- return callback()
- ReferencesHandler._isFullIndex project, (err, isFullIndex) ->
- if err
- logger.err {err, projectId}, "error checking whether to do full index"
- return callback(err)
- logger.log {projectId, docIds}, 'flushing docs to mongo before calling references service'
- Async.series(
- docIds.map((docId) -> (cb) -> DocumentUpdaterHandler.flushDocToMongo(projectId, docId, cb)),
- (err) ->
- # continue
- if err
- logger.err {err, projectId, docIds}, "error flushing docs to mongo"
- return callback(err)
- bibDocUrls = docIds.map (docId) ->
- ReferencesHandler._buildDocUrl projectId, docId
- bibFileUrls = fileIds.map (fileId) ->
- ReferencesHandler._buildFileUrl projectId, fileId
- allUrls = bibDocUrls.concat(bibFileUrls)
- logger.log {projectId, isFullIndex, docIds, bibDocUrls}, "sending request to references service"
- request.post {
- url: "#{settings.apis.references.url}/project/#{projectId}/index"
- json:
- docUrls: allUrls
- fullIndex: isFullIndex
- }, (err, res, data) ->
- if err
- logger.err {err, projectId}, "error communicating with references api"
- return callback(err)
- if 200 <= res.statusCode < 300
- logger.log {projectId}, "got keys from references api"
- return callback(null, data)
- else
- err = new Error("references api responded with non-success code: #{res.statusCode}")
- logger.log {err, projectId}, "error updating references"
- return callback(err)
- )
diff --git a/services/web/app/coffee/Features/Security/LoginRateLimiter.coffee b/services/web/app/coffee/Features/Security/LoginRateLimiter.coffee
deleted file mode 100644
index 20943628ed..0000000000
--- a/services/web/app/coffee/Features/Security/LoginRateLimiter.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-RateLimiter = require('../../infrastructure/RateLimiter')
-
-
-ONE_MIN = 60
-ATTEMPT_LIMIT = 10
-
-
-module.exports =
-
- processLoginRequest: (email, callback) ->
- opts =
- endpointName: 'login'
- throttle: ATTEMPT_LIMIT
- timeInterval: ONE_MIN * 2
- subjectName: email
- RateLimiter.addCount opts, (err, shouldAllow) ->
- callback(err, shouldAllow)
-
- recordSuccessfulLogin: (email, callback = ->)->
- RateLimiter.clearRateLimit 'login', email, callback
-
diff --git a/services/web/app/coffee/Features/Security/OneTimeTokenHandler.coffee b/services/web/app/coffee/Features/Security/OneTimeTokenHandler.coffee
deleted file mode 100644
index 69c9f5b0e9..0000000000
--- a/services/web/app/coffee/Features/Security/OneTimeTokenHandler.coffee
+++ /dev/null
@@ -1,50 +0,0 @@
-Settings = require('settings-sharelatex')
-crypto = require("crypto")
-logger = require("logger-sharelatex")
-{db} = require "../../infrastructure/mongojs"
-Errors = require "../Errors/Errors"
-
-ONE_HOUR_IN_S = 60 * 60
-
-module.exports =
- getNewToken: (use, data, options = {}, callback = (error, data) ->)->
- # options is optional
- if typeof options == "function"
- callback = options
- options = {}
- expiresIn = options.expiresIn or ONE_HOUR_IN_S
- createdAt = new Date()
- expiresAt = new Date(createdAt.getTime() + expiresIn * 1000)
- token = crypto.randomBytes(32).toString("hex")
- logger.log {data, expiresIn, token_start: token.slice(0,8)}, "generating token for #{use}"
- db.tokens.insert {
- use: use
- token: token,
- data: data,
- createdAt: createdAt,
- expiresAt: expiresAt
- }, (error) ->
- return callback(error) if error?
- callback null, token
-
- getValueFromTokenAndExpire: (use, token, callback = (error, data) ->)->
- logger.log token_start: token.slice(0,8), "getting data from #{use} token"
- now = new Date()
- db.tokens.findAndModify {
- query: {
- use: use,
- token: token,
- expiresAt: { $gt: now },
- usedAt: { $exists: false }
- },
- update: {
- $set: {
- usedAt: now
- }
- }
- }, (error, token) ->
- return callback(error) if error?
- if !token?
- return callback(new Errors.NotFoundError('no token found'))
- return callback null, token.data
-
diff --git a/services/web/app/coffee/Features/Security/RateLimiterMiddleware.coffee b/services/web/app/coffee/Features/Security/RateLimiterMiddleware.coffee
deleted file mode 100644
index 631e336cef..0000000000
--- a/services/web/app/coffee/Features/Security/RateLimiterMiddleware.coffee
+++ /dev/null
@@ -1,41 +0,0 @@
-RateLimiter = require "../../infrastructure/RateLimiter"
-logger = require "logger-sharelatex"
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-module.exports = RateLimiterMiddleware =
- ###
- Do not allow more than opts.maxRequests from a single client in
- opts.timeInterval. Pass an array of opts.params to segment this based on
- parameters in the request URL, e.g.:
-
- app.get "/project/:project_id", RateLimiterMiddleware.rateLimit(endpointName: "open-editor", params: ["project_id"])
-
- will rate limit each project_id separately.
-
- Unique clients are identified by user_id if logged in, and IP address if not.
- ###
- rateLimit: (opts) ->
- return (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req) || req.ip
- params = (opts.params or []).map (p) -> req.params[p]
- params.push user_id
- subjectName = params.join(":")
- if opts.ipOnly
- subjectName = req.ip
- if !opts.endpointName?
- throw new Error("no endpointName provided")
- options = {
- endpointName: opts.endpointName
- timeInterval: opts.timeInterval or 60
- subjectName: subjectName
- throttle: opts.maxRequests or 6
- }
- RateLimiter.addCount options, (error, canContinue)->
- return next(error) if error?
- if canContinue
- next()
- else
- logger.warn options, "rate limit exceeded"
- res.status(429) # Too many requests
- res.write("Rate limit reached, please try again later")
- res.end()
diff --git a/services/web/app/coffee/Features/ServerAdmin/AdminController.coffee b/services/web/app/coffee/Features/ServerAdmin/AdminController.coffee
deleted file mode 100755
index b813878335..0000000000
--- a/services/web/app/coffee/Features/ServerAdmin/AdminController.coffee
+++ /dev/null
@@ -1,90 +0,0 @@
-metrics = require("metrics-sharelatex")
-logger = require('logger-sharelatex')
-_ = require('underscore')
-User = require('../../models/User').User
-Project = require('../../models/Project').Project
-DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-Settings = require('settings-sharelatex')
-util = require('util')
-RecurlyWrapper = require('../Subscription/RecurlyWrapper')
-SubscriptionHandler = require('../Subscription/SubscriptionHandler')
-projectEntityHandler = require('../Project/ProjectEntityHandler')
-TpdsUpdateSender = require("../ThirdPartyDataStore/TpdsUpdateSender")
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-SystemMessageManager = require("../SystemMessages/SystemMessageManager")
-
-oneMinInMs = 60 * 1000
-
-updateOpenConnetionsMetrics = ()->
- metrics.gauge "open_connections.socketio", require("../../infrastructure/Server").io?.sockets?.clients()?.length
- metrics.gauge "open_connections.http", _.size(require('http').globalAgent?.sockets)
- metrics.gauge "open_connections.https", _.size(require('https').globalAgent?.sockets)
- setTimeout updateOpenConnetionsMetrics, oneMinInMs
-
-setTimeout updateOpenConnetionsMetrics, oneMinInMs
-
-
-
-module.exports = AdminController =
-
- index : (req, res, next)=>
- http = require('http')
- openSockets = {}
- for url, agents of require('http').globalAgent.sockets
- openSockets["http://#{url}"] = (agent._httpMessage.path for agent in agents)
- for url, agents of require('https').globalAgent.sockets
- openSockets["https://#{url}"] = (agent._httpMessage.path for agent in agents)
-
- SystemMessageManager.getMessagesFromDB (error, systemMessages) ->
- return next(error) if error?
- res.render 'admin/index',
- title: 'System Admin'
- openSockets: openSockets
- systemMessages: systemMessages
-
- registerNewUser: (req, res, next) ->
- res.render 'admin/register'
-
- dissconectAllUsers: (req, res)=>
- logger.warn "disconecting everyone"
- EditorRealTimeController.emitToAll 'forceDisconnect', "Sorry, we are performing a quick update to the editor and need to close it down. Please refresh the page to continue."
- res.sendStatus(200)
-
- closeEditor : (req, res)->
- logger.warn "closing editor"
- Settings.editorIsOpen = req.body.isOpen
- res.sendStatus(200)
-
- writeAllToMongo : (req, res)->
- logger.log "writing all docs to mongo"
- Settings.mongo.writeAll = true
- DocumentUpdaterHandler.flushAllDocsToMongo ()->
- logger.log "all docs have been saved to mongo"
- res.send()
-
- syncUserToSubscription: (req, res)->
- {user_id, subscription_id} = req.body
- RecurlyWrapper.getSubscription subscription_id, {}, (err, subscription)->
- User.findById user_id, (err, user)->
- SubscriptionHandler.syncSubscriptionToUser subscription, user._id, (err)->
- logger.log user_id:user_id, subscription_id:subscription_id, "linked account to subscription"
- res.send()
-
- flushProjectToTpds: (req, res)->
- projectEntityHandler.flushProjectToThirdPartyDataStore req.body.project_id, (err)->
- res.sendStatus 200
-
- pollDropboxForUser: (req, res)->
- user_id = req.body.user_id
- TpdsUpdateSender.pollDropboxForUser user_id, () ->
- res.sendStatus 200
-
- createMessage: (req, res, next) ->
- SystemMessageManager.createMessage req.body.content, (error) ->
- return next(error) if error?
- res.sendStatus 200
-
- clearMessages: (req, res, next) ->
- SystemMessageManager.clearMessages (error) ->
- return next(error) if error?
- res.sendStatus 200
diff --git a/services/web/app/coffee/Features/Spelling/SpellingController.coffee b/services/web/app/coffee/Features/Spelling/SpellingController.coffee
deleted file mode 100644
index cff53ec171..0000000000
--- a/services/web/app/coffee/Features/Spelling/SpellingController.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-request = require 'request'
-Settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-TEN_SECONDS = 1000 * 10
-
-module.exports = SpellingController =
- proxyRequestToSpellingApi: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- url = req.url.slice("/spelling".length)
- url = "/user/#{user_id}#{url}"
- req.headers["Host"] = Settings.apis.spelling.host
- request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS)
- .on "error", (error) ->
- logger.error err: error, "Spelling API error"
- res.status(500).end()
- .pipe(res)
diff --git a/services/web/app/coffee/Features/StaticPages/HomeController.coffee b/services/web/app/coffee/Features/StaticPages/HomeController.coffee
deleted file mode 100755
index a6c0bef978..0000000000
--- a/services/web/app/coffee/Features/StaticPages/HomeController.coffee
+++ /dev/null
@@ -1,41 +0,0 @@
-logger = require('logger-sharelatex')
-Settings = require('settings-sharelatex')
-_ = require('underscore')
-Features = require "../../infrastructure/Features"
-
-Path = require "path"
-fs = require "fs"
-
-ErrorController = require "../Errors/ErrorController"
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-slHomepageExists = fs.existsSync Path.resolve(__dirname + "/../../../views/external/home/sl.pug")
-v2HomepageExists = fs.existsSync Path.resolve(__dirname + "/../../../views/external/home/v2.pug")
-
-module.exports = HomeController =
- index : (req,res)->
- if AuthenticationController.isUserLoggedIn(req)
- if req.query.scribtex_path?
- res.redirect "/project?scribtex_path=#{req.query.scribtex_path}"
- else
- res.redirect '/project'
- else
- HomeController.home(req, res)
-
- home: (req, res, next)->
- if Features.hasFeature('homepage') and !Settings.overleaf and slHomepageExists
- res.render 'external/home/sl'
- else if Features.hasFeature('homepage') and Settings.overleaf and v2HomepageExists
- res.render 'external/home/v2'
- else
- res.redirect '/login'
-
- externalPage: (page, title) ->
- return (req, res, next = (error) ->) ->
- path = Path.resolve(__dirname + "/../../../views/external/#{page}.pug")
- fs.exists path, (exists) -> # No error in this callback - old method in Node.js!
- if exists
- res.render "external/#{page}.pug",
- title: title
- else
- ErrorController.notFound(req, res, next)
diff --git a/services/web/app/coffee/Features/StaticPages/StaticPageHelpers.coffee b/services/web/app/coffee/Features/StaticPages/StaticPageHelpers.coffee
deleted file mode 100644
index 068fa86e43..0000000000
--- a/services/web/app/coffee/Features/StaticPages/StaticPageHelpers.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-extensionsToProxy = [".png", ".xml", ".jpeg", ".json", ".zip", ".eps", ".gif", ".jpg"]
-_ = require("underscore")
-
-module.exports =
- shouldProxy: (url)->
- shouldProxy = _.find extensionsToProxy, (extension)->
- url.indexOf(extension) != -1
- return shouldProxy
-
-
-
-
diff --git a/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee b/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee
deleted file mode 100644
index e33cae555a..0000000000
--- a/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee
+++ /dev/null
@@ -1,25 +0,0 @@
-HomeController = require('./HomeController')
-UniversityController = require("./UniversityController")
-
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.get '/', HomeController.index
- webRouter.get '/home', HomeController.home
-
- webRouter.get '/tos', HomeController.externalPage("tos", "Terms of Service")
- webRouter.get '/about', HomeController.externalPage("about", "About Us")
-
- webRouter.get '/security', HomeController.externalPage("security", "Security")
- webRouter.get '/privacy_policy', HomeController.externalPage("privacy", "Privacy Policy")
- webRouter.get '/planned_maintenance', HomeController.externalPage("planned_maintenance", "Planned Maintenance")
- webRouter.get '/style', HomeController.externalPage("style_guide", "Style Guide")
- webRouter.get '/ol-style', HomeController.externalPage("ol_style_guide", "Overleaf Style Guide")
- webRouter.get '/jobs', HomeController.externalPage("jobs", "Jobs")
-
- webRouter.get '/track-changes-and-comments-in-latex', HomeController.externalPage("review-features-page", "Review features")
-
- webRouter.get '/dropbox', HomeController.externalPage("dropbox", "Dropbox and ShareLaTeX")
-
- webRouter.get '/university', UniversityController.getIndexPage
- webRouter.get '/university/*', UniversityController.getPage
diff --git a/services/web/app/coffee/Features/StaticPages/UniversityController.coffee b/services/web/app/coffee/Features/StaticPages/UniversityController.coffee
deleted file mode 100644
index 3caa5ecf5b..0000000000
--- a/services/web/app/coffee/Features/StaticPages/UniversityController.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-Settings = require("settings-sharelatex")
-sixpack = require("../../infrastructure/Sixpack")
-
-
-
-module.exports = UniversityController =
-
- getPage: (req, res, next)->
- url = req.url?.toLowerCase().replace(".html","")
- return res.redirect("/i#{url}")
-
- getIndexPage: (req, res)->
- return res.redirect("/i/university")
-
diff --git a/services/web/app/coffee/Features/Subscription/FeaturesUpdater.coffee b/services/web/app/coffee/Features/Subscription/FeaturesUpdater.coffee
deleted file mode 100644
index d95596b060..0000000000
--- a/services/web/app/coffee/Features/Subscription/FeaturesUpdater.coffee
+++ /dev/null
@@ -1,102 +0,0 @@
-async = require("async")
-PlansLocator = require("./PlansLocator")
-_ = require("underscore")
-SubscriptionLocator = require("./SubscriptionLocator")
-UserFeaturesUpdater = require("./UserFeaturesUpdater")
-Settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-ReferalFeatures = require("../Referal/ReferalFeatures")
-V1SubscriptionManager = require("./V1SubscriptionManager")
-InstitutionsFeatures = require '../Institutions/InstitutionsFeatures'
-
-oneMonthInSeconds = 60 * 60 * 24 * 30
-
-module.exports = FeaturesUpdater =
- refreshFeatures: (user_id, notifyV1 = true, callback = (error, features, featuresChanged) ->)->
- if typeof notifyV1 == 'function'
- callback = notifyV1
- notifyV1 = true
-
- if notifyV1
- V1SubscriptionManager.notifyV1OfFeaturesChange user_id, (error) ->
- if error?
- logger.err {err: error, user_id}, "error notifying v1 about updated features"
-
-
- jobs =
- individualFeatures: (cb) -> FeaturesUpdater._getIndividualFeatures user_id, cb
- groupFeatureSets: (cb) -> FeaturesUpdater._getGroupFeatureSets user_id, cb
- institutionFeatures:(cb) -> InstitutionsFeatures.getInstitutionsFeatures user_id, cb
- v1Features: (cb) -> FeaturesUpdater._getV1Features user_id, cb
- bonusFeatures: (cb) -> ReferalFeatures.getBonusFeatures user_id, cb
- async.series jobs, (err, results)->
- if err?
- logger.err err:err, user_id:user_id,
- "error getting subscription or group for refreshFeatures"
- return callback(err)
-
- {individualFeatures, groupFeatureSets, institutionFeatures, v1Features, bonusFeatures} = results
- logger.log {user_id, individualFeatures, groupFeatureSets, institutionFeatures, v1Features, bonusFeatures}, 'merging user features'
- featureSets = groupFeatureSets.concat [individualFeatures, institutionFeatures, v1Features, bonusFeatures]
- features = _.reduce(featureSets, FeaturesUpdater._mergeFeatures, Settings.defaultFeatures)
-
- logger.log {user_id, features}, 'updating user features'
- UserFeaturesUpdater.updateFeatures user_id, features, callback
-
- _getIndividualFeatures: (user_id, callback = (error, features = {}) ->) ->
- SubscriptionLocator.getUsersSubscription user_id, (err, sub)->
- callback err, FeaturesUpdater._subscriptionToFeatures(sub)
-
- _getGroupFeatureSets: (user_id, callback = (error, featureSets = []) ->) ->
- SubscriptionLocator.getGroupSubscriptionsMemberOf user_id, (err, subs) ->
- callback err, (subs or []).map FeaturesUpdater._subscriptionToFeatures
-
- _getV1Features: (user_id, callback = (error, features = {}) ->) ->
- V1SubscriptionManager.getPlanCodeFromV1 user_id, (err, planCode, v1Id) ->
- if err?
- return callback(null, []) if err?.name == 'NotFoundError'
- return callback(err)
-
- callback(err, FeaturesUpdater._mergeFeatures(
- V1SubscriptionManager.getGrandfatheredFeaturesForV1User(v1Id) or {},
- FeaturesUpdater._planCodeToFeatures(planCode)
- ))
-
- _mergeFeatures: (featuresA, featuresB) ->
- features = Object.assign({}, featuresA)
- for key, value of featuresB
- # Special merging logic for non-boolean features
- if key == 'compileGroup'
- if features['compileGroup'] == 'priority' or featuresB['compileGroup'] == 'priority'
- features['compileGroup'] = 'priority'
- else
- features['compileGroup'] = 'standard'
- else if key == 'collaborators'
- if features['collaborators'] == -1 or featuresB['collaborators'] == -1
- features['collaborators'] = -1
- else
- features['collaborators'] = Math.max(
- features['collaborators'] or 0,
- featuresB['collaborators'] or 0
- )
- else if key == 'compileTimeout'
- features['compileTimeout'] = Math.max(
- features['compileTimeout'] or 0,
- featuresB['compileTimeout'] or 0
- )
- else
- # Boolean keys, true is better
- features[key] = features[key] or featuresB[key]
- return features
-
- _subscriptionToFeatures: (subscription) ->
- FeaturesUpdater._planCodeToFeatures(subscription?.planCode)
-
- _planCodeToFeatures: (planCode) ->
- if !planCode?
- return {}
- plan = PlansLocator.findLocalPlanInSettings planCode
- if !plan?
- return {}
- else
- return plan.features
diff --git a/services/web/app/coffee/Features/Subscription/GroupPlansData.coffee b/services/web/app/coffee/Features/Subscription/GroupPlansData.coffee
deleted file mode 100644
index f72f882039..0000000000
--- a/services/web/app/coffee/Features/Subscription/GroupPlansData.coffee
+++ /dev/null
@@ -1,37 +0,0 @@
-Settings = require 'settings-sharelatex'
-fs = require('fs')
-
-# The groups.json file encodes the various group plan options we provide, and
-# is used in the app the render the appropriate dialog in the plans page, and
-# to generate the appropriate entries in the Settings.plans array.
-# It is also used by scripts/recurly/sync_recurly.rb, which will make sure
-# Recurly has a plan configured for all the groups, and that the prices are
-# up to date with the data in groups.json.
-data = fs.readFileSync(__dirname + '/../../../templates/plans/groups.json')
-groups = JSON.parse(data.toString())
-
-capitalize = (string) ->
- string.charAt(0).toUpperCase() + string.slice(1);
-
-# With group accounts in Recurly, we end up with a lot of plans to manage.
-# Rather than hand coding them in the settings file, and then needing to keep
-# that data in sync with the data in groups.json, we can auto generate the
-# group plan entries and append them to Settings.plans at boot time. This is not
-# a particularly clean pattern, since it's a little surprising that settings
-# are modified at boot-time, but I think it's a better option than trying to
-# keep two sources of data in sync.
-for usage, plan_data of groups
- for plan_code, currency_data of plan_data
- for currency, price_data of currency_data
- for size, price of price_data
- Settings.plans.push {
- planCode: "group_#{plan_code}_#{size}_#{usage}",
- name: "#{Settings.appName} #{capitalize(plan_code)} - Group Account (#{size} licenses) - #{capitalize(usage)}",
- hideFromUsers: true,
- annual: true
- features: Settings.features[plan_code]
- groupPlan: true
- membersLimit: parseInt(size)
- }
-
-module.exports = groups
diff --git a/services/web/app/coffee/Features/Subscription/LimitationsManager.coffee b/services/web/app/coffee/Features/Subscription/LimitationsManager.coffee
deleted file mode 100644
index c34b6c028d..0000000000
--- a/services/web/app/coffee/Features/Subscription/LimitationsManager.coffee
+++ /dev/null
@@ -1,97 +0,0 @@
-logger = require("logger-sharelatex")
-ProjectGetter = require('../Project/ProjectGetter')
-UserGetter = require("../User/UserGetter")
-SubscriptionLocator = require("./SubscriptionLocator")
-Settings = require("settings-sharelatex")
-CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler")
-CollaboratorsInvitesHandler = require("../Collaborators/CollaboratorsInviteHandler")
-V1SubscriptionManager = require("./V1SubscriptionManager")
-
-module.exports = LimitationsManager =
- allowedNumberOfCollaboratorsInProject: (project_id, callback) ->
- ProjectGetter.getProject project_id, owner_ref: true, (error, project) =>
- return callback(error) if error?
- @allowedNumberOfCollaboratorsForUser project.owner_ref, callback
-
- allowedNumberOfCollaboratorsForUser: (user_id, callback) ->
- UserGetter.getUser user_id, {features: 1}, (error, user) ->
- return callback(error) if error?
- if user.features? and user.features.collaborators?
- callback null, user.features.collaborators
- else
- callback null, Settings.defaultFeatures.collaborators
-
- canAddXCollaborators: (project_id, x_collaborators, callback = (error, allowed)->) ->
- @allowedNumberOfCollaboratorsInProject project_id, (error, allowed_number) =>
- return callback(error) if error?
- CollaboratorsHandler.getInvitedCollaboratorCount project_id, (error, current_number) =>
- return callback(error) if error?
- CollaboratorsInvitesHandler.getInviteCount project_id, (error, invite_count) =>
- return callback(error) if error?
- if current_number + invite_count + x_collaborators <= allowed_number or allowed_number < 0
- callback null, true
- else
- callback null, false
-
- hasPaidSubscription: (user, callback = (err, hasSubscriptionOrIsMember)->) ->
- @userHasV2Subscription user, (err, hasSubscription, subscription)=>
- return callback(err) if err?
- @userIsMemberOfGroupSubscription user, (err, isMember)=>
- return callback(err) if err?
- @userHasV1Subscription user, (err, hasV1Subscription)=>
- return callback(err) if err?
- logger.log {user_id:user._id, isMember, hasSubscription, hasV1Subscription}, "checking if user has subscription or is group member"
- callback err, isMember or hasSubscription or hasV1Subscription, subscription
-
-
- # alias for backward-compatibility with modules. Use `haspaidsubscription` instead
- userHasSubscriptionOrIsGroupMember: (user, callback) ->
- @hasPaidSubscription(user, callback)
-
- userHasV2Subscription: (user, callback = (err, hasSubscription, subscription)->) ->
- logger.log user_id:user._id, "checking if user has subscription"
- SubscriptionLocator.getUsersSubscription user._id, (err, subscription)->
- if err?
- return callback(err)
- hasValidSubscription = subscription? and (subscription.recurlySubscription_id? or subscription?.customAccount == true)
- logger.log user:user, hasValidSubscription:hasValidSubscription, subscription:subscription, "checking if user has subscription"
- callback err, hasValidSubscription, subscription
-
- userHasV1OrV2Subscription: (user, callback = (err, hasSubscription) ->) ->
- @userHasV2Subscription user, (err, hasV2Subscription) =>
- return callback(err) if err?
- return callback null, true if hasV2Subscription
- @userHasV1Subscription user, (err, hasV1Subscription) =>
- return callback(err) if err?
- return callback null, true if hasV1Subscription
- return callback null, false
-
- userIsMemberOfGroupSubscription: (user, callback = (error, isMember, subscriptions) ->) ->
- logger.log user_id: user._id, "checking is user is member of subscription groups"
- SubscriptionLocator.getMemberSubscriptions user._id, (err, subscriptions = []) ->
- return callback(err) if err?
- callback err, subscriptions.length > 0, subscriptions
-
- userHasV1Subscription: (user, callback = (error, hasV1Subscription) ->) ->
- V1SubscriptionManager.getSubscriptionsFromV1 user._id, (err, v1Subscription) ->
- logger.log {user_id: user._id, v1Subscription}, '[userHasV1Subscription]'
- callback err, !!v1Subscription?.has_subscription
-
- teamHasReachedMemberLimit: (subscription) ->
- currentTotal = (subscription.member_ids or []).length +
- (subscription.teamInvites or []).length +
- (subscription.invited_emails or []).length
-
- return currentTotal >= subscription.membersLimit
-
- hasGroupMembersLimitReached: (subscriptionId, callback = (err, limitReached, subscription)->)->
- SubscriptionLocator.getSubscription subscriptionId, (err, subscription)->
- if err?
- logger.err err:err, subscriptionId: subscriptionId, "error getting subscription"
- return callback(err)
- if !subscription?
- logger.err subscriptionId: subscriptionId, "no subscription found"
- return callback("no subscription found")
-
- limitReached = LimitationsManager.teamHasReachedMemberLimit(subscription)
- callback(err, limitReached, subscription)
diff --git a/services/web/app/coffee/Features/Subscription/PlansLocator.coffee b/services/web/app/coffee/Features/Subscription/PlansLocator.coffee
deleted file mode 100644
index 49d7a29b79..0000000000
--- a/services/web/app/coffee/Features/Subscription/PlansLocator.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-Settings = require("settings-sharelatex")
-
-module.exports =
-
- findLocalPlanInSettings: (planCode) ->
- for plan in Settings.plans
- return plan if plan.planCode == planCode
- return null
-
diff --git a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee b/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee
deleted file mode 100644
index 0a179cd81f..0000000000
--- a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee
+++ /dev/null
@@ -1,540 +0,0 @@
-querystring = require 'querystring'
-crypto = require 'crypto'
-request = require 'request'
-Settings = require "settings-sharelatex"
-xml2js = require "xml2js"
-logger = require("logger-sharelatex")
-Async = require('async')
-
-module.exports = RecurlyWrapper =
- apiUrl : Settings.apis?.recurly?.url or "https://api.recurly.com/v2"
-
- _addressToXml: (address) ->
- allowedKeys = ['address1', 'address2', 'city', 'country', 'state', 'zip', 'postal_code']
- resultString = "\n"
- for k, v of address
- if k == 'postal_code'
- k = 'zip'
- if v and (k in allowedKeys)
- resultString += "<#{k}#{if k == 'address2' then ' nil="nil"' else ''}>#{v || ''}#{k}>\n"
- resultString += "\n"
- return resultString
-
- _paypal:
- checkAccountExists: (cache, next) ->
- user = cache.user
- recurly_token_id = cache.recurly_token_id
- subscriptionDetails = cache.subscriptionDetails
- logger.log {user_id: user._id, recurly_token_id}, "checking if recurly account exists for user"
- RecurlyWrapper.apiRequest({
- url: "accounts/#{user._id}"
- method: "GET"
- expect404: true
- }, (error, response, responseBody) ->
- if error
- logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while checking account"
- return next(error)
- if response.statusCode == 404 # actually not an error in this case, just no existing account
- logger.log {user_id: user._id, recurly_token_id}, "user does not currently exist in recurly, proceed"
- cache.userExists = false
- return next(null, cache)
- logger.log {user_id: user._id, recurly_token_id}, "user appears to exist in recurly"
- RecurlyWrapper._parseAccountXml responseBody, (err, account) ->
- if err
- logger.error {err, user_id: user._id, recurly_token_id}, "error parsing account"
- return next(err)
- cache.userExists = true
- cache.account = account
- return next(null, cache)
- )
- createAccount: (cache, next) ->
- user = cache.user
- recurly_token_id = cache.recurly_token_id
- subscriptionDetails = cache.subscriptionDetails
- address = subscriptionDetails.address
- if !address
- return next(new Error('no address in subscriptionDetails at createAccount stage'))
- if cache.userExists
- logger.log {user_id: user._id, recurly_token_id}, "user already exists in recurly"
- return next(null, cache)
- logger.log {user_id: user._id, recurly_token_id}, "creating user in recurly"
- requestBody = """
-
- #{user._id}
- #{user.email}
- #{user.first_name}
- #{user.last_name}
-
- #{address.address1}
- #{address.address2}
- #{address.city || ''}
- #{address.state || ''}
- #{address.zip || ''}
- #{address.country}
-
-
- """
- RecurlyWrapper.apiRequest({
- url : "accounts"
- method : "POST"
- body : requestBody
- }, (error, response, responseBody) =>
- if error
- logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating account"
- return next(error)
- RecurlyWrapper._parseAccountXml responseBody, (err, account) ->
- if err
- logger.error {err, user_id: user._id, recurly_token_id}, "error creating account"
- return next(err)
- cache.account = account
- return next(null, cache)
- )
- createBillingInfo: (cache, next) ->
- user = cache.user
- recurly_token_id = cache.recurly_token_id
- subscriptionDetails = cache.subscriptionDetails
- logger.log {user_id: user._id, recurly_token_id}, "creating billing info in recurly"
- accountCode = cache?.account?.account_code
- if !accountCode
- return next(new Error('no account code at createBillingInfo stage'))
- requestBody = """
-
- #{recurly_token_id}
-
- """
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountCode}/billing_info"
- method: "POST"
- body: requestBody
- }, (error, response, responseBody) =>
- if error
- logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating billing info"
- return next(error)
- RecurlyWrapper._parseBillingInfoXml responseBody, (err, billingInfo) ->
- if err
- logger.error {err, user_id: user._id, accountCode, recurly_token_id}, "error creating billing info"
- return next(err)
- cache.billingInfo = billingInfo
- return next(null, cache)
- )
-
- setAddress: (cache, next) ->
- user = cache.user
- recurly_token_id = cache.recurly_token_id
- subscriptionDetails = cache.subscriptionDetails
- logger.log {user_id: user._id, recurly_token_id}, "setting billing address in recurly"
- accountCode = cache?.account?.account_code
- if !accountCode
- return next(new Error('no account code at setAddress stage'))
- address = subscriptionDetails.address
- if !address
- return next(new Error('no address in subscriptionDetails at setAddress stage'))
- requestBody = RecurlyWrapper._addressToXml(address)
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountCode}/billing_info"
- method: "PUT"
- body: requestBody
- }, (error, response, responseBody) =>
- if error
- logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while setting address"
- return next(error)
- RecurlyWrapper._parseBillingInfoXml responseBody, (err, billingInfo) ->
- if err
- logger.error {err, user_id: user._id, recurly_token_id}, "error updating billing info"
- return next(err)
- cache.billingInfo = billingInfo
- return next(null, cache)
- )
- createSubscription: (cache, next) ->
- user = cache.user
- recurly_token_id = cache.recurly_token_id
- subscriptionDetails = cache.subscriptionDetails
- logger.log {user_id: user._id, recurly_token_id}, "creating subscription in recurly"
- requestBody = """
-
- #{subscriptionDetails.plan_code}
- #{subscriptionDetails.currencyCode}
- #{subscriptionDetails.coupon_code}
-
- #{user._id}
-
-
- """ # TODO: check account details and billing
- RecurlyWrapper.apiRequest({
- url : "subscriptions"
- method : "POST"
- body : requestBody
- }, (error, response, responseBody) =>
- if error
- logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating subscription"
- return next(error)
- RecurlyWrapper._parseSubscriptionXml responseBody, (err, subscription) ->
- if err
- logger.error {err, user_id: user._id, recurly_token_id}, "error creating subscription"
- return next(err)
- cache.subscription = subscription
- return next(null, cache)
- )
-
- _createPaypalSubscription: (user, subscriptionDetails, recurly_token_id, callback) ->
- logger.log {user_id: user._id, recurly_token_id}, "starting process of creating paypal subscription"
- # We use `async.waterfall` to run each of these actions in sequence
- # passing a `cache` object along the way. The cache is initialized
- # with required data, and `async.apply` to pass the cache to the first function
- cache = {user, recurly_token_id, subscriptionDetails}
- Async.waterfall([
- Async.apply(RecurlyWrapper._paypal.checkAccountExists, cache),
- RecurlyWrapper._paypal.createAccount,
- RecurlyWrapper._paypal.createBillingInfo,
- RecurlyWrapper._paypal.setAddress,
- RecurlyWrapper._paypal.createSubscription,
- ], (err, result) ->
- if err
- logger.error {err, user_id: user._id, recurly_token_id}, "error in paypal subscription creation process"
- return callback(err)
- if !result.subscription
- err = new Error('no subscription object in result')
- logger.error {err, user_id: user._id, recurly_token_id}, "error in paypal subscription creation process"
- return callback(err)
- logger.log {user_id: user._id, recurly_token_id}, "done creating paypal subscription for user"
- callback(null, result.subscription)
- )
-
- _createCreditCardSubscription: (user, subscriptionDetails, recurly_token_id, callback) ->
- requestBody = """
-
- #{subscriptionDetails.plan_code}
- #{subscriptionDetails.currencyCode}
- #{subscriptionDetails.coupon_code}
-
- #{user._id}
- #{user.email}
- #{user.first_name}
- #{user.last_name}
-
- #{recurly_token_id}
-
-
-
- """
- RecurlyWrapper.apiRequest({
- url : "subscriptions"
- method : "POST"
- body : requestBody
- }, (error, response, responseBody) =>
- return callback(error) if error?
- RecurlyWrapper._parseSubscriptionXml responseBody, callback
- )
-
- createSubscription: (user, subscriptionDetails, recurly_token_id, callback)->
- isPaypal = subscriptionDetails.isPaypal
- logger.log {user_id: user._id, isPaypal, recurly_token_id}, "setting up subscription in recurly"
- fn = if isPaypal then RecurlyWrapper._createPaypalSubscription else RecurlyWrapper._createCreditCardSubscription
- fn user, subscriptionDetails, recurly_token_id, callback
-
- apiRequest : (options, callback) ->
- options.url = RecurlyWrapper.apiUrl + "/" + options.url
- options.headers =
- "Authorization" : "Basic " + new Buffer(Settings.apis.recurly.apiKey).toString("base64")
- "Accept" : "application/xml"
- "Content-Type" : "application/xml; charset=utf-8"
- expect404 = options.expect404
- delete options.expect404
- request options, (error, response, body) ->
- unless error? or response.statusCode == 200 or response.statusCode == 201 or response.statusCode == 204 or (response.statusCode == 404 and expect404)
- logger.err err:error, body:body, options:options, statusCode:response?.statusCode, "error returned from recurly"
- error = "Recurly API returned with status code: #{response.statusCode}"
- if response.statusCode == 404 and expect404
- logger.log {url: options.url, method: options.method}, "got 404 response from recurly, expected as valid response"
- callback(error, response, body)
-
- getSubscriptions: (accountId, callback)->
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountId}/subscriptions"
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseXml body, callback
- )
-
-
- getSubscription: (subscriptionId, options, callback) ->
- callback = options unless callback?
- options ||= {}
-
- if options.recurlyJsResult
- url = "recurly_js/result/#{subscriptionId}"
- else
- url = "subscriptions/#{subscriptionId}"
-
- RecurlyWrapper.apiRequest({
- url: url
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseSubscriptionXml body, (error, recurlySubscription) =>
- return callback(error) if error?
- if options.includeAccount
- if recurlySubscription.account? and recurlySubscription.account.url?
- accountId = recurlySubscription.account.url.match(/accounts\/(.*)/)[1]
- else
- return callback "I don't understand the response from Recurly"
-
- RecurlyWrapper.getAccount accountId, (error, account) ->
- return callback(error) if error?
- recurlySubscription.account = account
- callback null, recurlySubscription
-
- else
- callback null, recurlySubscription
- )
-
- getAccounts: (callback)->
- allAccounts = []
- getPageOfAccounts = (cursor = null)=>
- opts =
- url: "accounts"
- qs:
- per_page:200
- if cursor?
- opts.qs.cursor = cursor
- RecurlyWrapper.apiRequest opts, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseXml body, (err, data)->
- if err?
- logger.err err:err, "could not get accoutns"
- callback(err)
- allAccounts = allAccounts.concat(data.accounts)
- logger.log "got another #{data.accounts.length}, total now #{allAccounts.length}"
- cursor = response.headers.link?.match(/cursor=([0-9]+)&/)?[1]
- if cursor?
- getPageOfAccounts(cursor)
- else
- callback(err, allAccounts)
-
- getPageOfAccounts()
-
-
- getAccount: (accountId, callback) ->
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountId}"
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseAccountXml body, callback
- )
-
- getAccountActiveCoupons: (accountId, callback) ->
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountId}/redemptions"
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseRedemptionsXml body, (error, redemptions) ->
- return callback(error) if error?
- activeRedemptions = redemptions.filter (redemption) ->
- redemption.state == 'active'
- couponCodes = activeRedemptions.map (redemption) ->
- redemption.coupon_code
- Async.map couponCodes, RecurlyWrapper.getCoupon, (error, coupons) ->
- return callback(error) if error?
- callback(null, coupons)
- )
-
- getCoupon: (couponCode, callback) ->
- opts = { url: "coupons/#{couponCode}" }
- RecurlyWrapper.apiRequest opts, (error, response, body) ->
- RecurlyWrapper._parseCouponXml body, callback
-
- getBillingInfo: (accountId, callback)->
- RecurlyWrapper.apiRequest({
- url: "accounts/#{accountId}/billing_info"
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseXml body, callback
- )
-
-
- updateSubscription: (subscriptionId, options, callback) ->
- logger.log subscriptionId:subscriptionId, options:options, "telling recurly to update subscription"
- requestBody = """
-
- #{options.plan_code}
- #{options.timeframe}
-
- """
- RecurlyWrapper.apiRequest({
- url : "subscriptions/#{subscriptionId}"
- method : "put"
- body : requestBody
- }, (error, response, responseBody) =>
- return callback(error) if error?
- RecurlyWrapper._parseSubscriptionXml responseBody, callback
- )
-
- createFixedAmmountCoupon: (coupon_code, name, currencyCode, discount_in_cents, plan_code, callback)->
- requestBody = """
-
- #{coupon_code}
- #{name}
- dollars
-
- <#{currencyCode}>#{discount_in_cents}#{currencyCode}>
-
-
- #{plan_code}
-
- false
-
- """
- logger.log coupon_code:coupon_code, requestBody:requestBody, "creating coupon"
- RecurlyWrapper.apiRequest({
- url : "coupons"
- method : "post"
- body : requestBody
- }, (error, response, responseBody) =>
- if error?
- logger.err err:error, coupon_code:coupon_code, "error creating coupon"
- callback(error)
- )
-
-
- lookupCoupon: (coupon_code, callback)->
- RecurlyWrapper.apiRequest({
- url: "coupons/#{coupon_code}"
- }, (error, response, body) =>
- return callback(error) if error?
- RecurlyWrapper._parseXml body, callback
- )
-
- cancelSubscription: (subscriptionId, callback) ->
- logger.log subscriptionId:subscriptionId, "telling recurly to cancel subscription"
- RecurlyWrapper.apiRequest({
- url: "subscriptions/#{subscriptionId}/cancel",
- method: "put"
- }, (error, response, body) ->
- if error?
- RecurlyWrapper._parseXml body, (_err, parsed) ->
- if parsed?.error?.description == "A canceled subscription can't transition to canceled"
- logger.log {subscriptionId, error, body}, "subscription already cancelled, not really an error, proceeding"
- callback(null)
- else
- callback(error)
- else
- callback(null)
- )
-
- reactivateSubscription: (subscriptionId, callback) ->
- logger.log subscriptionId:subscriptionId, "telling recurly to reactivating subscription"
- RecurlyWrapper.apiRequest({
- url: "subscriptions/#{subscriptionId}/reactivate",
- method: "put"
- }, (error, response, body) ->
- callback(error)
- )
-
-
- redeemCoupon: (account_code, coupon_code, callback)->
- requestBody = """
-
- #{account_code}
- USD
-
- """
- logger.log account_code:account_code, coupon_code:coupon_code, requestBody:requestBody, "redeeming coupon for user"
- RecurlyWrapper.apiRequest({
- url : "coupons/#{coupon_code}/redeem"
- method : "post"
- body : requestBody
- }, (error, response, responseBody) =>
- if error?
- logger.err err:error, account_code:account_code, coupon_code:coupon_code, "error redeeming coupon"
- callback(error)
- )
-
- extendTrial: (subscriptionId, daysUntilExpire = 7, callback)->
- next_renewal_date = new Date()
- next_renewal_date.setDate(next_renewal_date.getDate() + daysUntilExpire)
- logger.log subscriptionId:subscriptionId, daysUntilExpire:daysUntilExpire, "Exending Free trial for user"
- RecurlyWrapper.apiRequest({
- url : "/subscriptions/#{subscriptionId}/postpone?next_renewal_date=#{next_renewal_date}&bulk=false"
- method : "put"
- }, (error, response, responseBody) =>
- if error?
- logger.err err:error, subscriptionId:subscriptionId, daysUntilExpire:daysUntilExpire, "error exending trial"
- callback(error)
- )
-
- listAccountActiveSubscriptions: (account_id, callback = (error, subscriptions) ->) ->
- RecurlyWrapper.apiRequest {
- url: "accounts/#{account_id}/subscriptions"
- qs:
- state: "active"
- expect404: true
- }, (error, response, body) ->
- return callback(error) if error?
- if response.statusCode == 404
- return callback null, []
- else
- RecurlyWrapper._parseSubscriptionsXml body, callback
-
- _parseSubscriptionsXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "subscriptions", callback
-
- _parseSubscriptionXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "subscription", callback
-
- _parseAccountXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "account", callback
-
- _parseBillingInfoXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "billing_info", callback
-
- _parseRedemptionsXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "redemptions", callback
-
- _parseCouponXml: (xml, callback) ->
- RecurlyWrapper._parseXmlAndGetAttribute xml, "coupon", callback
-
- _parseXmlAndGetAttribute: (xml, attribute, callback) ->
- RecurlyWrapper._parseXml xml, (error, data) ->
- return callback(error) if error?
- if data? and data[attribute]?
- return callback null, data[attribute]
- else
- return callback(new Error("I don't understand the response from Recurly"))
-
- _parseXml: (xml, callback) ->
- convertDataTypes = (data) ->
- if data? and data["$"]?
- if data["$"]["nil"] == "nil"
- data = null
- else if data["$"].href?
- data.url = data["$"].href
- delete data["$"]
- else if data["$"]["type"] == "integer"
- data = parseInt(data["_"], 10)
- else if data["$"]["type"] == "datetime"
- data = new Date(data["_"])
- else if data["$"]["type"] == "array"
- delete data["$"]
- array = []
- for key, value of data
- if value instanceof Array
- array = array.concat(convertDataTypes(value))
- else
- array.push(convertDataTypes(value))
- data = array
-
- if data instanceof Array
- data = (convertDataTypes(entry) for entry in data)
- else if typeof data == "object"
- for key, value of data
- data[key] = convertDataTypes(value)
- return data
-
- parser = new xml2js.Parser(
- explicitRoot : true
- explicitArray : false
- emptyTag: ''
- )
- parser.parseString xml, (error, data) ->
- return callback(error) if error?
- result = convertDataTypes(data)
- callback null, result
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
deleted file mode 100644
index 6edd79b94f..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
+++ /dev/null
@@ -1,269 +0,0 @@
-AuthenticationController = require '../Authentication/AuthenticationController'
-SubscriptionHandler = require './SubscriptionHandler'
-PlansLocator = require("./PlansLocator")
-SubscriptionViewModelBuilder = require('./SubscriptionViewModelBuilder')
-LimitationsManager = require("./LimitationsManager")
-RecurlyWrapper = require './RecurlyWrapper'
-Settings = require 'settings-sharelatex'
-logger = require('logger-sharelatex')
-GeoIpLookup = require("../../infrastructure/GeoIpLookup")
-UserGetter = require "../User/UserGetter"
-FeaturesUpdater = require './FeaturesUpdater'
-planFeatures = require './planFeatures'
-GroupPlansData = require './GroupPlansData'
-V1SubscriptionManager = require "./V1SubscriptionManager"
-
-module.exports = SubscriptionController =
-
- plansPage: (req, res, next) ->
- plans = SubscriptionViewModelBuilder.buildViewModel()
- viewName = "subscriptions/plans"
- if req.query.v?
- viewName = "#{viewName}_#{req.query.v}"
- logger.log viewName:viewName, "showing plans page"
- currentUser = null
-
- GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency)->
- return next(err) if err?
- render = () ->
- res.render viewName,
- title: "plans_and_pricing"
- plans: plans
- gaExperiments: Settings.gaExperiments.plansPage
- recomendedCurrency:recomendedCurrency
- planFeatures: planFeatures
- groupPlans: GroupPlansData
- user_id = AuthenticationController.getLoggedInUserId(req)
- if user_id?
- UserGetter.getUser user_id, {signUpDate: 1}, (err, user) ->
- return next(err) if err?
- currentUser = user
- render()
- else
- render()
-
- #get to show the recurly.js page
- paymentPage: (req, res, next) ->
- user = AuthenticationController.getSessionUser(req)
- plan = PlansLocator.findLocalPlanInSettings(req.query.planCode)
- LimitationsManager.userHasV1OrV2Subscription user, (err, hasSubscription)->
- return next(err) if err?
- if hasSubscription or !plan?
- res.redirect "/user/subscription?hasSubscription=true"
- else
- # LimitationsManager.userHasV2Subscription only checks Mongo. Double check with
- # Recurly as well at this point (we don't do this most places for speed).
- SubscriptionHandler.validateNoSubscriptionInRecurly user._id, (error, valid) ->
- return next(error) if error?
- if !valid
- res.redirect "/user/subscription?hasSubscription=true"
- return
- else
- currency = req.query.currency?.toUpperCase()
- GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency, countryCode)->
- return next(err) if err?
- if recomendedCurrency? and !currency?
- currency = recomendedCurrency
- res.render "subscriptions/new",
- title : "subscribe"
- plan_code: req.query.planCode
- currency: currency
- countryCode:countryCode
- plan:plan
- showStudentPlan: req.query.ssp
- recurlyConfig: JSON.stringify
- currency: currency
- subdomain: Settings.apis.recurly.subdomain
- showCouponField: req.query.scf
- showVatField: req.query.svf
- couponCode: req.query.cc or ""
-
-
-
- userSubscriptionPage: (req, res, next) ->
- user = AuthenticationController.getSessionUser(req)
- SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel user, (error, results) ->
- return next(error) if error?
- {
- personalSubscription,
- memberGroupSubscriptions,
- managedGroupSubscriptions,
- confirmedMemberInstitutions,
- managedInstitutions,
- managedPublishers,
- v1SubscriptionStatus
- } = results
- LimitationsManager.userHasV1OrV2Subscription user, (err, hasSubscription) ->
- return next(error) if error?
- fromPlansPage = req.query.hasSubscription
- logger.log {
- user,
- hasSubscription,
- fromPlansPage,
- personalSubscription,
- memberGroupSubscriptions,
- managedGroupSubscriptions,
- confirmedMemberInstitutions,
- managedInstitutions,
- managedPublishers,
- v1SubscriptionStatus
- }, "showing subscription dashboard"
- plans = SubscriptionViewModelBuilder.buildViewModel()
- data = {
- title: "your_subscription"
- plans,
- user,
- hasSubscription,
- fromPlansPage,
- personalSubscription,
- memberGroupSubscriptions,
- managedGroupSubscriptions,
- confirmedMemberInstitutions,
- managedInstitutions,
- managedPublishers,
- v1SubscriptionStatus
- }
- res.render "subscriptions/dashboard", data
-
- createSubscription: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- recurly_token_id = req.body.recurly_token_id
- subscriptionDetails = req.body.subscriptionDetails
- logger.log recurly_token_id: recurly_token_id, user_id:user._id, subscriptionDetails:subscriptionDetails, "creating subscription"
-
- LimitationsManager.userHasV1OrV2Subscription user, (err, hasSubscription)->
- return next(err) if err?
- if hasSubscription
- logger.warn {user_id: user._id}, 'user already has subscription'
- res.sendStatus 409 # conflict
- SubscriptionHandler.createSubscription user, subscriptionDetails, recurly_token_id, (err)->
- if err?
- logger.err err:err, user_id:user._id, "something went wrong creating subscription"
- return next(err)
- res.sendStatus 201
-
- successful_subscription: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel user, (error, {personalSubscription}) ->
- return next(error) if error?
- if !personalSubscription?
- return res.redirect '/user/subscription/plans'
- res.render "subscriptions/successful_subscription",
- title: "thank_you"
- personalSubscription: personalSubscription
-
- cancelSubscription: (req, res, next) ->
- user = AuthenticationController.getSessionUser(req)
- logger.log user_id:user._id, "canceling subscription"
- SubscriptionHandler.cancelSubscription user, (err)->
- if err?
- logger.err err:err, user_id:user._id, "something went wrong canceling subscription"
- return next(err)
- # Note: this redirect isn't used in the main flow as the redirection is
- # handled by Angular
- res.redirect "/user/subscription/canceled"
-
- canceledSubscription: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- res.render "subscriptions/canceled_subscription",
- title: "subscription_canceled"
-
- cancelV1Subscription: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {user_id}, "canceling v1 subscription"
- V1SubscriptionManager.cancelV1Subscription user_id, (err)->
- if err?
- logger.err err:err, user_id:user_id, "something went wrong canceling v1 subscription"
- return next(err)
- res.redirect "/user/subscription"
-
- updateSubscription: (req, res, next)->
- _origin = req?.query?.origin || null
- user = AuthenticationController.getSessionUser(req)
- planCode = req.body.plan_code
- if !planCode?
- err = new Error('plan_code is not defined')
- logger.err {user_id: user._id, err, planCode, origin: _origin, body: req.body}, "[Subscription] error in updateSubscription form"
- return next(err)
- logger.log planCode: planCode, user_id:user._id, "updating subscription"
- SubscriptionHandler.updateSubscription user, planCode, null, (err)->
- if err?
- logger.err err:err, user_id:user._id, "something went wrong updating subscription"
- return next(err)
- res.redirect "/user/subscription"
-
- reactivateSubscription: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- logger.log user_id:user._id, "reactivating subscription"
- SubscriptionHandler.reactivateSubscription user, (err)->
- if err?
- logger.err err:err, user_id:user._id, "something went wrong reactivating subscription"
- return next(err)
- res.redirect "/user/subscription"
-
- recurlyCallback: (req, res, next)->
- logger.log data: req.body, "received recurly callback"
- # we only care if a subscription has exipired
- if req.body? and req.body["expired_subscription_notification"]?
- recurlySubscription = req.body["expired_subscription_notification"].subscription
- SubscriptionHandler.recurlyCallback recurlySubscription, (err)->
- return next(err) if err?
- res.sendStatus 200
- else
- res.sendStatus 200
-
- renderUpgradeToAnnualPlanPage: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- LimitationsManager.userHasV2Subscription user, (err, hasSubscription, subscription)->
- return next(err) if err?
- planCode = subscription?.planCode.toLowerCase()
- if planCode?.indexOf("annual") != -1
- planName = "annual"
- else if planCode?.indexOf("student") != -1
- planName = "student"
- else if planCode?.indexOf("collaborator") != -1
- planName = "collaborator"
- if !hasSubscription
- return res.redirect("/user/subscription/plans")
- logger.log planName:planName, user_id:user._id, "rendering upgrade to annual page"
- res.render "subscriptions/upgradeToAnnual",
- title: "Upgrade to annual"
- planName: planName
-
- processUpgradeToAnnualPlan: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- {planName} = req.body
- coupon_code = Settings.coupon_codes.upgradeToAnnualPromo[planName]
- annualPlanName = "#{planName}-annual"
- logger.log user_id:user._id, planName:annualPlanName, "user is upgrading to annual billing with discount"
- SubscriptionHandler.updateSubscription user, annualPlanName, coupon_code, (err)->
- if err?
- logger.err err:err, user_id:user._id, "error updating subscription"
- return next(err)
- res.sendStatus 200
-
- extendTrial: (req, res, next)->
- user = AuthenticationController.getSessionUser(req)
- LimitationsManager.userHasV2Subscription user, (err, hasSubscription, subscription)->
- return next(err) if err?
- SubscriptionHandler.extendTrial subscription, 14, (err)->
- if err?
- res.send 500
- else
- res.send 200
-
- recurlyNotificationParser: (req, res, next) ->
- xml = ""
- req.on "data", (chunk) ->
- xml += chunk
- req.on "end", () ->
- RecurlyWrapper._parseXml xml, (error, body) ->
- return next(error) if error?
- req.body = body
- next()
-
- refreshUserFeatures: (req, res, next) ->
- {user_id} = req.params
- FeaturesUpdater.refreshFeatures user_id, (error) ->
- return next(error) if error?
- res.sendStatus 200
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionFormatters.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionFormatters.coffee
deleted file mode 100644
index f0929a08cf..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionFormatters.coffee
+++ /dev/null
@@ -1,33 +0,0 @@
-dateformat = require 'dateformat'
-settings = require "settings-sharelatex"
-
-
-currenySymbols =
- EUR: "€"
- USD: "$"
- GBP: "£"
- SEK: "kr"
- CAD: "$"
- NOK: "kr"
- DKK: "kr"
- AUD: "$"
- NZD: "$"
- CHF: "Fr"
- SGD: "$"
-
-
-module.exports =
-
- formatPrice: (priceInCents, currency = "USD") ->
- string = priceInCents + ""
- string = "0" + string if string.length == 2
- string = "00" + string if string.length == 1
- string = "000" if string.length == 0
- cents = string.slice(-2)
- dollars = string.slice(0, -2)
- symbol = currenySymbols[currency]
- return "#{symbol}#{dollars}.#{cents}"
-
- formatDate: (date) ->
- return null if !date?
- dateformat date, "dS mmmm yyyy"
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee
deleted file mode 100644
index 6fb58a7cd9..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee
+++ /dev/null
@@ -1,48 +0,0 @@
-SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
-logger = require("logger-sharelatex")
-SubscriptionLocator = require("./SubscriptionLocator")
-AuthenticationController = require('../Authentication/AuthenticationController')
-_ = require("underscore")
-async = require("async")
-
-module.exports =
-
- removeUserFromGroup: (req, res, next)->
- subscription = req.entity
- userToRemove_id = req.params.user_id
- logger.log subscriptionId: subscription._id, userToRemove_id:userToRemove_id, "removing user from group subscription"
- SubscriptionGroupHandler.removeUserFromGroup subscription._id, userToRemove_id, (err)->
- if err?
- logger.err err:err, subscriptionId: subscription._id, userToRemove_id:userToRemove_id, "error removing user from group"
- return next(err)
- res.send()
-
- removeSelfFromGroup: (req, res, next)->
- adminUserId = req.query.admin_user_id
- userToRemove_id = AuthenticationController.getLoggedInUserId(req)
- getManagedSubscription adminUserId, (error, subscription) ->
- return next(error) if error?
- logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription after self request"
- SubscriptionGroupHandler.removeUserFromGroup subscription._id, userToRemove_id, (err)->
- if err?
- logger.err err:err, userToRemove_id:userToRemove_id, adminUserId:adminUserId, "error removing self from group"
- return res.sendStatus 500
- res.send()
-
- # legacy route
- redirectToSubscriptionGroupAdminPage: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- getManagedSubscription user_id, (error, subscription) ->
- return next(error) if error?
- if !subscription?.groupPlan
- return res.redirect("/user/subscription")
- res.redirect("/manage/groups/#{subscription._id}/members")
-
-getManagedSubscription = (managerId, callback) ->
- SubscriptionLocator.findManagedSubscription managerId, (err, subscription)->
- if subscription?
- logger.log managerId: managerId, "got managed subscription"
- else
- err ||= new Error("No subscription found managed by user #{managerId}")
-
- return callback(err, subscription)
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee
deleted file mode 100644
index e378cd9c56..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee
+++ /dev/null
@@ -1,59 +0,0 @@
-async = require("async")
-_ = require("underscore")
-SubscriptionUpdater = require("./SubscriptionUpdater")
-SubscriptionLocator = require("./SubscriptionLocator")
-UserGetter = require("../User/UserGetter")
-Subscription = require("../../models/Subscription").Subscription
-LimitationsManager = require("./LimitationsManager")
-logger = require("logger-sharelatex")
-OneTimeTokenHandler = require("../Security/OneTimeTokenHandler")
-EmailHandler = require("../Email/EmailHandler")
-settings = require("settings-sharelatex")
-NotificationsBuilder = require("../Notifications/NotificationsBuilder")
-UserMembershipViewModel = require("../UserMembership/UserMembershipViewModel")
-
-module.exports = SubscriptionGroupHandler =
-
- removeUserFromGroup: (subscriptionId, userToRemove_id, callback)->
- SubscriptionUpdater.removeUserFromGroup subscriptionId, userToRemove_id, callback
-
- replaceUserReferencesInGroups: (oldId, newId, callback) ->
- logger.log old_id: oldId, new_id: newId, "replacing user reference in groups"
- Subscription.update {admin_id: oldId}, {admin_id: newId}, (error) ->
- return callback(error) if error?
-
- replaceInArray Subscription, "manager_ids", oldId, newId, (error) ->
- return callback(error) if error?
-
- replaceInArray Subscription, "member_ids", oldId, newId, callback
-
- isUserPartOfGroup: (user_id, subscription_id, callback=(err, partOfGroup)->)->
- SubscriptionLocator.getSubscriptionByMemberIdAndId user_id, subscription_id, (err, subscription)->
- if subscription?
- partOfGroup = true
- else
- partOfGroup = false
- logger.log user_id:user_id, subscription_id:subscription_id, partOfGroup:partOfGroup, "checking if user is part of a group"
- callback(err, partOfGroup)
-
- getTotalConfirmedUsersInGroup: (subscription_id, callback=(err, totalUsers)->)->
- SubscriptionLocator.getSubscription subscription_id, (err, subscription)->
- callback(err, subscription?.member_ids?.length)
-
-replaceInArray = (model, property, oldValue, newValue, callback) ->
- logger.log "Replacing #{oldValue} with #{newValue} in #{property} of #{model}"
-
- # Mongo won't let us pull and addToSet in the same query, so do it in
- # two. Note we need to add first, since the query is based on the old user.
- query = {}
- query[property] = oldValue
-
- setNewValue = {}
- setNewValue[property] = newValue
-
- setOldValue = {}
- setOldValue[property] = oldValue
-
- model.update query, { $addToSet: setNewValue }, { multi: true }, (error) ->
- return callback(error) if error?
- model.update query, { $pull: setOldValue }, { multi: true }, callback
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee
deleted file mode 100644
index a57916fac7..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee
+++ /dev/null
@@ -1,96 +0,0 @@
-async = require("async")
-RecurlyWrapper = require("./RecurlyWrapper")
-Settings = require "settings-sharelatex"
-User = require('../../models/User').User
-logger = require('logger-sharelatex')
-SubscriptionUpdater = require("./SubscriptionUpdater")
-LimitationsManager = require('./LimitationsManager')
-EmailHandler = require("../Email/EmailHandler")
-Events = require "../../infrastructure/Events"
-Analytics = require("../Analytics/AnalyticsManager")
-
-
-module.exports =
- validateNoSubscriptionInRecurly: (user_id, callback = (error, valid) ->) ->
- RecurlyWrapper.listAccountActiveSubscriptions user_id, (error, subscriptions = []) ->
- return callback(error) if error?
- if subscriptions.length > 0
- SubscriptionUpdater.syncSubscription subscriptions[0], user_id, (error) ->
- return callback(error) if error?
- return callback(null, false)
- else
- return callback(null, true)
-
- createSubscription: (user, subscriptionDetails, recurly_token_id, callback)->
- self = @
- clientTokenId = ""
- @validateNoSubscriptionInRecurly user._id, (error, valid) ->
- return callback(error) if error?
- if !valid
- return callback(new Error("user already has subscription in recurly"))
- RecurlyWrapper.createSubscription user, subscriptionDetails, recurly_token_id, (error, recurlySubscription)->
- return callback(error) if error?
- SubscriptionUpdater.syncSubscription recurlySubscription, user._id, (error) ->
- return callback(error) if error?
- callback()
-
- updateSubscription: (user, plan_code, coupon_code, callback)->
- logger.log user:user, plan_code:plan_code, coupon_code:coupon_code, "updating subscription"
- LimitationsManager.userHasV2Subscription user, (err, hasSubscription, subscription)->
- if !hasSubscription
- return callback()
- else
- async.series [
- (cb)->
- return cb() if !coupon_code?
- logger.log user_id:user._id, plan_code:plan_code, coupon_code:coupon_code, "updating subscription with coupon code applied first"
- RecurlyWrapper.getSubscription subscription.recurlySubscription_id, includeAccount: true, (err, usersSubscription)->
- return callback(err) if err?
- account_code = usersSubscription.account.account_code
- RecurlyWrapper.redeemCoupon account_code, coupon_code, cb
- (cb)->
- RecurlyWrapper.updateSubscription subscription.recurlySubscription_id, {plan_code: plan_code, timeframe: "now"}, (error, recurlySubscription) ->
- return callback(error) if error?
- SubscriptionUpdater.syncSubscription recurlySubscription, user._id, cb
- ], callback
-
-
- cancelSubscription: (user, callback) ->
- LimitationsManager.userHasV2Subscription user, (err, hasSubscription, subscription)->
- if hasSubscription
- RecurlyWrapper.cancelSubscription subscription.recurlySubscription_id, (error) ->
- return callback(error) if error?
- emailOpts =
- to: user.email
- first_name: user.first_name
- ONE_HOUR_IN_MS = 1000 * 60 * 60
- setTimeout (-> EmailHandler.sendEmail "canceledSubscription", emailOpts
- ), ONE_HOUR_IN_MS
- Events.emit "cancelSubscription", user._id
- Analytics.recordEvent user._id, "subscription-canceled"
- callback()
- else
- callback()
-
- reactivateSubscription: (user, callback) ->
- LimitationsManager.userHasV2Subscription user, (err, hasSubscription, subscription)->
- if hasSubscription
- RecurlyWrapper.reactivateSubscription subscription.recurlySubscription_id, (error) ->
- return callback(error) if error?
- EmailHandler.sendEmail "reactivatedSubscription", to: user.email
- Analytics.recordEvent user._id, "subscription-reactivated"
- callback()
- else
- callback()
-
- recurlyCallback: (recurlySubscription, callback) ->
- RecurlyWrapper.getSubscription recurlySubscription.uuid, includeAccount: true, (error, recurlySubscription) ->
- return callback(error) if error?
- User.findById recurlySubscription.account.account_code, (error, user) ->
- return callback(error) if error?
- if !user?
- return callback("no user found")
- SubscriptionUpdater.syncSubscription recurlySubscription, user?._id, callback
-
- extendTrial: (subscription, daysToExend, callback)->
- RecurlyWrapper.extendTrial subscription.recurlySubscription_id, daysToExend, callback
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee
deleted file mode 100644
index 62064b602c..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee
+++ /dev/null
@@ -1,49 +0,0 @@
-Subscription = require('../../models/Subscription').Subscription
-logger = require("logger-sharelatex")
-ObjectId = require('mongoose').Types.ObjectId
-
-module.exports = SubscriptionLocator =
-
- getUsersSubscription: (user_or_id, callback)->
- user_id = @_getUserId(user_or_id)
- logger.log user_id:user_id, "getting users subscription"
- Subscription.findOne admin_id:user_id, (err, subscription)->
- logger.log user_id:user_id, "got users subscription"
- callback(err, subscription)
-
- findManagedSubscription: (managerId, callback)->
- logger.log managerId: managerId, "finding managed subscription"
- Subscription.findOne manager_ids: managerId, callback
-
- getManagedGroupSubscriptions: (user_or_id, callback = (error, managedSubscriptions) ->) ->
- user_id = @_getUserId(user_or_id)
- Subscription.find({
- manager_ids: user_or_id,
- groupPlan: true
- }).populate("admin_id").exec callback
-
- getMemberSubscriptions: (user_or_id, callback) ->
- user_id = @_getUserId(user_or_id)
- logger.log user_id: user_id, "getting users group subscriptions"
- Subscription.find(member_ids: user_id).populate("admin_id").exec callback
-
- getSubscription: (subscription_id, callback)->
- Subscription.findOne _id:subscription_id, callback
-
- getSubscriptionByMemberIdAndId: (user_id, subscription_id, callback)->
- Subscription.findOne {member_ids: user_id, _id:subscription_id}, {_id:1}, callback
-
- getGroupSubscriptionsMemberOf: (user_id, callback)->
- Subscription.find {member_ids: user_id}, {_id:1, planCode:1}, callback
-
- getGroupsWithEmailInvite: (email, callback) ->
- Subscription.find { invited_emails: email }, callback
-
- getGroupWithV1Id: (v1TeamId, callback) ->
- Subscription.findOne { "overleaf.id": v1TeamId }, callback
-
- _getUserId: (user_or_id) ->
- if user_or_id? and user_or_id._id?
- return user_or_id._id
- else if user_or_id?
- return user_or_id
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee
deleted file mode 100644
index 57c1dba8c8..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee
+++ /dev/null
@@ -1,55 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-SubscriptionController = require('./SubscriptionController')
-SubscriptionGroupController = require './SubscriptionGroupController'
-TeamInvitesController = require './TeamInvitesController'
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-Settings = require "settings-sharelatex"
-
-module.exports =
- apply: (webRouter, privateApiRouter, publicApiRouter) ->
- return unless Settings.enableSubscriptions
-
- webRouter.get '/user/subscription/plans', SubscriptionController.plansPage
-
- webRouter.get '/user/subscription', AuthenticationController.requireLogin(), SubscriptionController.userSubscriptionPage
-
- webRouter.get '/user/subscription/new', AuthenticationController.requireLogin(), SubscriptionController.paymentPage
-
- webRouter.get '/user/subscription/thank-you', AuthenticationController.requireLogin(), SubscriptionController.successful_subscription
-
- webRouter.get '/user/subscription/canceled', AuthenticationController.requireLogin(), SubscriptionController.canceledSubscription
-
-
- webRouter.get '/subscription/group', AuthenticationController.requireLogin(), SubscriptionGroupController.redirectToSubscriptionGroupAdminPage
- webRouter.delete '/subscription/group/user', AuthenticationController.requireLogin(), SubscriptionGroupController.removeSelfFromGroup
-
- # Team invites
- webRouter.get '/subscription/invites/:token/', AuthenticationController.requireLogin(),
- TeamInvitesController.viewInvite
- webRouter.put '/subscription/invites/:token/',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: 'team-invite',
- maxRequests: 10
- timeInterval: 60
- }),
- TeamInvitesController.acceptInvite
-
- #recurly callback
- publicApiRouter.post '/user/subscription/callback', SubscriptionController.recurlyNotificationParser, SubscriptionController.recurlyCallback
-
- #user changes their account state
- webRouter.post '/user/subscription/create', AuthenticationController.requireLogin(), SubscriptionController.createSubscription
- webRouter.post '/user/subscription/update', AuthenticationController.requireLogin(), SubscriptionController.updateSubscription
- webRouter.post '/user/subscription/cancel', AuthenticationController.requireLogin(), SubscriptionController.cancelSubscription
- webRouter.post '/user/subscription/reactivate', AuthenticationController.requireLogin(), SubscriptionController.reactivateSubscription
-
- webRouter.post '/user/subscription/v1/cancel', AuthenticationController.requireLogin(), SubscriptionController.cancelV1Subscription
-
- webRouter.put '/user/subscription/extend', AuthenticationController.requireLogin(), SubscriptionController.extendTrial
-
- webRouter.get "/user/subscription/upgrade-annual", AuthenticationController.requireLogin(), SubscriptionController.renderUpgradeToAnnualPlanPage
- webRouter.post "/user/subscription/upgrade-annual", AuthenticationController.requireLogin(), SubscriptionController.processUpgradeToAnnualPlan
-
- # Currently used in acceptance tests only, as a way to trigger the syncing logic
- publicApiRouter.post "/user/:user_id/features/sync", AuthenticationController.httpAuth, SubscriptionController.refreshUserFeatures
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee
deleted file mode 100644
index 1af9e17cc6..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee
+++ /dev/null
@@ -1,108 +0,0 @@
-async = require("async")
-_ = require("underscore")
-Subscription = require('../../models/Subscription').Subscription
-SubscriptionLocator = require("./SubscriptionLocator")
-UserGetter = require("../User/UserGetter")
-PlansLocator = require("./PlansLocator")
-Settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-ObjectId = require('mongoose').Types.ObjectId
-FeaturesUpdater = require('./FeaturesUpdater')
-
-oneMonthInSeconds = 60 * 60 * 24 * 30
-
-module.exports = SubscriptionUpdater =
- syncSubscription: (recurlySubscription, adminUser_id, callback) ->
- logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "syncSubscription, creating new if subscription does not exist"
- SubscriptionLocator.getUsersSubscription adminUser_id, (err, subscription)->
- return callback(err) if err?
- if subscription?
- logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "subscription does exist"
- SubscriptionUpdater._updateSubscriptionFromRecurly recurlySubscription, subscription, callback
- else
- logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "subscription does not exist, creating a new one"
- SubscriptionUpdater._createNewSubscription adminUser_id, (err, subscription)->
- return callback(err) if err?
- SubscriptionUpdater._updateSubscriptionFromRecurly recurlySubscription, subscription, callback
-
- addUserToGroup: (subscriptionId, userId, callback)->
- @addUsersToGroup(subscriptionId, [userId], callback)
-
- addUsersToGroup: (subscriptionId, memberIds, callback)->
- @addUsersToGroupWithoutFeaturesRefresh subscriptionId, memberIds, (err) ->
- return callback(err) if err?
-
- # Only apply features updates to users, not user stubs
- UserGetter.getUsers memberIds, { _id: 1 }, (err, users) ->
- return callback(err) if err?
-
- userIds = users.map (u) -> u._id.toString()
- async.map userIds, FeaturesUpdater.refreshFeatures, callback
-
- addUsersToGroupWithoutFeaturesRefresh: (subscriptionId, memberIds, callback)->
- logger.log subscriptionId: subscriptionId, memberIds: memberIds, "adding members into mongo subscription"
- searchOps =
- _id: subscriptionId
- insertOperation =
- { $addToSet: { member_ids: { $each: memberIds } } }
-
- Subscription.findAndModify searchOps, insertOperation, callback
-
- removeUserFromGroups: (filter, user_id, callback)->
- removeOperation =
- "$pull": {member_ids:user_id}
- Subscription.updateMany filter, removeOperation, (err)->
- if err?
- logger.err err:err, searchOps:searchOps, removeOperation:removeOperation, "error removing user from groups"
- return callback(err)
- UserGetter.getUserOrUserStubById user_id, {}, (error, user, isStub) ->
- return callback(error) if error
- return callback() if isStub
- FeaturesUpdater.refreshFeatures user_id, callback
-
- removeUserFromGroup: (subscriptionId, user_id, callback)->
- SubscriptionUpdater.removeUserFromGroups { _id: subscriptionId }, user_id, callback
-
- removeUserFromAllGroups: (user_id, callback) ->
- SubscriptionLocator.getMemberSubscriptions user_id, (error, subscriptions) ->
- return callback(error) if error
- return callback() unless subscriptions
- subscriptionIds = subscriptions.map (sub) -> sub._id
- SubscriptionUpdater.removeUserFromGroups { _id: subscriptionIds }, user_id, callback
-
- deleteWithV1Id: (v1TeamId, callback)->
- Subscription.deleteOne { "overleaf.id": v1TeamId }, callback
-
- deleteSubscription: (subscription_id, callback = (error) ->) ->
- SubscriptionLocator.getSubscription subscription_id, (err, subscription) ->
- return callback(err) if err?
- affected_user_ids = [subscription.admin_id].concat(subscription.member_ids or [])
- logger.log {subscription_id, affected_user_ids}, "deleting subscription and downgrading users"
- Subscription.remove {_id: ObjectId(subscription_id)}, (err) ->
- return callback(err) if err?
- async.mapSeries affected_user_ids, FeaturesUpdater.refreshFeatures, callback
-
- _createNewSubscription: (adminUser_id, callback)->
- logger.log adminUser_id:adminUser_id, "creating new subscription"
- subscription = new Subscription(admin_id:adminUser_id, manager_ids: [adminUser_id])
- subscription.save (err)->
- callback err, subscription
-
- _updateSubscriptionFromRecurly: (recurlySubscription, subscription, callback)->
- logger.log recurlySubscription:recurlySubscription, subscription:subscription, "updaing subscription"
- if recurlySubscription.state == "expired"
- return SubscriptionUpdater.deleteSubscription subscription._id, callback
- subscription.recurlySubscription_id = recurlySubscription.uuid
- subscription.planCode = recurlySubscription.plan.plan_code
- plan = PlansLocator.findLocalPlanInSettings(subscription.planCode)
- if !plan?
- return callback(new Error("plan code not found: #{subscription.planCode}"))
- if plan.groupPlan
- subscription.groupPlan = true
- subscription.membersLimit = plan.membersLimit
- subscription.save ->
- allIds = _.union subscription.member_ids, [subscription.admin_id]
- jobs = allIds.map (user_id)->
- return (cb)->
- FeaturesUpdater.refreshFeatures user_id, cb
- async.series jobs, callback
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee
deleted file mode 100644
index 2c55a1ee8e..0000000000
--- a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee
+++ /dev/null
@@ -1,149 +0,0 @@
-Settings = require('settings-sharelatex')
-RecurlyWrapper = require("./RecurlyWrapper")
-PlansLocator = require("./PlansLocator")
-SubscriptionFormatters = require("./SubscriptionFormatters")
-LimitationsManager = require("./LimitationsManager")
-SubscriptionLocator = require("./SubscriptionLocator")
-V1SubscriptionManager = require("./V1SubscriptionManager")
-InstitutionsGetter = require("../Institutions/InstitutionsGetter")
-PublishersGetter = require("../Publishers/PublishersGetter")
-sanitizeHtml = require 'sanitize-html'
-logger = require('logger-sharelatex')
-_ = require("underscore")
-async = require('async')
-
-
-buildBillingDetails = (recurlySubscription) ->
- hostedLoginToken = recurlySubscription?.account?.hosted_login_token
- recurlySubdomain = Settings?.apis?.recurly?.subdomain
- if hostedLoginToken? && recurlySubdomain?
- return [
- "https://",
- recurlySubdomain,
- ".recurly.com/account/billing_info/edit?ht=",
- hostedLoginToken
- ].join("")
-
-module.exports =
- buildUsersSubscriptionViewModel: (user, callback = (error, data) ->) ->
- async.auto {
- personalSubscription: (cb) ->
- SubscriptionLocator.getUsersSubscription user, cb
- recurlySubscription: ['personalSubscription', (cb, {personalSubscription}) ->
- if !personalSubscription?.recurlySubscription_id? or personalSubscription?.recurlySubscription_id == ''
- return cb(null, null)
- RecurlyWrapper.getSubscription personalSubscription.recurlySubscription_id, includeAccount: true, cb
- ]
- recurlyCoupons: ['recurlySubscription', (cb, {recurlySubscription}) ->
- return cb(null, null) if !recurlySubscription
- accountId = recurlySubscription.account.account_code
- RecurlyWrapper.getAccountActiveCoupons accountId, cb
- ]
- plan: ['personalSubscription', (cb, {personalSubscription}) ->
- return cb() if !personalSubscription?
- plan = PlansLocator.findLocalPlanInSettings(personalSubscription.planCode)
- return cb(new Error("No plan found for planCode '#{personalSubscription.planCode}'")) if !plan?
- cb(null, plan)
- ]
- memberGroupSubscriptions: (cb) ->
- SubscriptionLocator.getMemberSubscriptions user, cb
- managedGroupSubscriptions: (cb) ->
- SubscriptionLocator.getManagedGroupSubscriptions user, cb
- confirmedMemberInstitutions: (cb) ->
- InstitutionsGetter.getConfirmedInstitutions user._id, cb
- managedInstitutions: (cb) ->
- InstitutionsGetter.getManagedInstitutions user._id, cb
- managedPublishers: (cb) ->
- PublishersGetter.getManagedPublishers user._id, cb
- v1SubscriptionStatus: (cb) ->
- V1SubscriptionManager.getSubscriptionStatusFromV1 user._id, (error, status, v1Id) ->
- return cb(error) if error?
- cb(null, status)
- }, (err, results) ->
- return callback(err) if err?
- {
- personalSubscription,
- memberGroupSubscriptions,
- managedGroupSubscriptions,
- confirmedMemberInstitutions,
- managedInstitutions,
- managedPublishers,
- v1SubscriptionStatus,
- recurlySubscription,
- recurlyCoupons,
- plan
- } = results
- memberGroupSubscriptions ?= []
- managedGroupSubscriptions ?= []
- confirmedMemberInstitutions ?= []
- managedInstitutions ?= []
- v1SubscriptionStatus ?= {}
- recurlyCoupons ?= []
-
-
- if personalSubscription?.toObject?
- # Downgrade from Mongoose object, so we can add a recurly and plan attribute
- personalSubscription = personalSubscription.toObject()
-
- if plan?
- personalSubscription.plan = plan
-
- if personalSubscription? and recurlySubscription?
- tax = recurlySubscription?.tax_in_cents || 0
- personalSubscription.recurly = {
- tax: tax
- taxRate: parseFloat(recurlySubscription?.tax_rate?._)
- billingDetailsLink: buildBillingDetails(recurlySubscription)
- price: SubscriptionFormatters.formatPrice (recurlySubscription?.unit_amount_in_cents + tax), recurlySubscription?.currency
- nextPaymentDueAt: SubscriptionFormatters.formatDate(recurlySubscription?.current_period_ends_at)
- currency: recurlySubscription.currency
- state: recurlySubscription.state
- trialEndsAtFormatted: SubscriptionFormatters.formatDate(recurlySubscription?.trial_ends_at)
- trial_ends_at: recurlySubscription.trial_ends_at
- activeCoupons: recurlyCoupons
- }
-
- for memberGroupSubscription in memberGroupSubscriptions
- if memberGroupSubscription.teamNotice
- memberGroupSubscription.teamNotice = sanitizeHtml(memberGroupSubscription.teamNotice)
-
- callback null, {
- personalSubscription,
- managedGroupSubscriptions,
- memberGroupSubscriptions,
- confirmedMemberInstitutions,
- managedInstitutions,
- managedPublishers,
- v1SubscriptionStatus
- }
-
- buildViewModel : ->
- plans = Settings.plans
-
- allPlans = {}
- plans.forEach (plan)->
- allPlans[plan.planCode] = plan
-
- result =
- allPlans: allPlans
-
-
- result.personalAccount = _.find plans, (plan)->
- plan.planCode == "personal"
-
- result.studentAccounts = _.filter plans, (plan)->
- plan.planCode.indexOf("student") != -1
-
- result.groupMonthlyPlans = _.filter plans, (plan)->
- plan.groupPlan and !plan.annual
-
- result.groupAnnualPlans = _.filter plans, (plan)->
- plan.groupPlan and plan.annual
-
- result.individualMonthlyPlans = _.filter plans, (plan)->
- !plan.groupPlan and !plan.annual and plan.planCode != "personal" and plan.planCode.indexOf("student") == -1
-
- result.individualAnnualPlans = _.filter plans, (plan)->
- !plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1
-
- return result
diff --git a/services/web/app/coffee/Features/Subscription/TeamInvitesController.coffee b/services/web/app/coffee/Features/Subscription/TeamInvitesController.coffee
deleted file mode 100644
index 72c28d3a79..0000000000
--- a/services/web/app/coffee/Features/Subscription/TeamInvitesController.coffee
+++ /dev/null
@@ -1,70 +0,0 @@
-settings = require "settings-sharelatex"
-logger = require("logger-sharelatex")
-TeamInvitesHandler = require('./TeamInvitesHandler')
-AuthenticationController = require("../Authentication/AuthenticationController")
-SubscriptionLocator = require("./SubscriptionLocator")
-ErrorController = require("../Errors/ErrorController")
-EmailHelper = require("../Helpers/EmailHelper")
-
-module.exports =
- createInvite: (req, res, next) ->
- teamManagerId = AuthenticationController.getLoggedInUserId(req)
- subscription = req.entity
- email = EmailHelper.parseEmail(req.body.email)
- if !email?
- return res.status(422).json error:
- code: 'invalid_email'
- message: req.i18n.translate('invalid_email')
-
-
- TeamInvitesHandler.createInvite teamManagerId, subscription, email, (err, invite) ->
- return next(err) if err?
- inviteView = { user:
- { email: invite.email, sentAt: invite.sentAt, invite: true }
- }
- res.json inviteView
-
- viewInvite: (req, res, next) ->
- token = req.params.token
- userId = AuthenticationController.getLoggedInUserId(req)
-
- TeamInvitesHandler.getInvite token, (err, invite, teamSubscription) ->
- return next(err) if err?
-
- if !invite
- return ErrorController.notFound(req, res, next)
-
- SubscriptionLocator.getUsersSubscription userId, (err, personalSubscription) ->
- return next(err) if err?
-
- hasIndividualRecurlySubscription =
- personalSubscription? &&
- !personalSubscription.planCode.match(/(free|trial)/)? &&
- personalSubscription.groupPlan == false &&
- personalSubscription.recurlySubscription_id? &&
- personalSubscription.recurlySubscription_id != ""
-
- res.render "subscriptions/team/invite",
- inviterName: invite.inviterName
- inviteToken: invite.token
- hasIndividualRecurlySubscription: hasIndividualRecurlySubscription
- appName: settings.appName
-
- acceptInvite: (req, res, next) ->
- token = req.params.token
- userId = AuthenticationController.getLoggedInUserId(req)
-
- TeamInvitesHandler.acceptInvite token, userId, (err, results) ->
- return next(err) if err?
- res.sendStatus 204
-
- revokeInvite: (req, res) ->
- subscription = req.entity
- email = EmailHelper.parseEmail(req.params.email)
- teamManagerId = AuthenticationController.getLoggedInUserId(req)
- if !email?
- return res.sendStatus(400)
-
- TeamInvitesHandler.revokeInvite teamManagerId, subscription, email, (err, results) ->
- return next(err) if err?
- res.sendStatus 204
diff --git a/services/web/app/coffee/Features/Subscription/TeamInvitesHandler.coffee b/services/web/app/coffee/Features/Subscription/TeamInvitesHandler.coffee
deleted file mode 100644
index 43223ebd5c..0000000000
--- a/services/web/app/coffee/Features/Subscription/TeamInvitesHandler.coffee
+++ /dev/null
@@ -1,158 +0,0 @@
-logger = require("logger-sharelatex")
-crypto = require("crypto")
-async = require("async")
-
-settings = require("settings-sharelatex")
-ObjectId = require("mongojs").ObjectId
-
-TeamInvite = require("../../models/TeamInvite").TeamInvite
-Subscription = require("../../models/Subscription").Subscription
-
-UserGetter = require("../User/UserGetter")
-SubscriptionLocator = require("./SubscriptionLocator")
-SubscriptionUpdater = require("./SubscriptionUpdater")
-LimitationsManager = require("./LimitationsManager")
-
-EmailHandler = require("../Email/EmailHandler")
-EmailHelper = require("../Helpers/EmailHelper")
-
-Errors = require "../Errors/Errors"
-
-module.exports = TeamInvitesHandler =
- getInvite: (token, callback) ->
- Subscription.findOne 'teamInvites.token': token, (err, subscription) ->
- return callback(err) if err?
- return callback(new Errors.NotFoundError('team not found')) unless subscription?
-
- invite = subscription.teamInvites.find (i) -> i.token == token
- return callback(null, invite, subscription)
-
- createInvite: (teamManagerId, subscription, email, callback) ->
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- logger.log {teamManagerId, email}, "Creating manager team invite"
- UserGetter.getUser teamManagerId, (error, teamManager) ->
- return callback(error) if error?
-
- if teamManager.first_name and teamManager.last_name
- inviterName = "#{teamManager.first_name} #{teamManager.last_name} (#{teamManager.email})"
- else
- inviterName = teamManager.email
-
- removeLegacyInvite subscription.id, email, (error) ->
- return callback(error) if error?
- createInvite(subscription, email, inviterName, callback)
-
- importInvite: (subscription, inviterName, email, token, sentAt, callback) ->
- checkIfInviteIsPossible subscription, email, (error, possible, reason) ->
- return callback(error) if error?
- return callback(reason) unless possible
-
- subscription.teamInvites.push({
- email: email
- inviterName: inviterName
- token: token
- sentAt: sentAt
- })
-
- subscription.save callback
-
- acceptInvite: (token, userId, callback) ->
- logger.log {userId}, "Accepting invite"
- TeamInvitesHandler.getInvite token, (err, invite, subscription) ->
- return callback(err) if err?
- return callback(new Errors.NotFoundError('invite not found')) unless invite?
-
- SubscriptionUpdater.addUserToGroup subscription._id, userId, (err) ->
- return callback(err) if err?
-
- removeInviteFromTeam(subscription.id, invite.email, callback)
-
- revokeInvite: (teamManagerId, subscription, email, callback) ->
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- logger.log {teamManagerId, email}, "Revoking invite"
- removeInviteFromTeam(subscription.id, email, callback)
-
- # Legacy method to allow a user to receive a confirmation email if their
- # email is in Subscription.invited_emails when they join. We'll remove this
- # after a short while.
- createTeamInvitesForLegacyInvitedEmail: (email, callback) ->
- SubscriptionLocator.getGroupsWithEmailInvite email, (err, teams) ->
- return callback(err) if err?
-
- async.map teams,
- (team, cb) -> TeamInvitesHandler.createInvite(team.admin_id, team, email, cb)
- , callback
-
-createInvite = (subscription, email, inviterName, callback) ->
- logger.log {subscriptionId: subscription.id, email, inviterName}, "Creating invite"
- checkIfInviteIsPossible subscription, email, (error, possible, reason) ->
- return callback(error) if error?
- return callback(reason) unless possible
-
- invite = subscription.teamInvites.find (invite) -> invite.email == email
-
- if !invite?
- invite = {
- email: email
- inviterName: inviterName
- token: crypto.randomBytes(32).toString("hex")
- sentAt: new Date()
- }
- subscription.teamInvites.push(invite)
- else
- invite.sentAt = new Date()
-
- subscription.save (error) ->
- return callback(error) if error?
-
- opts =
- to: email
- inviterName: inviterName
- acceptInviteUrl: "#{settings.siteUrl}/subscription/invites/#{invite.token}/"
- appName: settings.appName
- EmailHandler.sendEmail "verifyEmailToJoinTeam", opts, (error) ->
- return callback(error, invite)
-
-removeInviteFromTeam = (subscriptionId, email, callback) ->
- searchConditions = { _id: new ObjectId(subscriptionId.toString()) }
- removeInvite = { $pull: { teamInvites: { email: email } } }
- logger.log {subscriptionId, email, searchConditions, removeInvite}, 'removeInviteFromTeam'
-
- async.series [
- (cb) -> Subscription.update(searchConditions, removeInvite, cb),
- (cb) -> removeLegacyInvite(subscriptionId, email, cb),
- ], callback
-
-removeLegacyInvite = (subscriptionId, email, callback) ->
- Subscription.update({
- _id: new ObjectId(subscriptionId.toString())
- }, {
- $pull: {
- invited_emails: email
- }
- }, callback)
-
-checkIfInviteIsPossible = (subscription, email, callback = (error, possible, reason) -> ) ->
- unless subscription.groupPlan
- logger.log {subscriptionId: subscription.id},
- "can not add members to a subscription that is not in a group plan"
- return callback(null, false, wrongPlan: true)
-
- if LimitationsManager.teamHasReachedMemberLimit(subscription)
- logger.log {subscriptionId: subscription.id}, "team has reached member limit"
- return callback(null, false, limitReached: true)
-
- UserGetter.getUserByAnyEmail email, (error, existingUser) ->
- return callback(error) if error?
- return callback(null, true) unless existingUser?
-
- existingMember = subscription.member_ids.find (memberId) ->
- memberId.toString() == existingUser._id.toString()
-
- if existingMember
- logger.log {subscriptionId: subscription.id, email}, "user already in team"
- return callback(null, false, alreadyInTeam: true)
- else
- return callback(null, true)
diff --git a/services/web/app/coffee/Features/Subscription/UserFeaturesUpdater.coffee b/services/web/app/coffee/Features/Subscription/UserFeaturesUpdater.coffee
deleted file mode 100644
index 3d20f40271..0000000000
--- a/services/web/app/coffee/Features/Subscription/UserFeaturesUpdater.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-logger = require("logger-sharelatex")
-User = require('../../models/User').User
-
-module.exports =
- updateFeatures: (user_id, features, callback = (err, features, featuresChanged)->)->
- conditions = _id:user_id
- update = {}
- logger.log user_id:user_id, features:features, "updating users features"
- update["features.#{key}"] = value for key, value of features
- User.update conditions, update, (err, result)->
- callback err, features, result?.nModified == 1
-
diff --git a/services/web/app/coffee/Features/Subscription/V1SubscriptionManager.coffee b/services/web/app/coffee/Features/Subscription/V1SubscriptionManager.coffee
deleted file mode 100644
index 10c1a7983b..0000000000
--- a/services/web/app/coffee/Features/Subscription/V1SubscriptionManager.coffee
+++ /dev/null
@@ -1,103 +0,0 @@
-UserGetter = require "../User/UserGetter"
-request = require "request"
-settings = require "settings-sharelatex"
-logger = require "logger-sharelatex"
-{ V1ConnectionError, NotFoundError } = require "../Errors/Errors"
-
-module.exports = V1SubscriptionManager =
- # Returned planCode = 'v1_pro' | 'v1_pro_plus' | 'v1_student' | 'v1_free' | null
- # For this to work, we need plans in settings with plan-codes:
- # - 'v1_pro'
- # - 'v1_pro_plus'
- # - 'v1_student'
- # - 'v1_free'
- getPlanCodeFromV1: (userId, callback=(err, planCode, v1Id)->) ->
- logger.log {userId}, "[V1SubscriptionManager] fetching v1 plan for user"
- V1SubscriptionManager._v1Request userId, {
- method: 'GET',
- url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/plan_code"
- }, (error, body, v1Id) ->
- return callback(error) if error?
- planName = body?.plan_name
- logger.log {userId, planName, body}, "[V1SubscriptionManager] fetched v1 plan for user"
- if planName in ['pro', 'pro_plus', 'student', 'free']
- planName = "v1_#{planName}"
- else
- # Throw away 'anonymous', etc as being equivalent to null
- planName = null
- return callback(null, planName, v1Id)
-
- notifyV1OfFeaturesChange: (userId, callback = (error) ->) ->
- V1SubscriptionManager._v1Request userId, {
- method: 'POST',
- url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/sync"
- }, callback
-
- getSubscriptionsFromV1: (userId, callback=(err, subscriptions, v1Id) ->) ->
- V1SubscriptionManager._v1Request userId, {
- method: 'GET',
- url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/subscriptions"
- }, callback
-
- getSubscriptionStatusFromV1: (userId, callback=(err, status) ->) ->
- V1SubscriptionManager._v1Request userId, {
- method: 'GET',
- url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/subscription_status"
- }, callback
-
- cancelV1Subscription: (userId, callback=(err)->) ->
- V1SubscriptionManager._v1Request userId, {
- method: 'DELETE',
- url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/subscription"
- }, callback
-
- v1IdForUser: (userId, callback=(err, v1Id) ->) ->
- UserGetter.getUser userId, {'overleaf.id': 1}, (err, user) ->
- return callback(err) if err?
- v1Id = user?.overleaf?.id
- if !v1Id?
- logger.log {userId}, "[V1SubscriptionManager] no v1 id found for user"
-
- callback(null, v1Id)
-
- # v1 accounts created before migration to v2 had github and mendeley for free
- # but these are now paid-for features for new accounts (v1id > cutoff)
- getGrandfatheredFeaturesForV1User: (v1Id) ->
- cutoff = settings.v1GrandfatheredFeaturesUidCutoff
- return {} if !cutoff?
- return {} if !v1Id?
-
- if (v1Id < cutoff)
- return settings.v1GrandfatheredFeatures or {}
- else
- return {}
-
- _v1Request: (userId, options, callback=(err, body, v1Id)->) ->
- if !settings?.apis?.v1
- return callback null, null
-
- V1SubscriptionManager.v1IdForUser userId, (err, v1Id) ->
- return callback(err) if err?
- return callback(null, null, null) if !v1Id?
- request {
- baseUrl: settings.apis.v1.url
- url: options.url(v1Id)
- method: options.method
- auth:
- user: settings.apis.v1.user
- pass: settings.apis.v1.pass
- sendImmediately: true
- json: true,
- timeout: 15 * 1000
- }, (error, response, body) ->
- if error?
- # Specially handle no connection err, so warning can be shown
- error = new V1ConnectionError('No V1 connection') if error.code == 'ECONNREFUSED'
- return callback(error)
- if 200 <= response.statusCode < 300
- return callback null, body, v1Id
- else
- if response.statusCode == 404
- return callback new NotFoundError("v1 user not found: #{userId}")
- else
- return callback new Error("non-success code from v1: #{response.statusCode} #{options.method} #{options.url(v1Id)}")
diff --git a/services/web/app/coffee/Features/Subscription/planFeatures.coffee b/services/web/app/coffee/Features/Subscription/planFeatures.coffee
deleted file mode 100644
index db5710341e..0000000000
--- a/services/web/app/coffee/Features/Subscription/planFeatures.coffee
+++ /dev/null
@@ -1,133 +0,0 @@
-module.exports =
- [
- {
- feature: 'number_collab'
- value: 'str'
- plans: {
- free: '1'
- coll: '10'
- prof: 'unlimited'
- }
- student: '6'
- }
- {
- feature: 'unlimited_private'
- value: 'bool'
- info: 'unlimited_private_info'
- plans: {
- free: true
- coll: true
- prof: true
- },
- student: true
- }
- {
- feature: 'realtime_collab'
- value: 'bool'
- info: 'realtime_collab_info'
- plans: {
- free: true
- coll: true
- prof: true
- }
- student: true
- }
- {
- feature: 'thousands_templates'
- value: 'bool'
- info: 'hundreds_templates_info'
- plans: {
- free: true
- coll: true
- prof: true
- }
- student: true
- }
- {
- feature: 'powerful_latex_editor'
- value: 'bool'
- info: 'latex_editor_info'
- plans: {
- free: true
- coll: true
- prof: true
- }
- student: true
- }
- {
- feature: 'realtime_track_changes'
- value: 'bool'
- info: 'realtime_track_changes_info'
- plans: {
- free: false
- coll: true
- prof: true
- },
- student: true
- }
- {
- feature: 'reference_search'
- value: 'bool'
- info: 'reference_search_info'
- plans: {
- free: false
- coll: true
- prof: true
- },
- student: true
- },
- {
- feature: 'reference_sync'
- info: 'reference_sync_info'
- value: 'bool'
- plans: {
- free: false
- coll: true
- prof: true
- },
- student: true
- }
- {
- feature: 'full_doc_history'
- value: 'bool'
- info: 'full_doc_history_info'
- plans: {
- free: false,
- coll: true,
- prof: true
- },
- student: true
- }
- {
- feature: 'dropbox_integration_lowercase'
- value: 'bool'
- info: 'dropbox_integration_info'
- plans: {
- free: false,
- coll: true,
- prof: true
- },
- student: true
- },
- {
- feature: 'github_integration_lowercase'
- value: 'bool'
- info: 'github_integration_info'
- plans: {
- free: false,
- coll: true,
- prof: true
- },
- student: true
- },
- {
- feature: 'priority_support',
- value: 'bool',
- plans: {
- free: false,
- coll: true,
- prof: true
- },
- student: true
- },
- ]
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/SudoMode/SudoModeController.coffee b/services/web/app/coffee/Features/SudoMode/SudoModeController.coffee
deleted file mode 100644
index b26b88e4f2..0000000000
--- a/services/web/app/coffee/Features/SudoMode/SudoModeController.coffee
+++ /dev/null
@@ -1,63 +0,0 @@
-logger = require 'logger-sharelatex'
-SudoModeHandler = require './SudoModeHandler'
-AuthenticationController = require '../Authentication/AuthenticationController'
-ObjectId = require('../../infrastructure/Mongoose').mongo.ObjectId
-UserGetter = require '../User/UserGetter'
-Settings = require 'settings-sharelatex'
-
-
-module.exports = SudoModeController =
-
- sudoModePrompt: (req, res, next) ->
- if req.externalAuthenticationSystemUsed() and !Settings.overleaf?
- logger.log {userId}, "[SudoMode] using external auth, redirecting"
- return res.redirect('/project')
- userId = AuthenticationController.getLoggedInUserId(req)
- logger.log {userId}, "[SudoMode] rendering sudo mode password page"
- SudoModeHandler.isSudoModeActive userId, (err, isActive) ->
- if err?
- logger.err {err, userId}, "[SudoMode] error checking if sudo mode is active"
- return next(err)
- if isActive
- logger.log {userId}, "[SudoMode] sudo mode already active, redirecting"
- return res.redirect('/project')
- res.render 'sudo_mode/sudo_mode_prompt', title: 'confirm_password_to_continue'
-
- submitPassword: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- redir = AuthenticationController._getRedirectFromSession(req) || "/project"
- password = req.body.password
- if !password
- logger.log {userId}, "[SudoMode] no password supplied, failed authentication"
- return next(new Error('no password supplied'))
- logger.log {userId, redir}, "[SudoMode] checking user password"
- UserGetter.getUser ObjectId(userId), {email: 1}, (err, userRecord) ->
- if err?
- logger.err {err, userId}, "[SudoMode] error getting user"
- return next(err)
- if !userRecord?
- err = new Error('user not found')
- logger.err {err, userId}, "[SudoMode] user not found"
- return next(err)
- SudoModeHandler.authenticate userRecord.email, password, (err, user) ->
- if err?
- logger.err {err, userId}, "[SudoMode] error authenticating user"
- return next(err)
- if user?
- logger.log {userId}, "[SudoMode] authenticated user, activating sudo mode"
- SudoModeHandler.activateSudoMode userId, (err) ->
- if err?
- logger.err {err, userId}, "[SudoMode] error activating sudo mode"
- return next(err)
- return res.json {
- redir: redir
- }
- else
- logger.log {userId}, "[SudoMode] authentication failed for user"
- return res.json {
- message: {
- text: req.i18n.translate("invalid_password"),
- type: 'error'
- }
- }
-
diff --git a/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee b/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee
deleted file mode 100644
index 18e7bfd74f..0000000000
--- a/services/web/app/coffee/Features/SudoMode/SudoModeHandler.coffee
+++ /dev/null
@@ -1,46 +0,0 @@
-RedisWrapper = require('../../infrastructure/RedisWrapper')
-rclient = RedisWrapper.client('sudomode')
-logger = require('logger-sharelatex')
-AuthenticationManager = require '../Authentication/AuthenticationManager'
-Settings = require 'settings-sharelatex'
-V1Handler = require '../V1/V1Handler'
-UserGetter = require '../User/UserGetter'
-
-
-TIMEOUT_IN_SECONDS = 60 * 60
-
-
-module.exports = SudoModeHandler =
-
- _buildKey: (userId) ->
- "SudoMode:{#{userId}}"
-
- authenticate: (email, password, callback=(err, user)->) ->
- if Settings.overleaf?
- V1Handler.authWithV1 email, password, (err, isValid, v1Profile) ->
- if !isValid
- return callback(null, null)
- UserGetter.getUser {'overleaf.id': v1Profile.id}, callback
- else
- AuthenticationManager.authenticate {email}, password, callback
-
- activateSudoMode: (userId, callback=(err)->) ->
- if !userId?
- return callback(new Error('[SudoMode] user must be supplied'))
- duration = TIMEOUT_IN_SECONDS
- logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
- rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback
-
- clearSudoMode: (userId, callback=(err)->) ->
- if !userId?
- return callback(new Error('[SudoMode] user must be supplied'))
- logger.log {userId}, "[SudoMode] clearing sudo mode for user"
- rclient.del SudoModeHandler._buildKey(userId), callback
-
- isSudoModeActive: (userId, callback=(err, isActive)->) ->
- if !userId?
- return callback(new Error('[SudoMode] user must be supplied'))
- rclient.get SudoModeHandler._buildKey(userId), (err, result) ->
- if err?
- return callback(err)
- callback(null, result == '1')
diff --git a/services/web/app/coffee/Features/SudoMode/SudoModeMiddleware.coffee b/services/web/app/coffee/Features/SudoMode/SudoModeMiddleware.coffee
deleted file mode 100644
index 8ef75a52ed..0000000000
--- a/services/web/app/coffee/Features/SudoMode/SudoModeMiddleware.coffee
+++ /dev/null
@@ -1,25 +0,0 @@
-logger = require 'logger-sharelatex'
-SudoModeHandler = require './SudoModeHandler'
-AuthenticationController = require '../Authentication/AuthenticationController'
-Settings = require 'settings-sharelatex'
-
-
-module.exports = SudoModeMiddleware =
-
- protectPage: (req, res, next) ->
- if req.externalAuthenticationSystemUsed() and !Settings.overleaf?
- logger.log {userId}, "[SudoMode] using external auth, skipping sudo-mode check"
- return next()
- userId = AuthenticationController.getLoggedInUserId(req)
- logger.log {userId}, "[SudoMode] protecting endpoint, checking if sudo mode is active"
- SudoModeHandler.isSudoModeActive userId, (err, isActive) ->
- if err?
- logger.err {err, userId}, "[SudoMode] error checking if sudo mode is active"
- return next(err)
- if isActive
- logger.log {userId}, "[SudoMode] sudo mode active, continuing"
- return next()
- else
- logger.log {userId}, "[SudoMode] sudo mode not active, redirecting"
- AuthenticationController.setRedirectInSession(req)
- return res.redirect('/confirm-password')
diff --git a/services/web/app/coffee/Features/SystemMessages/SystemMessageManager.coffee b/services/web/app/coffee/Features/SystemMessages/SystemMessageManager.coffee
deleted file mode 100644
index e3705b3577..0000000000
--- a/services/web/app/coffee/Features/SystemMessages/SystemMessageManager.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-SystemMessage = require("../../models/SystemMessage").SystemMessage
-
-module.exports = SystemMessageManager =
- getMessages: (callback = (error, messages) ->) ->
- if @_cachedMessages?
- return callback null, @_cachedMessages
- else
- @getMessagesFromDB (error, messages) =>
- return callback(error) if error?
- @_cachedMessages = messages
- return callback null, messages
-
- getMessagesFromDB: (callback = (error, messages) ->) ->
- SystemMessage.find {}, callback
-
- clearMessages: (callback = (error) ->) ->
- SystemMessage.remove {}, callback
-
- createMessage: (content, callback = (error) ->) ->
- message = new SystemMessage { content: content }
- message.save callback
-
- clearCache: () ->
- delete @_cachedMessages
-
-CACHE_TIMEOUT = 20 * 1000 # 20 seconds
-setInterval () ->
- SystemMessageManager.clearCache()
-, CACHE_TIMEOUT
diff --git a/services/web/app/coffee/Features/Tags/TagsController.coffee b/services/web/app/coffee/Features/Tags/TagsController.coffee
deleted file mode 100644
index 0cd15ab5e7..0000000000
--- a/services/web/app/coffee/Features/Tags/TagsController.coffee
+++ /dev/null
@@ -1,55 +0,0 @@
-TagsHandler = require("./TagsHandler")
-logger = require("logger-sharelatex")
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-module.exports =
- getAllTags: (req, res, next)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log {user_id}, "getting tags"
- TagsHandler.getAllTags user_id, (error, allTags)->
- return next(error) if error?
- res.json(allTags)
-
- createTag: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- name = req.body.name
- logger.log {user_id, name}, "creating tag"
- TagsHandler.createTag user_id, name, (error, tag) ->
- return next(error) if error?
- res.json(tag)
-
- addProjectToTag: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- {tag_id, project_id} = req.params
- logger.log {user_id, tag_id, project_id}, "adding tag to project"
- TagsHandler.addProjectToTag user_id, tag_id, project_id, (error) ->
- return next(error) if error?
- res.status(204).end()
-
- removeProjectFromTag: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- {tag_id, project_id} = req.params
- logger.log {user_id, tag_id, project_id}, "removing tag from project"
- TagsHandler.removeProjectFromTag user_id, tag_id, project_id, (error) ->
- return next(error) if error?
- res.status(204).end()
-
- deleteTag: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- tag_id = req.params.tag_id
- logger.log {user_id, tag_id}, "deleting tag"
- TagsHandler.deleteTag user_id, tag_id, (error) ->
- return next(error) if error?
- res.status(204).end()
-
- renameTag: (req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- tag_id = req.params.tag_id
- name = req.body?.name
- if !name?
- return res.status(400).end()
- else
- logger.log {user_id, tag_id, name}, "renaming tag"
- TagsHandler.renameTag user_id, tag_id, name, (error) ->
- return next(error) if error?
- res.status(204).end()
diff --git a/services/web/app/coffee/Features/Tags/TagsHandler.coffee b/services/web/app/coffee/Features/Tags/TagsHandler.coffee
deleted file mode 100644
index 5a0c746295..0000000000
--- a/services/web/app/coffee/Features/Tags/TagsHandler.coffee
+++ /dev/null
@@ -1,112 +0,0 @@
-_ = require('underscore')
-settings = require("settings-sharelatex")
-request = require("request")
-logger = require("logger-sharelatex")
-
-TIMEOUT = 1000
-module.exports = TagsHandler =
- getAllTags: (user_id, callback)->
- @_requestTags user_id, (err, allTags)=>
- if !allTags?
- allTags = []
- @_groupTagsByProject allTags, (err, groupedByProject)->
- logger.log allTags:allTags, user_id:user_id, groupedByProject:groupedByProject, "got all tags from tags api"
- callback err, allTags, groupedByProject
-
- createTag: (user_id, name, callback = (error, tag) ->) ->
- opts =
- url: "#{settings.apis.tags.url}/user/#{user_id}/tag"
- json:
- name: name
- timeout: TIMEOUT
- request.post opts, (err, res, body)->
- TagsHandler._handleResponse err, res, {user_id}, (error) ->
- return callback(error) if error?
- callback(null, body or {})
-
- renameTag: (user_id, tag_id, name, callback = (error) ->) ->
- url = "#{settings.apis.tags.url}/user/#{user_id}/tag/#{tag_id}/rename"
- request.post {
- url: url
- json:
- name: name
- timeout: TIMEOUT
- }, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, tag_id, name}, callback
-
- deleteTag: (user_id, tag_id, callback = (error) ->) ->
- url = "#{settings.apis.tags.url}/user/#{user_id}/tag/#{tag_id}"
- request.del {url, timeout: TIMEOUT}, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, tag_id}, callback
-
- updateTagUserIds: (old_user_id, new_user_id, callback) ->
- opts =
- url: "#{settings.apis.tags.url}/user/#{old_user_id}/tag"
- json:
- user_id: new_user_id
- timeout: TIMEOUT
- request.put opts, (err, res, body)->
- TagsHandler._handleResponse err, res, {old_user_id, new_user_id}, callback
-
- removeProjectFromTag: (user_id, tag_id, project_id, callback)->
- url = "#{settings.apis.tags.url}/user/#{user_id}/tag/#{tag_id}/project/#{project_id}"
- request.del {url, timeout: TIMEOUT}, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, tag_id, project_id}, callback
-
- addProjectToTag: (user_id, tag_id, project_id, callback)->
- url = "#{settings.apis.tags.url}/user/#{user_id}/tag/#{tag_id}/project/#{project_id}"
- request.post {url, timeout: TIMEOUT}, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, tag_id, project_id}, callback
-
- addProjectToTagName: (user_id, name, project_id, callback)->
- url = "#{settings.apis.tags.url}/user/#{user_id}/tag/project/#{project_id}"
- opts =
- json: { name }
- timeout: TIMEOUT
- url: url
- request.post opts, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, name, project_id}, callback
-
- removeProjectFromAllTags: (user_id, project_id, callback)->
- url = "#{settings.apis.tags.url}/user/#{user_id}/project/#{project_id}"
- opts =
- url: url
- timeout:TIMEOUT
- request.del opts, (err, res, body) ->
- TagsHandler._handleResponse err, res, {url, user_id, project_id}, callback
-
- _handleResponse: (err, res, params, callback) ->
- if err?
- params.err = err
- logger.err params, "error in tag api"
- return callback(err)
- else if res? and res.statusCode >= 200 and res.statusCode < 300
- return callback(null)
- else
- err = new Error("tags api returned a failure status code: #{res?.statusCode}")
- params.err = err
- logger.err params, "tags api returned failure status code: #{res?.statusCode}"
- return callback(err)
-
- _requestTags: (user_id, callback)->
- opts =
- url: "#{settings.apis.tags.url}/user/#{user_id}/tag"
- json: true
- timeout: TIMEOUT
- request.get opts, (err, res, body)->
- TagsHandler._handleResponse err, res, {user_id}, (error) ->
- return callback(error, []) if error?
- callback(null, body or [])
-
- _groupTagsByProject: (tags, callback)->
- result = {}
- _.each tags, (tag)->
- _.each tag.project_ids, (project_id)->
- result[project_id] = []
-
- _.each tags, (tag)->
- _.each tag.project_ids, (project_id)->
- clonedTag = _.clone(tag)
- delete clonedTag.project_ids
- result[project_id].push(clonedTag)
- callback null, result
diff --git a/services/web/app/coffee/Features/Templates/TemplatesController.coffee b/services/web/app/coffee/Features/Templates/TemplatesController.coffee
deleted file mode 100644
index 0f6c896bb9..0000000000
--- a/services/web/app/coffee/Features/Templates/TemplatesController.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-path = require('path')
-AuthenticationController = require('../../../js/Features/Authentication/AuthenticationController')
-TemplatesManager = require('./TemplatesManager')
-ProjectHelper = require('../../../js/Features/Project/ProjectHelper')
-logger = require('logger-sharelatex')
-
-module.exports = TemplatesController =
-
- getV1Template: (req, res)->
- templateVersionId = req.params.Template_version_id
- templateId = req.query.id
- if !/^[0-9]+$/.test(templateVersionId) || !/^[0-9]+$/.test(templateId)
- logger.err templateVersionId:templateVersionId, templateId: templateId, "invalid template id or version"
- return res.sendStatus 400
- data = {}
- data.templateVersionId = templateVersionId
- data.templateId = templateId
- data.name = req.query.templateName
- data.compiler = ProjectHelper.compilerFromV1Engine(req.query.latexEngine)
- data.imageName = req.query.texImage
- data.mainFile = req.query.mainFile
- data.brandVariationId = req.query.brandVariationId
- res.render path.resolve(__dirname, "../../../views/project/editor/new_from_template"), data
-
- createProjectFromV1Template: (req, res, next)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- TemplatesManager.createProjectFromV1Template req.body.brandVariationId, req.body.compiler, req.body.mainFile, req.body.templateId, req.body.templateName, req.body.templateVersionId, user_id, req.body.imageName, (err, project) ->
- return next err if err?
- delete req.session.templateData
- res.redirect "/project/#{project._id}"
diff --git a/services/web/app/coffee/Features/Templates/TemplatesManager.coffee b/services/web/app/coffee/Features/Templates/TemplatesManager.coffee
deleted file mode 100644
index 8e95649672..0000000000
--- a/services/web/app/coffee/Features/Templates/TemplatesManager.coffee
+++ /dev/null
@@ -1,70 +0,0 @@
-Project = require('../../../js/models/Project').Project
-ProjectDetailsHandler = require "../../../js/Features/Project/ProjectDetailsHandler"
-ProjectOptionsHandler = require "../../../js/Features/Project/ProjectOptionsHandler"
-ProjectRootDocManager = require "../../../js/Features/Project/ProjectRootDocManager"
-ProjectUploadManager = require "../../../js/Features/Uploads/ProjectUploadManager"
-FileWriter = require "../../infrastructure/FileWriter"
-async = require "async"
-fs = require "fs"
-logger = require "logger-sharelatex"
-request = require "request"
-settings = require "settings-sharelatex"
-uuid = require "uuid"
-
-module.exports = TemplatesManager =
- createProjectFromV1Template: (brandVariationId, compiler, mainFile, templateId, templateName, templateVersionId, user_id, imageName, callback) ->
- zipUrl = "#{settings.apis.v1.url}/api/v1/sharelatex/templates/#{templateVersionId}"
- zipReq = request zipUrl, {
- auth:
- user: settings.apis.v1.user
- pass: settings.apis.v1.pass
- }
- zipReq.on "error", (err) ->
- logger.error { err }, "error getting zip from template API"
- callback err
- FileWriter.ensureDumpFolderExists (err) ->
- return callback(err) if err?
-
- projectName = ProjectDetailsHandler.fixProjectName templateName
- dumpPath = "#{settings.path.dumpFolder}/#{uuid.v4()}"
- writeStream = fs.createWriteStream dumpPath
- writeStream.on "close", ->
- if zipReq.response.statusCode != 200
- logger.err { uri: zipUrl, statusCode: zipReq.response.statusCode }, "non-success code getting zip from template API"
- return callback new Error("get zip failed")
- ProjectUploadManager.createProjectFromZipArchiveWithName user_id, projectName, dumpPath, (err, project) ->
- if err?
- logger.err { err, zipReq }, "problem building project from zip"
- return callback err
- async.series [
- (cb) -> TemplatesManager._setCompiler project._id, compiler, cb
- (cb) -> TemplatesManager._setImage project._id, imageName, cb
- (cb) -> TemplatesManager._setMainFile project._id, mainFile, cb
- (cb) -> TemplatesManager._setBrandVariationId project._id, brandVariationId, cb
- ], (err) ->
- return callback err if err?
- fs.unlink dumpPath, (err) ->
- logger.err {err}, "error unlinking template zip" if err?
- update =
- fromV1TemplateId: templateId,
- fromV1TemplateVersionId: templateVersionId
- Project.update { _id: project._id }, update, {}, (err) ->
- return callback err if err?
- callback null, project
- zipReq.pipe(writeStream)
-
- _setCompiler: (project_id, compiler, callback) ->
- return callback() unless compiler?
- ProjectOptionsHandler.setCompiler project_id, compiler, callback
-
- _setImage: (project_id, imageName, callback) ->
- imageName ||= "wl_texlive:2018.1"
- ProjectOptionsHandler.setImageName project_id, imageName, callback
-
- _setMainFile: (project_id, mainFile, callback) ->
- return callback() unless mainFile?
- ProjectRootDocManager.setRootDocFromName project_id, mainFile, callback
-
- _setBrandVariationId: (project_id, brandVariationId, callback) ->
- return callback() unless brandVariationId?
- ProjectOptionsHandler.setBrandVariationId project_id, brandVariationId, callback
diff --git a/services/web/app/coffee/Features/Templates/TemplatesMiddleware.coffee b/services/web/app/coffee/Features/Templates/TemplatesMiddleware.coffee
deleted file mode 100644
index 8baa0ca605..0000000000
--- a/services/web/app/coffee/Features/Templates/TemplatesMiddleware.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-
-
-module.exports =
- saveTemplateDataInSession: (req, res, next)->
- if req.query.templateName
- req.session.templateData = req.query
- next()
diff --git a/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee b/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee
deleted file mode 100644
index 51ddf95b29..0000000000
--- a/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-TemplatesController = require("./TemplatesController")
-TemplatesMiddleware = require('./TemplatesMiddleware')
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-
-module.exports =
- apply: (app)->
-
- app.get '/project/new/template/:Template_version_id', TemplatesMiddleware.saveTemplateDataInSession, AuthenticationController.requireLogin(), TemplatesController.getV1Template
-
- app.post '/project/new/template', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "create-project-from-template"
- maxRequests: 20
- timeInterval: 60
- }), TemplatesController.createProjectFromV1Template
diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee
deleted file mode 100644
index 9dcce6e9c8..0000000000
--- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee
+++ /dev/null
@@ -1,75 +0,0 @@
-tpdsUpdateHandler = require('./TpdsUpdateHandler')
-UpdateMerger = require "./UpdateMerger"
-logger = require('logger-sharelatex')
-Path = require('path')
-metrics = require("metrics-sharelatex")
-
-module.exports =
- # mergeUpdate and deleteUpdate are used by Dropbox, where the project is only passed as the name, as the
- # first part of the file path. They have to check the project exists, find it, and create it if not.
- # They also ignore 'noisy' files like .DS_Store, .gitignore, etc.
- mergeUpdate: (req, res)->
- metrics.inc("tpds.merge-update")
- {filePath, user_id, projectName} = parseParams(req)
- source = req.headers["x-sl-update-source"] or "unknown"
- logger.log user_id:user_id, filePath:filePath, fullPath:req.params[0], projectName:projectName, source: source, "reciving update request from tpds"
- tpdsUpdateHandler.newUpdate user_id, projectName, filePath, req, source, (err)->
- logger.log user_id:user_id, filePath:filePath, fullPath:req.params[0], "sending response that tpdsUpdate has been completed"
- if err?
- logger.err err:err, user_id:user_id, filePath:filePath, "error reciving update from tpds"
- res.sendStatus(500)
- else
- logger.log user_id:user_id, filePath:filePath, projectName:projectName, "telling tpds update has been processed"
- res.sendStatus 200
-
-
- deleteUpdate: (req, res)->
- metrics.inc("tpds.delete-update")
- {filePath, user_id, projectName} = parseParams(req)
- source = req.headers["x-sl-update-source"] or "unknown"
- logger.log user_id:user_id, filePath:filePath, projectName:projectName, fullPath:req.params[0], source: source, "reciving delete request from tpds"
- tpdsUpdateHandler.deleteUpdate user_id, projectName, filePath, source, (err)->
- if err?
- logger.err err:err, user_id:user_id, filePath:filePath, "error reciving update from tpds"
- res.sendStatus(500)
- else
- logger.log user_id:user_id, filePath:filePath, projectName:projectName, "telling tpds delete has been processed"
- res.sendStatus 200
-
- # updateProjectContents and deleteProjectContents are used by GitHub. The project_id is known so we
- # can skip right ahead to creating/updating/deleting the file. These methods will not ignore noisy
- # files like .DS_Store, .gitignore, etc because people are generally more explicit with the files they
- # want in git.
- updateProjectContents: (req, res, next = (error) ->) ->
- {project_id} = req.params
- path = "/" + req.params[0] # UpdateMerger expects leading slash
- source = req.headers["x-sl-update-source"] or "unknown"
- logger.log project_id: project_id, path: path, source: source, "received project contents update"
- UpdateMerger.mergeUpdate null, project_id, path, req, source, (error) ->
- return next(error) if error?
- res.sendStatus(200)
-
- deleteProjectContents: (req, res, next = (error) ->) ->
- {project_id} = req.params
- path = "/" + req.params[0] # UpdateMerger expects leading slash
- source = req.headers["x-sl-update-source"] or "unknown"
- logger.log project_id: project_id, path: path, source: source, "received project contents delete request"
- UpdateMerger.deleteUpdate null, project_id, path, source, (error) ->
- return next(error) if error?
- res.sendStatus(200)
-
- parseParams: parseParams = (req)->
- path = req.params[0]
- user_id = req.params.user_id
-
- path = Path.join("/",path)
- if path.substring(1).indexOf('/') == -1
- filePath = "/"
- projectName = path.substring(1)
- else
- filePath = path.substring(path.indexOf("/",1))
- projectName = path.substring(0, path.indexOf("/",1))
- projectName = projectName.replace("/","")
-
- return filePath:filePath, user_id:user_id, projectName:projectName
-
diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee
deleted file mode 100644
index 78e3f12ed6..0000000000
--- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee
+++ /dev/null
@@ -1,54 +0,0 @@
-updateMerger = require('./UpdateMerger')
-logger = require('logger-sharelatex')
-projectLocator = require('../Project/ProjectLocator')
-projectCreationHandler = require('../Project/ProjectCreationHandler')
-projectDeleter = require('../Project/ProjectDeleter')
-ProjectRootDocManager = require "../Project/ProjectRootDocManager"
-FileTypeManager = require('../Uploads/FileTypeManager')
-CooldownManager = require('../Cooldown/CooldownManager')
-Errors = require('../Errors/Errors')
-
-commitMessage = "Before update from Dropbox"
-
-module.exports =
-
- newUpdate: (user_id, projectName, path, updateRequest, source, callback)->
- getOrCreateProject = (cb)=>
- projectLocator.findUsersProjectByName user_id, projectName, (err, project)=>
- logger.log user_id:user_id, filePath:path, projectName:projectName, "handling new update from tpds"
- if !project?
- projectCreationHandler.createBlankProject user_id, projectName, (err, project)=>
- # have a crack at setting the root doc after a while, on creation we won't have it yet, but should have
- # been sent it it within 30 seconds
- setTimeout (-> ProjectRootDocManager.setRootDocAutomatically project._id ), @_rootDocTimeoutLength
- cb err, project
- else
- cb err, project
- getOrCreateProject (err, project)->
- return callback(err) if err?
- CooldownManager.isProjectOnCooldown project._id, (err, projectIsOnCooldown) ->
- return callback(err) if err?
- if projectIsOnCooldown
- logger.log {projectId: project._id}, "project is on cooldown, denying request"
- return callback(new Errors.TooManyRequestsError('project on cooldown'))
- FileTypeManager.shouldIgnore path, (err, shouldIgnore)->
- if shouldIgnore
- return callback()
- updateMerger.mergeUpdate user_id, project._id, path, updateRequest, source, callback
-
-
- deleteUpdate: (user_id, projectName, path, source, callback)->
- logger.log user_id:user_id, filePath:path, "handling delete update from tpds"
- projectLocator.findUsersProjectByName user_id, projectName, (err, project)->
- if !project?
- logger.log user_id:user_id, filePath:path, projectName:projectName, "project not found from tpds update, ignoring folder or project"
- return callback()
- if path == "/"
- logger.log user_id:user_id, filePath:path, projectName:projectName, project_id:project._id, "project found for delete update, path is root so marking project as deleted"
- return projectDeleter.markAsDeletedByExternalSource project._id, callback
- else
- updateMerger.deleteUpdate user_id, project._id, path, source, (err)->
- callback(err)
-
-
- _rootDocTimeoutLength : 30 * 1000
diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateSender.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateSender.coffee
deleted file mode 100644
index 488f62bfa1..0000000000
--- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateSender.coffee
+++ /dev/null
@@ -1,142 +0,0 @@
-settings = require('settings-sharelatex')
-logger = require('logger-sharelatex')
-path = require('path')
-ProjectGetter = require('../Project/ProjectGetter')
-keys = require('../../infrastructure/Keys')
-metrics = require("metrics-sharelatex")
-request = require("request")
-CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
-
-buildPath = (user_id, project_name, filePath)->
- projectPath = path.join(project_name, "/", filePath)
- projectPath = encodeURIComponent(projectPath)
- fullPath = path.join("/user/", "#{user_id}", "/entity/",projectPath)
- return fullPath
-
-
-
-
-tpdsworkerEnabled = -> settings.apis.tpdsworker?.url?
-if !tpdsworkerEnabled()
- logger.log "tpdsworker is not enabled, request will not be sent to it"
-
-
-if settings.apis.thirdPartyDataStore.linode_url?
- tpdsUrl = settings.apis.thirdPartyDataStore.linode_url
-else
- tpdsUrl = settings.apis.thirdPartyDataStore.url
-
-module.exports = TpdsUpdateSender =
-
- _enqueue: (group, method, job, callback)->
- if !tpdsworkerEnabled()
- return callback()
- opts =
- uri:"#{settings.apis.tpdsworker.url}/enqueue/web_to_tpds_http_requests"
- json :
- group:group
- method:method
- job:job
- method:"post"
- timeout: (5 * 1000)
- request opts, (err)->
- if err?
- logger.err err:err, "error queuing something in the tpdsworker, continuing anyway"
- callback()
- else
- logger.log group:group, job:job, "successfully queued up job for tpdsworker"
- callback()
-
- _addEntity: (options, callback = (err)->)->
- getProjectsUsersIds options.project_id, (err, user_id, allUserIds)->
- if err?
- logger.err err:err, options:options, "error getting projects user ids"
- return callback(err)
- logger.log project_id: options.project_id, user_id:user_id, path: options.path, uri:options.uri, rev:options.rev, "sending file to third party data store"
- postOptions =
- method : "post"
- headers:
- sl_entity_rev:options.rev
- sl_project_id:options.project_id
- sl_all_user_ids:JSON.stringify(allUserIds)
- uri : "#{tpdsUrl}#{buildPath(user_id, options.project_name, options.path)}"
- title: "addFile"
- streamOrigin : options.streamOrigin
- TpdsUpdateSender._enqueue options.project_id, "pipeStreamFrom", postOptions, (err)->
- if err?
- logger.err err:err, project_id: options.project_id, user_id:user_id, path: options.path, uri:options.uri, rev:options.rev, "error sending file to third party data store queued up for processing"
- return callback(err)
- logger.log project_id: options.project_id, user_id:user_id, path: options.path, uri:options.uri, rev:options.rev, "sending file to third party data store queued up for processing"
- callback(err)
-
- addFile : (options, callback = (err)->)->
- metrics.inc("tpds.add-file")
- options.streamOrigin = (settings.apis.filestore.linode_url or settings.apis.filestore.url) + path.join("/project/#{options.project_id}/file/","#{options.file_id}")
- @_addEntity(options, callback)
-
- addDoc : (options, callback = (err)->)->
- metrics.inc("tpds.add-doc")
- options.streamOrigin = (settings.apis.docstore.linode_url or settings.apis.docstore.pubUrl) + path.join("/project/#{options.project_id}/doc/","#{options.doc_id}/raw")
- @_addEntity(options, callback)
-
-
- moveEntity : (options, callback = (err)->)->
- metrics.inc("tpds.move-entity")
- if options.newProjectName?
- startPath = path.join("/#{options.project_name}/")
- endPath = path.join("/#{options.newProjectName}/")
- else
- startPath = mergeProjectNameAndPath(options.project_name, options.startPath)
- endPath = mergeProjectNameAndPath(options.project_name, options.endPath)
- getProjectsUsersIds options.project_id, (err, user_id, allUserIds)->
- logger.log project_id: options.project_id, user_id:user_id, startPath:startPath, endPath:endPath, uri:options.uri, "moving entity in third party data store"
- moveOptions =
- method : "put"
- title:"moveEntity"
- uri : "#{tpdsUrl}/user/#{user_id}/entity"
- headers:
- sl_project_id:options.project_id,
- sl_entity_rev:options.rev
- sl_all_user_ids:JSON.stringify(allUserIds)
- json :
- user_id : user_id
- endPath: endPath
- startPath: startPath
- TpdsUpdateSender._enqueue options.project_id, "standardHttpRequest", moveOptions, callback
-
- deleteEntity : (options, callback = (err)->)->
- metrics.inc("tpds.delete-entity")
- getProjectsUsersIds options.project_id, (err, user_id, allUserIds)->
- logger.log project_id: options.project_id, user_id:user_id, path: options.path, uri:options.uri, "deleting entity in third party data store"
- deleteOptions =
- method : "DELETE"
- headers:
- sl_project_id:options.project_id
- sl_all_user_ids:JSON.stringify(allUserIds)
- uri : "#{tpdsUrl}#{buildPath(user_id, options.project_name, options.path)}"
- title:"deleteEntity"
- sl_all_user_ids:JSON.stringify(allUserIds)
- TpdsUpdateSender._enqueue options.project_id, "standardHttpRequest", deleteOptions, callback
-
- pollDropboxForUser: (user_id, callback = (err) ->) ->
- metrics.inc("tpds.poll-dropbox")
- logger.log user_id: user_id, "polling dropbox for user"
- options =
- method: "POST"
- uri:"#{tpdsUrl}/user/poll"
- json:
- user_ids: [user_id]
- TpdsUpdateSender._enqueue "poll-dropbox:#{user_id}", "standardHttpRequest", options, callback
-
-getProjectsUsersIds = (project_id, callback = (err, owner_id, allUserIds)->)->
- ProjectGetter.getProject project_id, {_id: true, owner_ref: true}, (err, project) ->
- return callback(err) if err?
- CollaboratorsHandler.getInvitedMemberIds project_id, (err, member_ids) ->
- return callback(err) if err?
- callback err, project?.owner_ref, member_ids
-
-mergeProjectNameAndPath = (project_name, path)->
- if(path.indexOf('/') == 0)
- path = path.substring(1)
- fullPath = "/#{project_name}/#{path}"
- return fullPath
diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee
deleted file mode 100644
index 8356a7cb91..0000000000
--- a/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee
+++ /dev/null
@@ -1,74 +0,0 @@
-_ = require('underscore')
-fs = require('fs')
-logger = require('logger-sharelatex')
-EditorController = require('../Editor/EditorController')
-FileTypeManager = require('../Uploads/FileTypeManager')
-FileWriter = require('../../infrastructure/FileWriter')
-ProjectEntityHandler = require('../Project/ProjectEntityHandler')
-
-module.exports = UpdateMerger =
- mergeUpdate: (user_id, project_id, path, updateRequest, source, callback = (error) ->)->
- logger.log project_id:project_id, path:path, "merging update from tpds"
- FileWriter.writeStreamToDisk project_id, updateRequest, (err, fsPath)->
- return callback(err) if err?
- UpdateMerger._mergeUpdate user_id, project_id, path, fsPath, source, (mergeErr) ->
- fs.unlink fsPath, (deleteErr) ->
- if deleteErr?
- logger.err project_id:project_id, fsPath:fsPath, "error deleting file"
- callback mergeErr
-
- _determineFileType: (project_id, path, fsPath, callback = (err, fileType) ->) ->
- ProjectEntityHandler.getAllEntities project_id, (err, docs, files) ->
- return callback(err) if err?
- if _.some(files, (f) -> f.path is path)
- return callback(null, "existing-file")
- if _.some(docs, (d) -> d.path is path)
- return callback(null, "existing-doc")
- # existing file not found in project, so check the file type to determine if doc
- FileTypeManager.getType path, fsPath, (err, isBinary)->
- return callback(err) if err?
- if isBinary
- callback(null, "new-file") # extension was not text
- else
- callback(null, "new-doc")
-
- _mergeUpdate: (user_id, project_id, path, fsPath, source, callback = (error) ->)->
- UpdateMerger._determineFileType project_id, path, fsPath, (err, fileType)->
- return callback(err) if err?
- if fileType in ["existing-file", "new-file"]
- UpdateMerger.p.processFile project_id, fsPath, path, source, user_id, callback
- else if fileType in ["existing-doc", "new-doc"]
- UpdateMerger.p.processDoc project_id, user_id, fsPath, path, source, callback
- else
- callback new Error("unrecognized file")
-
- deleteUpdate: (user_id, project_id, path, source, callback = () ->)->
- EditorController.deleteEntityWithPath project_id, path, source, user_id, () ->
- logger.log project_id:project_id, path:path, "finished processing update to delete entity from tpds"
- callback()
-
- p:
-
- processDoc: (project_id, user_id, fsPath, path, source, callback)->
- UpdateMerger.p.readFileIntoTextArray fsPath, (err, docLines)->
- if err?
- logger.err project_id:project_id, "error reading file into text array for process doc update"
- return callback(err)
- logger.log docLines:docLines, "processing doc update from tpds"
- EditorController.upsertDocWithPath project_id, path, docLines, source, user_id, (err) ->
- logger.log project_id:project_id, "completed processing file update from tpds"
- callback(err)
-
- processFile: (project_id, fsPath, path, source, user_id, callback)->
- logger.log project_id:project_id, "processing file update from tpds"
- EditorController.upsertFileWithPath project_id, path, fsPath, null, source, user_id, (err) ->
- logger.log project_id:project_id, "completed processing file update from tpds"
- callback(err)
-
- readFileIntoTextArray: (path, callback)->
- fs.readFile path, "utf8", (error, content = "") ->
- if error?
- logger.err path:path, "error reading file into text array"
- return callback(error)
- lines = content.split(/\r\n|\n|\r/)
- callback error, lines
diff --git a/services/web/app/coffee/Features/TokenAccess/TokenAccessController.coffee b/services/web/app/coffee/Features/TokenAccess/TokenAccessController.coffee
deleted file mode 100644
index bd90c65fb6..0000000000
--- a/services/web/app/coffee/Features/TokenAccess/TokenAccessController.coffee
+++ /dev/null
@@ -1,154 +0,0 @@
-ProjectController = require "../Project/ProjectController"
-AuthenticationController = require '../Authentication/AuthenticationController'
-TokenAccessHandler = require './TokenAccessHandler'
-Features = require '../../infrastructure/Features'
-Errors = require '../Errors/Errors'
-logger = require 'logger-sharelatex'
-settings = require 'settings-sharelatex'
-
-module.exports = TokenAccessController =
-
- _loadEditor: (projectId, req, res, next) ->
- req.params.Project_id = projectId.toString()
- return ProjectController.loadEditor(req, res, next)
-
- _tryHigherAccess: (token, userId, req, res, next) ->
- TokenAccessHandler.findProjectWithHigherAccess token, userId, (err, project) ->
- if err?
- logger.err {err, token, userId},
- "[TokenAccess] error finding project with higher access"
- return next(err)
- if !project?
- logger.log {token, userId},
- "[TokenAccess] no project with higher access found for this user and token"
- return next(new Errors.NotFoundError())
- logger.log {token, userId, projectId: project._id},
- "[TokenAccess] user has higher access to project, redirecting"
- res.redirect(302, "/project/#{project._id}")
-
- readAndWriteToken: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- token = req.params['read_and_write_token']
- logger.log {userId, token}, "[TokenAccess] requesting read-and-write token access"
- TokenAccessHandler.findProjectWithReadAndWriteToken token, (err, project, projectExists) ->
- if err?
- logger.err {err, token, userId},
- "[TokenAccess] error getting project by readAndWrite token"
- return next(err)
- if !projectExists and settings.overleaf
- logger.log {token, userId},
- "[TokenAccess] no project found for this token"
- TokenAccessController._handleV1Project(
- token,
- userId,
- "/#{token}",
- res,
- next
- )
- else if !project?
- logger.log {token, userId},
- "[TokenAccess] no token-based project found for readAndWrite token"
- if !userId?
- logger.log {token},
- "[TokenAccess] No project found with read-write token, anonymous user, deny"
- return next(new Errors.NotFoundError())
- TokenAccessController._tryHigherAccess(token, userId, req, res, next)
- else
- if !userId?
- if TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
- logger.log {token, projectId: project._id},
- "[TokenAccess] allow anonymous read-and-write token access"
- TokenAccessHandler.grantSessionTokenAccess(req, project._id, token)
- req._anonymousAccessToken = token
- return TokenAccessController._loadEditor(project._id, req, res, next)
- else
- logger.log {token, projectId: project._id},
- "[TokenAccess] deny anonymous read-and-write token access"
- AuthenticationController.setRedirectInSession(req)
- return res.redirect('/restricted')
- if project.owner_ref.toString() == userId
- logger.log {userId, projectId: project._id},
- "[TokenAccess] user is already project owner"
- return TokenAccessController._loadEditor(project._id, req, res, next)
- logger.log {userId, projectId: project._id},
- "[TokenAccess] adding user to project with readAndWrite token"
- TokenAccessHandler.addReadAndWriteUserToProject userId, project._id, (err) ->
- if err?
- logger.err {err, token, userId, projectId: project._id},
- "[TokenAccess] error adding user to project with readAndWrite token"
- return next(err)
- return TokenAccessController._loadEditor(project._id, req, res, next)
-
- readOnlyToken: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- token = req.params['read_only_token']
- logger.log {userId, token}, "[TokenAccess] requesting read-only token access"
- TokenAccessHandler.getV1DocPublishedInfo token, (err, doc_published_info) ->
- return next err if err?
- return res.redirect doc_published_info.published_path if doc_published_info.allow == false
-
- TokenAccessHandler.findProjectWithReadOnlyToken token, (err, project, projectExists) ->
- if err?
- logger.err {err, token, userId},
- "[TokenAccess] error getting project by readOnly token"
- return next(err)
- if !projectExists and settings.overleaf
- logger.log {token, userId},
- "[TokenAccess] no project found for this token"
- TokenAccessController._handleV1Project(
- token,
- userId,
- "/read/#{token}",
- res,
- next
- )
- else if !project?
- logger.log {token, userId},
- "[TokenAccess] no project found for readOnly token"
- if !userId?
- logger.log {token},
- "[TokenAccess] No project found with readOnly token, anonymous user, deny"
- return next(new Errors.NotFoundError())
- TokenAccessController._tryHigherAccess(token, userId, req, res, next)
- else
- if !userId?
- logger.log {userId, projectId: project._id},
- "[TokenAccess] adding anonymous user to project with readOnly token"
- TokenAccessHandler.grantSessionTokenAccess(req, project._id, token)
- req._anonymousAccessToken = token
- return TokenAccessController._loadEditor(project._id, req, res, next)
- else
- if project.owner_ref.toString() == userId
- logger.log {userId, projectId: project._id},
- "[TokenAccess] user is already project owner"
- return TokenAccessController._loadEditor(project._id, req, res, next)
- logger.log {userId, projectId: project._id},
- "[TokenAccess] adding user to project with readOnly token"
- TokenAccessHandler.addReadOnlyUserToProject userId, project._id, (err) ->
- if err?
- logger.err {err, token, userId, projectId: project._id},
- "[TokenAccess] error adding user to project with readAndWrite token"
- return next(err)
- return TokenAccessController._loadEditor(project._id, req, res, next)
-
- _handleV1Project: (token, userId, redirectPath, res, next) ->
- if !userId?
- if Features.hasFeature('force-import-to-v2')
- return res.render('project/v2-import', { loginRedirect: redirectPath })
- else
- return res.redirect(302, "/sign_in_to_v1?return_to=#{redirectPath}")
- else
- TokenAccessHandler.getV1DocInfo token, userId, (err, doc_info) ->
- return next err if err?
- return next(new Errors.NotFoundError()) if !doc_info.exists
- return next(new Errors.NotFoundError()) if doc_info.exported
- if Features.hasFeature('force-import-to-v2')
- return res.render('project/v2-import', {
- projectId: token,
- hasOwner: doc_info.has_owner,
- name: doc_info.name || 'Untitled',
- hasAssignment: doc_info.has_assignment,
- brandInfo: doc_info.brand_info
- })
- else
- return res.redirect(302, "/sign_in_to_v1?return_to=#{redirectPath}")
diff --git a/services/web/app/coffee/Features/TokenAccess/TokenAccessHandler.coffee b/services/web/app/coffee/Features/TokenAccess/TokenAccessHandler.coffee
deleted file mode 100644
index 3c64bbff07..0000000000
--- a/services/web/app/coffee/Features/TokenAccess/TokenAccessHandler.coffee
+++ /dev/null
@@ -1,174 +0,0 @@
-Project = require('../../models/Project').Project
-CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
-PublicAccessLevels = require '../Authorization/PublicAccessLevels'
-PrivilegeLevels = require '../Authorization/PrivilegeLevels'
-UserGetter = require '../User/UserGetter'
-ObjectId = require("mongojs").ObjectId
-Settings = require('settings-sharelatex')
-logger = require('logger-sharelatex')
-V1Api = require "../V1/V1Api"
-crypto = require 'crypto'
-
-module.exports = TokenAccessHandler =
-
- ANONYMOUS_READ_AND_WRITE_ENABLED:
- Settings.allowAnonymousReadAndWriteSharing == true
-
- _extractNumericPrefix: (token) ->
- token.match(/^(\d+)\w+/)
-
- _getProjectByReadOnlyToken: (token, callback=(err, project)->) ->
- Project.findOne {
- 'tokens.readOnly': token
- }, {_id: 1, tokens: 1, publicAccesLevel: 1, owner_ref: 1}, callback
-
- _getProjectByEitherToken: (token, callback=(err, project)->) ->
- TokenAccessHandler._getProjectByReadOnlyToken token, (err, project) ->
- return callback(err) if err?
- if project?
- return callback(null, project)
- TokenAccessHandler._getProjectByReadAndWriteToken token, (err, project) ->
- return callback(err) if err?
- callback(null, project)
-
- _getProjectByReadAndWriteToken: (token, callback=(err, project)->) ->
- numericPrefixMatch = TokenAccessHandler._extractNumericPrefix(token)
- if !numericPrefixMatch
- return callback(null, null)
- numerics = numericPrefixMatch[1]
- Project.findOne {
- 'tokens.readAndWritePrefix': numerics
- }, {_id: 1, tokens: 1, publicAccesLevel: 1, owner_ref: 1}, (err, project) ->
- return callback(err) if err?
- if !project?
- return callback(null, null)
- try
- if !crypto.timingSafeEqual(new Buffer(token), new Buffer(project.tokens.readAndWrite))
- logger.err {token}, "read-and-write token match on numeric section, but not on full token"
- return callback(null, null)
- else
- return callback(null, project)
- catch err
- logger.err {token, cryptoErr: err}, "error comparing tokens"
- return callback(null, null)
-
- findProjectWithReadOnlyToken: (token, callback=(err, project, projectExists)->) ->
- TokenAccessHandler._getProjectByReadOnlyToken token, (err, project) ->
- if err?
- return callback(err)
- if !project?
- return callback(null, null, false) # Project doesn't exist, so we handle differently
- if project.publicAccesLevel != PublicAccessLevels.TOKEN_BASED
- return callback(null, null, true) # Project does exist, but it isn't token based
- return callback(null, project, true)
-
- findProjectWithReadAndWriteToken: (token, callback=(err, project, projectExists)->) ->
- TokenAccessHandler._getProjectByReadAndWriteToken token, (err, project) ->
- if err?
- return callback(err)
- if !project?
- return callback(null, null, false) # Project doesn't exist, so we handle differently
- if project.publicAccesLevel != PublicAccessLevels.TOKEN_BASED
- return callback(null, null, true) # Project does exist, but it isn't token based
- return callback(null, project, true)
-
- _userIsMember: (userId, projectId, callback=(err, isMember)->) ->
- CollaboratorsHandler.isUserInvitedMemberOfProject userId, projectId, callback
-
- findProjectWithHigherAccess: (token, userId, callback=(err, project)->) ->
- TokenAccessHandler._getProjectByEitherToken token, (err, project) ->
- return callback(err) if err?
- if !project?
- return callback(null, null)
- projectId = project._id
- TokenAccessHandler._userIsMember userId, projectId, (err, isMember) ->
- return callback(err) if err?
- callback(
- null,
- if isMember == true then project else null
- )
-
- addReadOnlyUserToProject: (userId, projectId, callback=(err)->) ->
- userId = ObjectId(userId.toString())
- projectId = ObjectId(projectId.toString())
- Project.update {
- _id: projectId
- }, {
- $addToSet: {tokenAccessReadOnly_refs: userId}
- }, callback
-
- addReadAndWriteUserToProject: (userId, projectId, callback=(err)->) ->
- userId = ObjectId(userId.toString())
- projectId = ObjectId(projectId.toString())
- Project.update {
- _id: projectId
- }, {
- $addToSet: {tokenAccessReadAndWrite_refs: userId}
- }, callback
-
- grantSessionTokenAccess: (req, projectId, token) ->
- if req.session?
- if !req.session.anonTokenAccess?
- req.session.anonTokenAccess = {}
- req.session.anonTokenAccess[projectId.toString()] = token.toString()
-
- getRequestToken: (req, projectId) ->
- token = (
- req?.session?.anonTokenAccess?[projectId.toString()] or
- req?.headers['x-sl-anonymous-access-token']
- )
- return token
-
- isValidToken: (projectId, token, callback=(err, isValidReadAndWrite, isValidReadOnly)->) ->
- if !token
- return callback null, false, false
- _validate = (project) ->
- project? and
- project.publicAccesLevel == PublicAccessLevels.TOKEN_BASED and
- project._id.toString() == projectId.toString()
- TokenAccessHandler.findProjectWithReadAndWriteToken token, (err, readAndWriteProject) ->
- return callback(err) if err?
- isValidReadAndWrite = _validate(readAndWriteProject)
- TokenAccessHandler.findProjectWithReadOnlyToken token, (err, readOnlyProject) ->
- return callback(err) if err?
- isValidReadOnly = _validate(readOnlyProject)
- callback null, isValidReadAndWrite, isValidReadOnly
-
- protectTokens: (project, privilegeLevel) ->
- if project? && project.tokens?
- if privilegeLevel == PrivilegeLevels.OWNER
- return
- if privilegeLevel != PrivilegeLevels.READ_AND_WRITE
- project.tokens.readAndWrite = ''
- project.tokens.readAndWritePrefix = ''
- if privilegeLevel != PrivilegeLevels.READ_ONLY
- project.tokens.readOnly = ''
-
- getV1DocPublishedInfo: (token, callback = (err, publishedInfo) ->) ->
- # default to allowing access
- return callback(null, {
- allow: true
- }) unless Settings.apis?.v1?
-
- V1Api.request { url: "/api/v1/sharelatex/docs/#{token}/is_published" }, (err, response, body) ->
- return callback err if err?
- callback null, body
-
- getV1DocInfo: (token, v2UserId, callback=(err, info)->) ->
- # default to not exported
- return callback(null, {
- exists: true
- exported: false
- }) unless Settings.apis?.v1?
-
- UserGetter.getUser v2UserId, { overleaf: 1 }, (err, user) ->
- return callback(err) if err?
- v1UserId = user.overleaf?.id
- V1Api.request { url: "/api/v1/sharelatex/users/#{v1UserId}/docs/#{token}/info" }, (err, response, body) ->
- return callback err if err?
- callback null, body
-
-module.exports.READ_AND_WRITE_TOKEN_REGEX = /^(\d+)(\w+)$/
-module.exports.READ_AND_WRITE_URL_REGEX = /^\/(\d+)(\w+)$/
-module.exports.READ_ONLY_TOKEN_REGEX = /^([a-z]{12})$/
-module.exports.READ_ONLY_URL_REGEX = /^\/read\/([a-z]{12})$/
diff --git a/services/web/app/coffee/Features/Uploads/ArchiveManager.coffee b/services/web/app/coffee/Features/Uploads/ArchiveManager.coffee
deleted file mode 100644
index fe41454206..0000000000
--- a/services/web/app/coffee/Features/Uploads/ArchiveManager.coffee
+++ /dev/null
@@ -1,143 +0,0 @@
-logger = require "logger-sharelatex"
-metrics = require "metrics-sharelatex"
-fs = require "fs"
-Path = require "path"
-fse = require "fs-extra"
-yauzl = require "yauzl"
-Settings = require "settings-sharelatex"
-Errors = require "../Errors/Errors"
-_ = require("underscore")
-
-ONE_MEG = 1024 * 1024
-
-module.exports = ArchiveManager =
-
- _isZipTooLarge: (source, callback = (err, isTooLarge)->)->
- callback = _.once callback
-
- totalSizeInBytes = null
- yauzl.open source, {lazyEntries: true}, (err, zipfile) ->
- return callback(new Errors.InvalidError("invalid_zip_file")) if err?
-
- if Settings.maxEntitiesPerProject? and zipfile.entryCount > Settings.maxEntitiesPerProject
- return callback(null, true) # too many files in zip file
-
- zipfile.on "error", callback
-
- # read all the entries
- zipfile.readEntry()
- zipfile.on "entry", (entry) ->
- totalSizeInBytes += entry.uncompressedSize
- zipfile.readEntry() # get the next entry
-
- # no more entries to read
- zipfile.on "end", () ->
- if !totalSizeInBytes? or isNaN(totalSizeInBytes)
- logger.err source:source, totalSizeInBytes:totalSizeInBytes, "error getting bytes of zip"
- return callback(new Error("error getting bytes of zip"))
- isTooLarge = totalSizeInBytes > (ONE_MEG * 300)
- callback(null, isTooLarge)
-
- _checkFilePath: (entry, destination, callback = (err, destFile) ->) ->
- # transform backslashes to forwardslashes to accommodate badly-behaved zip archives
- transformedFilename = entry.fileName.replace(/\\/g, '/')
- # check if the entry is a directory
- endsWithSlash = /\/$/
- if endsWithSlash.test(transformedFilename)
- return callback() # don't give a destfile for directory
- # check that the file does not use a relative path
- for dir in transformedFilename.split('/')
- if dir == '..'
- return callback(new Error("relative path"))
- # check that the destination file path is normalized
- dest = "#{destination}/#{transformedFilename}"
- if dest != Path.normalize(dest)
- return callback(new Error("unnormalized path"))
- else
- return callback(null, dest)
-
- _writeFileEntry: (zipfile, entry, destFile, callback = (err)->) ->
- callback = _.once callback
-
- zipfile.openReadStream entry, (err, readStream) ->
- return callback(err) if err?
- readStream.on "error", callback
- readStream.on "end", callback
-
- errorHandler = (err) -> # clean up before calling callback
- readStream.unpipe()
- readStream.destroy()
- callback(err)
-
- fse.ensureDir Path.dirname(destFile), (err) ->
- return errorHandler(err) if err?
- writeStream = fs.createWriteStream destFile
- writeStream.on 'error', errorHandler
- readStream.pipe(writeStream)
-
- _extractZipFiles: (source, destination, callback = (err) ->) ->
- callback = _.once callback
-
- yauzl.open source, {lazyEntries: true}, (err, zipfile) ->
- return callback(err) if err?
- zipfile.on "error", callback
- # read all the entries
- zipfile.readEntry()
- zipfile.on "entry", (entry) ->
- logger.log {source:source, fileName: entry.fileName}, "processing zip file entry"
- ArchiveManager._checkFilePath entry, destination, (err, destFile) ->
- if err?
- logger.warn err:err, source:source, destination:destination, "skipping bad file path"
- zipfile.readEntry() # bad path, just skip to the next file
- return
- if destFile? # only write files
- ArchiveManager._writeFileEntry zipfile, entry, destFile, (err) ->
- if err?
- logger.error err:err, source:source, destFile:destFile, "error unzipping file entry"
- zipfile.close() # bail out, stop reading file entries
- return callback(err)
- else
- zipfile.readEntry() # continue to the next file
- else # if it's a directory, continue
- zipfile.readEntry()
- # no more entries to read
- zipfile.on "end", callback
-
- extractZipArchive: (source, destination, _callback = (err) ->) ->
- callback = (args...) ->
- _callback(args...)
- _callback = () ->
-
- ArchiveManager._isZipTooLarge source, (err, isTooLarge)->
- if err?
- logger.err err:err, "error checking size of zip file"
- return callback(err)
-
- if isTooLarge
- return callback(new Errors.InvalidError("zip_contents_too_large"))
-
- timer = new metrics.Timer("unzipDirectory")
- logger.log source: source, destination: destination, "unzipping file"
-
- ArchiveManager._extractZipFiles source, destination, (err) ->
- timer.done()
- if err?
- logger.error {err, source, destination}, "unzip failed"
- callback(err)
- else
- callback()
-
- findTopLevelDirectory: (directory, callback = (error, topLevelDir) ->) ->
- fs.readdir directory, (error, files) ->
- return callback(error) if error?
- if files.length == 1
- childPath = Path.join(directory, files[0])
- fs.stat childPath, (error, stat) ->
- return callback(error) if error?
- if stat.isDirectory()
- return callback(null, childPath)
- else
- return callback(null, directory)
- else
- return callback(null, directory)
-
diff --git a/services/web/app/coffee/Features/Uploads/FileSystemImportManager.coffee b/services/web/app/coffee/Features/Uploads/FileSystemImportManager.coffee
deleted file mode 100644
index 92352bf744..0000000000
--- a/services/web/app/coffee/Features/Uploads/FileSystemImportManager.coffee
+++ /dev/null
@@ -1,94 +0,0 @@
-async = require "async"
-fs = require "fs"
-_ = require "underscore"
-FileTypeManager = require "./FileTypeManager"
-EditorController = require "../Editor/EditorController"
-logger = require("logger-sharelatex")
-
-module.exports = FileSystemImportManager =
- addDoc: (user_id, project_id, folder_id, name, path, charset, replace, callback = (error, doc)-> )->
- FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
- if !isSafe
- logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, name:name, path:path, "add doc is from symlink, stopping process"
- return callback("path is symlink")
- fs.readFile path, charset, (error, content) ->
- return callback(error) if error?
- content = content.replace(/\r\n?/g, "\n") # convert Windows line endings to unix. very old macs also created \r-separated lines
- lines = content.split("\n")
- if replace
- EditorController.upsertDoc project_id, folder_id, name, lines, "upload", user_id, callback
- else
- EditorController.addDoc project_id, folder_id, name, lines, "upload", user_id, callback
-
- addFile: (user_id, project_id, folder_id, name, path, replace, callback = (error, file)-> )->
- FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
- if !isSafe
- logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, name:name, path:path, "add file is from symlink, stopping insert"
- return callback("path is symlink")
-
- if replace
- EditorController.upsertFile project_id, folder_id, name, path, null, "upload", user_id, callback
- else
- EditorController.addFile project_id, folder_id, name, path, null, "upload", user_id, callback
-
- addFolder: (user_id, project_id, folder_id, name, path, replace, callback = (error)-> ) ->
- FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
- if !isSafe
- logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, path:path, "add folder is from symlink, stopping insert"
- return callback("path is symlink")
- EditorController.addFolder project_id, folder_id, name, "upload", (error, new_folder) =>
- return callback(error) if error?
- FileSystemImportManager.addFolderContents user_id, project_id, new_folder._id, path, replace, (error) ->
- return callback(error) if error?
- callback null, new_folder
-
- addFolderContents: (user_id, project_id, parent_folder_id, folderPath, replace, callback = (error)-> ) ->
- FileSystemImportManager._isSafeOnFileSystem folderPath, (err, isSafe)->
- if !isSafe
- logger.log user_id:user_id, project_id:project_id, parent_folder_id:parent_folder_id, folderPath:folderPath, "add folder contents is from symlink, stopping insert"
- return callback("path is symlink")
- fs.readdir folderPath, (error, entries = []) =>
- return callback(error) if error?
- async.eachSeries(
- entries,
- (entry, callback) =>
- FileTypeManager.shouldIgnore entry, (error, ignore) =>
- return callback(error) if error?
- if !ignore
- FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, entry, "#{folderPath}/#{entry}", replace, callback
- else
- callback()
- callback
- )
-
- addEntity: (user_id, project_id, folder_id, name, path, replace, callback = (error, entity)-> ) ->
- FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
- if !isSafe
- logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, path:path, "add entry is from symlink, stopping insert"
- return callback("path is symlink")
-
- FileTypeManager.isDirectory path, (error, isDirectory) =>
- return callback(error) if error?
- if isDirectory
- FileSystemImportManager.addFolder user_id, project_id, folder_id, name, path, replace, callback
- else
- FileTypeManager.getType name, path, (error, isBinary, charset) =>
- return callback(error) if error?
- if isBinary
- FileSystemImportManager.addFile user_id, project_id, folder_id, name, path, replace, (err, entity) ->
- entity?.type = 'file'
- callback(err, entity)
- else
- FileSystemImportManager.addDoc user_id, project_id, folder_id, name, path, charset, replace, (err, entity) ->
- entity?.type = 'doc'
- callback(err, entity)
-
-
- _isSafeOnFileSystem: (path, callback = (err, isSafe)->)->
- fs.lstat path, (err, stat)->
- if err?
- logger.err err:err, "error with path symlink check"
- return callback(err)
- isSafe = stat.isFile() or stat.isDirectory()
- callback(err, isSafe)
-
diff --git a/services/web/app/coffee/Features/Uploads/FileTypeManager.coffee b/services/web/app/coffee/Features/Uploads/FileTypeManager.coffee
deleted file mode 100644
index 46cb86cfc3..0000000000
--- a/services/web/app/coffee/Features/Uploads/FileTypeManager.coffee
+++ /dev/null
@@ -1,70 +0,0 @@
-fs = require "fs"
-Path = require("path")
-isUtf8 = require('is-utf8');
-
-
-module.exports = FileTypeManager =
- TEXT_EXTENSIONS : [
- "tex", "latex", "sty", "cls", "bst", "bib", "bibtex", "txt", "tikz", "rtex", "md", "asy", "latexmkrc", "lbx", "bbx", "cbx", "m"
- ]
-
- IGNORE_EXTENSIONS : [
- "dvi", "aux", "log", "toc", "out", "pdfsync"
- # Index and glossary files
- "nlo", "ind", "glo", "gls", "glg"
- # Bibtex
- "bbl", "blg"
- # Misc/bad
- "doc", "docx", "gz"
- ]
-
- IGNORE_FILENAMES : [
- "__MACOSX"
- ".git"
- ".gitignore"
- ]
-
- MAX_TEXT_FILE_SIZE: 1 * 1024 * 1024 # 1 MB
-
- isDirectory: (path, callback = (error, result) ->) ->
- fs.stat path, (error, stats) ->
- return callback(error) if error?
- callback(null, stats?.isDirectory())
-
- # returns charset as understood by fs.readFile,
- getType: (name, fsPath, callback = (error, isBinary, charset) ->) ->
- parts = name.split(".")
- extension = parts.slice(-1)[0].toLowerCase()
- isText = (FileTypeManager.TEXT_EXTENSIONS.indexOf(extension) > -1 and parts.length > 1) or parts[0] == 'latexmkrc'
-
- return callback null, true unless isText
-
- fs.stat fsPath, (error, stat) ->
- return callback(error) if error?
- if stat.size > FileTypeManager.MAX_TEXT_FILE_SIZE
- return callback null, true # Treat large text file as binary
-
- fs.readFile fsPath, (err, bytes) ->
- return callback(err) if err?
-
- if isUtf8(bytes)
- return callback null, false, "utf-8"
- # check for little-endian unicode bom (nodejs does not support big-endian)
- if bytes[0] == 0xFF and bytes[1] == 0xFE
- return callback null, false, "utf-16le"
-
- callback null, false, "latin1"
-
- shouldIgnore: (path, callback = (error, result) ->) ->
- name = Path.basename(path)
- extension = name.split(".").slice(-1)[0]
- if extension?
- extension = extension.toLowerCase()
- ignore = false
- if name[0] == "." and extension != 'latexmkrc'
- ignore = true
- if @IGNORE_EXTENSIONS.indexOf(extension) != -1
- ignore = true
- if @IGNORE_FILENAMES.indexOf(name) != -1
- ignore = true
- callback null, ignore
diff --git a/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee b/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee
deleted file mode 100644
index 86cd8985f6..0000000000
--- a/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee
+++ /dev/null
@@ -1,81 +0,0 @@
-logger = require "logger-sharelatex"
-metrics = require "metrics-sharelatex"
-fs = require "fs"
-Path = require "path"
-FileSystemImportManager = require "./FileSystemImportManager"
-ProjectUploadManager = require "./ProjectUploadManager"
-AuthenticationController = require('../Authentication/AuthenticationController')
-Settings = require "settings-sharelatex"
-Errors = require "../Errors/Errors"
-multer = require('multer')
-
-upload = null
-
-try
- upload = multer(
- dest: Settings.path.uploadFolder
- limits: fileSize: Settings.maxUploadSize
- )
-catch err
- if err.message == "EEXIST"
- logger.log uploadFolder:Settings.path.uploadFolder, "dir already exists, continuing"
- else
- logger.err err:err, "caught error from multer in uploads router"
-
-module.exports = ProjectUploadController =
- uploadProject: (req, res, next) ->
- timer = new metrics.Timer("project-upload")
- user_id = AuthenticationController.getLoggedInUserId(req)
- {originalname, path} = req.file
- name = Path.basename(originalname, ".zip")
- ProjectUploadManager.createProjectFromZipArchive user_id, name, path, (error, project) ->
- fs.unlink path, ->
- timer.done()
- if error?
- logger.error
- err: error, file_path: path, file_name: name,
- "error uploading project"
- if error.name? && error.name == 'InvalidError'
- res.status(422).json { success: false, error: req.i18n.translate(error.message) }
- else
- res.status(500).json { success: false, error: req.i18n.translate("upload_failed") }
- else
- logger.log
- project: project._id, file_path: path, file_name: name,
- "uploaded project"
- res.send success: true, project_id: project._id
-
- uploadFile: (req, res, next) ->
- timer = new metrics.Timer("file-upload")
- name = req.file?.originalname
- path = req.file?.path
- project_id = req.params.Project_id
- folder_id = req.query.folder_id
- if !name? or name.length == 0 or name.length > 150
- logger.err project_id:project_id, name:name, "bad name when trying to upload file"
- return res.send success: false
- logger.log folder_id:folder_id, project_id:project_id, "getting upload file request"
- user_id = AuthenticationController.getLoggedInUserId(req)
-
- FileSystemImportManager.addEntity user_id, project_id, folder_id, name, path, true, (error, entity) ->
- fs.unlink path, ->
- timer.done()
- if error?
- logger.error
- err: error, project_id: project_id, file_path: path,
- file_name: name, folder_id: folder_id,
- "error uploading file"
- res.send success: false
- else
- logger.log
- project_id: project_id, file_path: path, file_name: name, folder_id: folder_id
- "uploaded file"
- res.send success: true, entity_id: entity?._id, entity_type: entity?.type
-
- multerMiddleware: (req, res, next) ->
- return res.status(500).json {success: false, error: req.i18n.translate("upload_failed")} unless upload?
- upload.single('qqfile') req, res, (err) ->
- if err instanceof multer.MulterError && err.code == 'LIMIT_FILE_SIZE'
- return res.status(422).json {success: false, error: req.i18n.translate("file_too_large")}
-
- next(err)
diff --git a/services/web/app/coffee/Features/Uploads/ProjectUploadManager.coffee b/services/web/app/coffee/Features/Uploads/ProjectUploadManager.coffee
deleted file mode 100644
index ecd6bb6ad6..0000000000
--- a/services/web/app/coffee/Features/Uploads/ProjectUploadManager.coffee
+++ /dev/null
@@ -1,71 +0,0 @@
-path = require "path"
-rimraf = require "rimraf"
-async = require "async"
-ArchiveManager = require "./ArchiveManager"
-FileSystemImportManager = require "./FileSystemImportManager"
-ProjectCreationHandler = require "../Project/ProjectCreationHandler"
-ProjectRootDocManager = require "../Project/ProjectRootDocManager"
-ProjectDetailsHandler = require "../Project/ProjectDetailsHandler"
-DocumentHelper = require "../Documents/DocumentHelper"
-
-module.exports = ProjectUploadHandler =
- createProjectFromZipArchive: (owner_id, defaultName, zipPath, callback = (error, project) ->) ->
- destination = @_getDestinationDirectory zipPath
- docPath = null
- project = null
-
- async.waterfall([
- (cb) ->
- ArchiveManager.extractZipArchive zipPath, destination, cb
- (cb) ->
- ProjectRootDocManager.findRootDocFileFromDirectory destination, (error, _docPath, docContents) ->
- cb(error, _docPath, docContents)
- (_docPath, docContents, cb) ->
- docPath = _docPath
- proposedName = ProjectDetailsHandler.fixProjectName(DocumentHelper.getTitleFromTexContent(docContents || '') || defaultName)
- ProjectDetailsHandler.generateUniqueName owner_id, proposedName, (error, name) ->
- cb(error, name)
- (name, cb) ->
- ProjectCreationHandler.createBlankProject owner_id, name, (error, _project) ->
- cb(error, _project)
- (_project, cb) =>
- project = _project
- @_insertZipContentsIntoFolder owner_id, project._id, project.rootFolder[0]._id, destination, cb
- (cb) ->
- if docPath?
- ProjectRootDocManager.setRootDocFromName project._id, docPath, (error) ->
- cb(error)
- else
- cb(null)
- (cb) ->
- cb(null, project)
- ], callback)
-
- createProjectFromZipArchiveWithName: (owner_id, proposedName, zipPath, callback = (error, project) ->) ->
- ProjectDetailsHandler.generateUniqueName owner_id, ProjectDetailsHandler.fixProjectName(proposedName), (error, name) =>
- return callback(error) if error?
- ProjectCreationHandler.createBlankProject owner_id, name, (error, project) =>
- return callback(error) if error?
- @insertZipArchiveIntoFolder owner_id, project._id, project.rootFolder[0]._id, zipPath, (error) ->
- return callback(error) if error?
- ProjectRootDocManager.setRootDocAutomatically project._id, (error) ->
- return callback(error) if error?
- callback(error, project)
-
- insertZipArchiveIntoFolder: (owner_id, project_id, folder_id, zipPath, callback = (error) ->) ->
- destination = @_getDestinationDirectory zipPath
- ArchiveManager.extractZipArchive zipPath, destination, (error) =>
- return callback(error) if error?
-
- @_insertZipContentsIntoFolder owner_id, project_id, folder_id, destination, callback
-
- _insertZipContentsIntoFolder: (owner_id, project_id, folder_id, destination, callback = (error) ->) ->
- ArchiveManager.findTopLevelDirectory destination, (error, topLevelDestination) ->
- return callback(error) if error?
- FileSystemImportManager.addFolderContents owner_id, project_id, folder_id, topLevelDestination, false, (error) ->
- return callback(error) if error?
- rimraf(destination, callback)
-
- _getDestinationDirectory: (source) ->
- return path.join(path.dirname(source), "#{path.basename(source, ".zip")}-#{Date.now()}")
-
diff --git a/services/web/app/coffee/Features/Uploads/UploadsRouter.coffee b/services/web/app/coffee/Features/Uploads/UploadsRouter.coffee
deleted file mode 100644
index 6ffaa4212e..0000000000
--- a/services/web/app/coffee/Features/Uploads/UploadsRouter.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
-AuthenticationController = require('../Authentication/AuthenticationController')
-ProjectUploadController = require "./ProjectUploadController"
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-Settings = require('settings-sharelatex')
-
-module.exports =
- apply: (webRouter, apiRouter) ->
- webRouter.post '/project/new/upload',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: "project-upload"
- maxRequests: 20
- timeInterval: 60
- }),
- ProjectUploadController.multerMiddleware,
- ProjectUploadController.uploadProject
-
- webRouter.post '/Project/:Project_id/upload',
- RateLimiterMiddleware.rateLimit({
- endpointName: "file-upload"
- params: ["Project_id"]
- maxRequests: 200
- timeInterval: 60 * 30
- }),
- AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanWriteProjectContent,
- ProjectUploadController.multerMiddleware,
- ProjectUploadController.uploadFile
diff --git a/services/web/app/coffee/Features/User/ThirdPartyIdentityManager.coffee b/services/web/app/coffee/Features/User/ThirdPartyIdentityManager.coffee
deleted file mode 100644
index 9e5ad1ca2d..0000000000
--- a/services/web/app/coffee/Features/User/ThirdPartyIdentityManager.coffee
+++ /dev/null
@@ -1,91 +0,0 @@
-Errors = require "../Errors/Errors"
-User = require("../../models/User").User
-UserStub = require("../../models/UserStub").UserStub
-UserUpdater = require "./UserUpdater"
-_ = require "lodash"
-
-module.exports = ThirdPartyIdentityManager =
- getUser: (providerId, externalUserId, callback) ->
- return callback(new Error "invalid arguments") unless providerId? and externalUserId?
- query = ThirdPartyIdentityManager._getUserQuery providerId, externalUserId
- User.findOne query, (err, user) ->
- return callback err if err?
- return callback(new Errors.ThirdPartyUserNotFoundError()) unless user
- callback null, user
-
- login: (providerId, externalUserId, externalData, callback) ->
- ThirdPartyIdentityManager.getUser providerId, externalUserId, (err, user) ->
- return callback err if err?
- return callback(null, user) unless externalData
- query = ThirdPartyIdentityManager._getUserQuery providerId, externalUserId
- update = ThirdPartyIdentityManager._thirdPartyIdentifierUpdate user, providerId, externalUserId, externalData
- User.findOneAndUpdate query, update, {new: true}, callback
-
- # attempt to login normally but check for user stub if user not found
- loginUserStub: (providerId, externalUserId, externalData, callback) ->
- ThirdPartyIdentityManager.login providerId, externalUserId, externalData, (err, user) ->
- return callback null, user unless err?
- return callback err unless err.name == "ThirdPartyUserNotFoundError"
- query = ThirdPartyIdentityManager._getUserQuery providerId, externalUserId
- UserStub.findOne query, (err, userStub) ->
- return callback err if err?
- return callback(new Errors.ThirdPartyUserNotFoundError()) unless userStub
- return callback(null, userStub) unless externalData
- update = ThirdPartyIdentityManager._thirdPartyIdentifierUpdate userStub, providerId, externalUserId, externalData
- UserStub.findOneAndUpdate query, update, {new: true}, callback
-
- _getUserQuery: (providerId, externalUserId) ->
- externalUserId = externalUserId.toString()
- providerId = providerId.toString()
- query =
- "thirdPartyIdentifiers.externalUserId": externalUserId
- "thirdPartyIdentifiers.providerId": providerId
- return query
-
- _thirdPartyIdentifierUpdate: (user, providerId, externalUserId, externalData) ->
- providerId = providerId.toString()
- # get third party identifier object from array
- thirdPartyIdentifier = user.thirdPartyIdentifiers.find (tpi) ->
- tpi.externalUserId == externalUserId and tpi.providerId == providerId
- # do recursive merge of new data over existing data
- _.merge(thirdPartyIdentifier.externalData, externalData)
- update = "thirdPartyIdentifiers.$": thirdPartyIdentifier
- return update
-
- # register: () ->
- # this should be implemented once we move to having v2 as the master
- # but for now we need to register with v1 then call link once that
- # is complete
-
- link: (user_id, providerId, externalUserId, externalData, callback, retry) ->
- query =
- _id: user_id
- "thirdPartyIdentifiers.providerId": $ne: providerId
- update = $push: thirdPartyIdentifiers:
- externalUserId: externalUserId
- externalData: externalData
- providerId: providerId
- # add new tpi only if an entry for the provider does not exist
- UserUpdater.updateUser query, update, (err, res) ->
- return callback err if err?
- return callback null, res if res.nModified == 1
- # if already retried then throw error
- return callback(new Error "update failed") if retry
- # attempt to clear existing entry then retry
- ThirdPartyIdentityManager.unlink user_id, providerId, (err) ->
- return callback err if err?
- ThirdPartyIdentityManager.link user_id, providerId, externalUserId, externalData, callback, true
-
- unlink: (user_id, providerId, callback) ->
- update = $pull: thirdPartyIdentifiers:
- providerId: providerId
- UserUpdater.updateUser user_id, update, callback
-
- # attempt to unlink user but unlink user stub if not linked to user
- unlinkUserStub: (user_id, providerId, callback) ->
- ThirdPartyIdentityManager.unlink user_id, providerId, (err, res) ->
- return callback err if err?
- return callback null, res if res.nModified == 1
- update = $pull: thirdPartyIdentifiers:
- providerId: providerId
- UserStub.update { _id: user_id }, update, callback
diff --git a/services/web/app/coffee/Features/User/UserController.coffee b/services/web/app/coffee/Features/User/UserController.coffee
deleted file mode 100644
index ab78878e4e..0000000000
--- a/services/web/app/coffee/Features/User/UserController.coffee
+++ /dev/null
@@ -1,209 +0,0 @@
-UserHandler = require("./UserHandler")
-UserDeleter = require("./UserDeleter")
-UserGetter = require("./UserGetter")
-User = require("../../models/User").User
-newsLetterManager = require('../Newsletter/NewsletterManager')
-UserRegistrationHandler = require("./UserRegistrationHandler")
-logger = require("logger-sharelatex")
-metrics = require("metrics-sharelatex")
-Url = require("url")
-AuthenticationManager = require("../Authentication/AuthenticationManager")
-AuthenticationController = require('../Authentication/AuthenticationController')
-UserSessionsManager = require("./UserSessionsManager")
-UserUpdater = require("./UserUpdater")
-SudoModeHandler = require('../SudoMode/SudoModeHandler')
-settings = require "settings-sharelatex"
-Errors = require "../Errors/Errors"
-
-module.exports = UserController =
-
- tryDeleteUser: (req, res, next) ->
- UserController._tryDeleteUser(UserDeleter.deleteUser, req, res, next)
-
- trySoftDeleteUser: (req, res, next) ->
- UserController._tryDeleteUser(UserDeleter.softDeleteUser, req, res, next)
-
- _tryDeleteUser: (deleteMethod, req, res, next) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- password = req.body.password
- logger.log {user_id}, "trying to delete user account"
- if !password? or password == ''
- logger.err {user_id}, 'no password supplied for attempt to delete account'
- return res.sendStatus(403)
- AuthenticationManager.authenticate {_id: user_id}, password, (err, user) ->
- if err?
- logger.err {user_id}, 'error authenticating during attempt to delete account'
- return next(err)
- if !user
- logger.err {user_id}, 'auth failed during attempt to delete account'
- return res.sendStatus(403)
- deleteMethod user_id, (err) ->
- if err?
- if err instanceof Errors.SubscriptionAdminDeletionError
- return res.status(422).json(error: err.name)
- else
- logger.err {user_id}, "error while deleting user account"
- return next(err)
- sessionId = req.sessionID
- req.logout?()
- req.session.destroy (err) ->
- if err?
- logger.err err: err, 'error destorying session'
- return next(err)
- UserSessionsManager.untrackSession(user, sessionId)
- res.sendStatus(200)
-
- unsubscribe: (req, res)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- UserGetter.getUser user_id, (err, user)->
- newsLetterManager.unsubscribe user, ->
- res.send()
-
- updateUserSettings : (req, res)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log user_id: user_id, "updating account settings"
- User.findById user_id, (err, user)->
- if err? or !user?
- logger.err err:err, user_id:user_id, "problem updaing user settings"
- return res.sendStatus 500
-
- if req.body.first_name?
- user.first_name = req.body.first_name.trim()
- if req.body.last_name?
- user.last_name = req.body.last_name.trim()
- if req.body.role?
- user.role = req.body.role.trim()
- if req.body.institution?
- user.institution = req.body.institution.trim()
- if req.body.mode?
- user.ace.mode = req.body.mode
- if req.body.editorTheme?
- user.ace.theme = req.body.editorTheme
- if req.body.overallTheme?
- user.ace.overallTheme = req.body.overallTheme
- if req.body.fontSize?
- user.ace.fontSize = req.body.fontSize
- if req.body.autoComplete?
- user.ace.autoComplete = req.body.autoComplete
- if req.body.autoPairDelimiters?
- user.ace.autoPairDelimiters = req.body.autoPairDelimiters
- if req.body.spellCheckLanguage?
- user.ace.spellCheckLanguage = req.body.spellCheckLanguage
- if req.body.pdfViewer?
- user.ace.pdfViewer = req.body.pdfViewer
- if req.body.syntaxValidation?
- user.ace.syntaxValidation = req.body.syntaxValidation
- if req.body.fontFamily?
- user.ace.fontFamily = req.body.fontFamily
- if req.body.lineHeight?
- user.ace.lineHeight = req.body.lineHeight
-
- user.save (err)->
- newEmail = req.body.email?.trim().toLowerCase()
- if !newEmail? or newEmail == user.email or req.externalAuthenticationSystemUsed()
- # end here, don't update email
- AuthenticationController.setInSessionUser(req, {first_name: user.first_name, last_name: user.last_name})
- return res.sendStatus 200
- else if newEmail.indexOf("@") == -1
- # email invalid
- return res.sendStatus(400)
- else
- # update the user email
- UserUpdater.changeEmailAddress user_id, newEmail, (err)->
- if err?
- logger.err err:err, user_id:user_id, newEmail:newEmail, "problem updaing users email address"
- if err instanceof Errors.EmailExistsError
- message = req.i18n.translate("email_already_registered")
- else
- message = req.i18n.translate("problem_changing_email_address")
- return res.send 500, {message:message}
- User.findById user_id, (err, user)->
- if err?
- logger.err err:err, user_id:user_id, "error getting user for email update"
- return res.send 500
- AuthenticationController.setInSessionUser(req, {email: user.email, first_name: user.first_name, last_name: user.last_name})
- UserHandler.populateTeamInvites user, (err)-> #need to refresh this in the background
- if err?
- logger.err err:err, "error populateTeamInvites"
- res.sendStatus(200)
-
- _doLogout: (req, cb = (err) ->) ->
- metrics.inc "user.logout"
- user = AuthenticationController.getSessionUser(req)
- logger.log user: user, "logging out"
- sessionId = req.sessionID
- req.logout?() # passport logout
- req.session.destroy (err)->
- if err
- logger.err err: err, 'error destorying session'
- cb(err)
- if user?
- UserSessionsManager.untrackSession(user, sessionId)
- SudoModeHandler.clearSudoMode(user._id)
- cb()
-
- logout : (req, res, next)->
- UserController._doLogout req, (err) ->
- return next(err) if err?
- redirect_url = if settings.overleaf? then settings.overleaf.host + '/users/ensure_signed_out' else '/login'
- res.redirect redirect_url
-
- register : (req, res, next = (error) ->)->
- email = req.body.email
- if !email? or email == ""
- res.sendStatus 422 # Unprocessable Entity
- return
- UserRegistrationHandler.registerNewUserAndSendActivationEmail email, (error, user, setNewPasswordUrl) ->
- return next(error) if error?
- res.json {
- email: user.email
- setNewPasswordUrl: setNewPasswordUrl
- }
-
- clearSessions: (req, res, next = (error) ->) ->
- metrics.inc "user.clear-sessions"
- user = AuthenticationController.getSessionUser(req)
- logger.log {user_id: user._id}, "clearing sessions for user"
- UserSessionsManager.revokeAllUserSessions user, [req.sessionID], (err) ->
- return next(err) if err?
- res.sendStatus 201
-
- changePassword : (req, res, next = (error) ->)->
- metrics.inc "user.password-change"
- oldPass = req.body.currentPassword
- user_id = AuthenticationController.getLoggedInUserId(req)
- AuthenticationManager.authenticate {_id:user_id}, oldPass, (err, user)->
- return next(err) if err?
- if(user)
- logger.log user: user._id, "changing password"
- newPassword1 = req.body.newPassword1
- newPassword2 = req.body.newPassword2
- validationError = AuthenticationManager.validatePassword(newPassword1)
- if newPassword1 != newPassword2
- logger.log user: user, "passwords do not match"
- res.send
- message:
- type:'error'
- text:'Your passwords do not match'
- else if validationError?
- logger.log user: user, validationError.message
- res.send
- message:
- type: 'error'
- text: validationError.message
- else
- logger.log user: user, "password changed"
- AuthenticationManager.setUserPassword user._id, newPassword1, (error) ->
- return next(error) if error?
- UserSessionsManager.revokeAllUserSessions user, [req.sessionID], (err) ->
- return next(err) if err?
- res.send
- message:
- type:'success'
- text:'Your password has been changed'
- else
- logger.log user_id: user_id, "current password wrong"
- res.send
- message:
- type:'error'
- text:'Your old password is wrong'
diff --git a/services/web/app/coffee/Features/User/UserCreator.coffee b/services/web/app/coffee/Features/User/UserCreator.coffee
deleted file mode 100644
index 7624c57b87..0000000000
--- a/services/web/app/coffee/Features/User/UserCreator.coffee
+++ /dev/null
@@ -1,50 +0,0 @@
-User = require("../../models/User").User
-logger = require("logger-sharelatex")
-metrics = require('metrics-sharelatex')
-{ addAffiliation } = require("../Institutions/InstitutionsAPI")
-
-
-module.exports = UserCreator =
-
- createNewUser: (attributes, options, callback = (error, user) ->)->
- if arguments.length == 2
- callback = options
- options = {}
- logger.log user: attributes, "creating new user"
- user = new User()
-
- username = attributes.email.match(/^[^@]*/)
- if !attributes.first_name? or attributes.first_name == ""
- attributes.first_name = username[0]
-
- for key, value of attributes
- user[key] = value
-
- user.ace.syntaxValidation = true
- user.featureSwitches?.pdfng = true
- user.emails = [
- email: user.email
- createdAt: new Date()
- reversedHostname: user.email.split('@')[1].split('').reverse().join('')
- ]
-
- user.save (err)->
- callback(err, user)
-
- return if options?.skip_affiliation
- # call addaffiliation after the main callback so it runs in the
- # background. There is no guaranty this will run so we must no rely on it
- addAffiliation user._id, user.email, (error) ->
- if error
- logger.log { userId: user._id, email: user.email, error: error },
- "couldn't add affiliation for user on create"
- else
- logger.log { userId: user._id, email: user.email },
- "added affiliation for user on create"
-
-
-metrics.timeAsyncMethod(
- UserCreator, 'createNewUser',
- 'mongo.UserCreator',
- logger
-)
diff --git a/services/web/app/coffee/Features/User/UserDeleter.coffee b/services/web/app/coffee/Features/User/UserDeleter.coffee
deleted file mode 100644
index 1a604b5e54..0000000000
--- a/services/web/app/coffee/Features/User/UserDeleter.coffee
+++ /dev/null
@@ -1,80 +0,0 @@
-User = require("../../models/User").User
-NewsletterManager = require "../Newsletter/NewsletterManager"
-ProjectDeleter = require("../Project/ProjectDeleter")
-logger = require("logger-sharelatex")
-SubscriptionHandler = require("../Subscription/SubscriptionHandler")
-SubscriptionUpdater = require("../Subscription/SubscriptionUpdater")
-SubscriptionLocator = require("../Subscription/SubscriptionLocator")
-UserMembershipsHandler = require("../UserMembership/UserMembershipsHandler")
-async = require("async")
-InstitutionsAPI = require("../Institutions/InstitutionsAPI")
-Errors = require("../Errors/Errors")
-{db, ObjectId} = require("../../infrastructure/mongojs")
-
-module.exports = UserDeleter =
-
- softDeleteUserForMigration: (user_id, callback = (err)->)->
- if !user_id?
- logger.err "user_id is null when trying to delete user"
- return callback(new Error("no user_id"))
- User.findById user_id, (err, user)->
- return callback(err) if err?
- return callback(new Errors.NotFoundError("user not found")) unless user?
- async.series([
- (cb) ->
- UserDeleter._ensureCanDeleteUser user, cb
- (cb) ->
- UserDeleter._cleanupUser user, cb
- (cb) ->
- ProjectDeleter.deleteUsersProjects user._id, cb
- (cb) ->
- user.deletedAt = new Date()
- db.usersDeletedByMigration.insert user, cb
- (cb) ->
- user.remove cb
- ], callback)
-
- deleteUser: (user_id, callback = ()->)->
- if !user_id?
- logger.err "user_id is null when trying to delete user"
- return callback("no user_id")
- User.findById user_id, (err, user)->
- if err?
- return callback(err)
- logger.log user:user, "deleting user"
- async.series [
- (cb) ->
- UserDeleter._ensureCanDeleteUser user, cb
- (cb)->
- UserDeleter._cleanupUser user, cb
- (cb)->
- ProjectDeleter.deleteUsersProjects user._id, cb
- (cb)->
- user.remove cb
- ], (err)->
- if err?
- logger.err err:err, user_id:user_id, "something went wrong deleteing the user"
- callback err
-
- _cleanupUser: (user, callback) ->
- return callback(new Error("no user supplied")) unless user?
- async.series([
- (cb)->
- NewsletterManager.unsubscribe user, (err) ->
- logger.err("Failed to unsubscribe user from newsletter", user_id: user._id, error: err)
- cb()
- (cb)->
- SubscriptionHandler.cancelSubscription user, cb
- (cb)->
- InstitutionsAPI.deleteAffiliations user._id, cb
- (cb)->
- SubscriptionUpdater.removeUserFromAllGroups user._id, cb
- (cb)->
- UserMembershipsHandler.removeUserFromAllEntities user._id, cb
- ], callback)
-
- _ensureCanDeleteUser: (user, callback) ->
- SubscriptionLocator.getUsersSubscription user, (error, subscription) ->
- if subscription?
- error ||= new Errors.SubscriptionAdminDeletionError()
- callback(error)
diff --git a/services/web/app/coffee/Features/User/UserEmailsConfirmationHandler.coffee b/services/web/app/coffee/Features/User/UserEmailsConfirmationHandler.coffee
deleted file mode 100644
index d353165e4d..0000000000
--- a/services/web/app/coffee/Features/User/UserEmailsConfirmationHandler.coffee
+++ /dev/null
@@ -1,47 +0,0 @@
-EmailHelper = require "../Helpers/EmailHelper"
-EmailHandler = require "../Email/EmailHandler"
-OneTimeTokenHandler = require "../Security/OneTimeTokenHandler"
-settings = require 'settings-sharelatex'
-Errors = require "../Errors/Errors"
-logger = require "logger-sharelatex"
-UserUpdater = require "./UserUpdater"
-UserGetter = require "./UserGetter"
-
-ONE_YEAR_IN_S = 365 * 24 * 60 * 60
-
-module.exports = UserEmailsConfirmationHandler =
- sendConfirmationEmail: (user_id, email, emailTemplate, callback = (error) ->) ->
- if arguments.length == 3
- callback = emailTemplate
- emailTemplate = 'confirmEmail'
-
- # when force-migrating accounts to v2 from v1, we don't want to send confirmation messages -
- # setting this env var allows us to turn this behaviour off
- return callback(null) if process.env['SHARELATEX_NO_CONFIRMATION_MESSAGES']?
-
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- data = {user_id, email}
- OneTimeTokenHandler.getNewToken 'email_confirmation', data, {expiresIn: ONE_YEAR_IN_S}, (err, token)->
- return callback(err) if err?
- emailOptions =
- to: email
- confirmEmailUrl: "#{settings.siteUrl}/user/emails/confirm?token=#{token}"
- sendingUser_id: user_id
- EmailHandler.sendEmail emailTemplate, emailOptions, callback
-
- confirmEmailFromToken: (token, callback = (error) ->) ->
- logger.log {token_start: token.slice(0,8)}, 'confirming email from token'
- OneTimeTokenHandler.getValueFromTokenAndExpire 'email_confirmation', token, (error, data) ->
- return callback(error) if error?
- if !data?
- return callback(new Errors.NotFoundError('no token found'))
- {user_id, email} = data
- logger.log {data, user_id, email, token_start: token.slice(0,8)}, 'found data for email confirmation'
- if !user_id? or email != EmailHelper.parseEmail(email)
- return callback(new Errors.NotFoundError('invalid data'))
- UserGetter.getUser user_id, {}, (error, user) ->
- return callback(error) if error?
- unless user?._id
- return callback(new Errors.NotFoundError('user not found'))
- UserUpdater.confirmEmail user_id, email, callback
diff --git a/services/web/app/coffee/Features/User/UserEmailsController.coffee b/services/web/app/coffee/Features/User/UserEmailsController.coffee
deleted file mode 100644
index e37a0452e7..0000000000
--- a/services/web/app/coffee/Features/User/UserEmailsController.coffee
+++ /dev/null
@@ -1,112 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-UserGetter = require("./UserGetter")
-UserUpdater = require("./UserUpdater")
-EmailHelper = require("../Helpers/EmailHelper")
-UserEmailsConfirmationHandler = require "./UserEmailsConfirmationHandler"
-{ endorseAffiliation } = require("../Institutions/InstitutionsAPI")
-logger = require("logger-sharelatex")
-Errors = require "../Errors/Errors"
-
-module.exports = UserEmailsController =
-
- list: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- UserGetter.getUserFullEmails userId, (error, fullEmails) ->
- return next(error) if error?
- res.json fullEmails
-
-
- add: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- email = EmailHelper.parseEmail(req.body.email)
- return res.sendStatus 422 unless email?
-
- affiliationOptions =
- university: req.body.university
- role: req.body.role
- department: req.body.department
- UserUpdater.addEmailAddress userId, email, affiliationOptions, (error)->
- if error?
- return UserEmailsController._handleEmailError error, req, res, next
- UserEmailsConfirmationHandler.sendConfirmationEmail userId, email, (err) ->
- return next(error) if error?
- res.sendStatus 204
-
-
- remove: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- email = EmailHelper.parseEmail(req.body.email)
- return res.sendStatus 422 unless email?
-
- UserUpdater.removeEmailAddress userId, email, (error)->
- return next(error) if error?
- res.sendStatus 200
-
-
- setDefault: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- email = EmailHelper.parseEmail(req.body.email)
- return res.sendStatus 422 unless email?
-
- UserUpdater.updateV1AndSetDefaultEmailAddress userId, email, (error)->
- if error?
- return UserEmailsController._handleEmailError error, req, res, next
- else
- return res.sendStatus 200
-
-
- endorse: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- email = EmailHelper.parseEmail(req.body.email)
- return res.sendStatus 422 unless email?
-
- endorseAffiliation userId, email, req.body.role, req.body.department, (error)->
- return next(error) if error?
- res.sendStatus 204
-
- resendConfirmation: (req, res, next) ->
- userId = AuthenticationController.getLoggedInUserId(req)
- email = EmailHelper.parseEmail(req.body.email)
- return res.sendStatus 422 unless email?
- UserGetter.getUserByAnyEmail email, {_id:1}, (error, user) ->
- return next(error) if error?
- if !user? or user?._id?.toString() != userId
- logger.log {userId, email, foundUserId: user?._id}, "email doesn't match logged in user"
- return res.sendStatus 422
- logger.log {userId, email}, 'resending email confirmation token'
- UserEmailsConfirmationHandler.sendConfirmationEmail userId, email, (error) ->
- return next(error) if error?
- res.sendStatus 200
-
- showConfirm: (req, res, next) ->
- res.render 'user/confirm_email', {
- token: req.query.token,
- title: 'confirm_email'
- }
-
- confirm: (req, res, next) ->
- token = req.body.token
- if !token?
- return res.sendStatus 422
- UserEmailsConfirmationHandler.confirmEmailFromToken token, (error) ->
- if error?
- if error instanceof Errors.NotFoundError
- res.status(404).json({
- message: 'Sorry, your confirmation token is invalid or has expired. Please request a new email confirmation link.'
- })
- else
- next(error)
- else
- res.sendStatus 200
-
- _handleEmailError: (error, req, res, next) ->
- if error instanceof Errors.UnconfirmedEmailError
- return res.status(409).json {
- message: 'email must be confirmed'
- }
- else if error instanceof Errors.EmailExistsError
- return res.status(409).json {
- message: req.i18n.translate("email_already_registered")
- }
- else
- return next(error)
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/User/UserGetter.coffee b/services/web/app/coffee/Features/User/UserGetter.coffee
deleted file mode 100644
index e7d78fd747..0000000000
--- a/services/web/app/coffee/Features/User/UserGetter.coffee
+++ /dev/null
@@ -1,124 +0,0 @@
-mongojs = require("../../infrastructure/mongojs")
-metrics = require('metrics-sharelatex')
-logger = require('logger-sharelatex')
-db = mongojs.db
-ObjectId = mongojs.ObjectId
-{ getUserAffiliations } = require("../Institutions/InstitutionsAPI")
-Errors = require("../Errors/Errors")
-
-module.exports = UserGetter =
- getUser: (query, projection, callback = (error, user) ->) ->
- return callback(new Error("no query provided")) unless query?
- if query?.email?
- return callback(new Error("Don't use getUser to find user by email"), null)
- if arguments.length == 2
- callback = projection
- projection = {}
- if typeof query == "string"
- try
- query = _id: ObjectId(query)
- catch e
- return callback(null, null)
- else if query instanceof ObjectId
- query = _id: query
-
- db.users.findOne query, projection, callback
-
- getUserEmail: (userId, callback = (error, email) ->) ->
- @getUser userId, { email: 1 }, (error, user) ->
- callback(error, user?.email)
-
- getUserFullEmails: (userId, callback = (error, emails) ->) ->
- @getUser userId, { email: 1, emails: 1 }, (error, user) ->
- return callback error if error?
- return callback new Error('User not Found') unless user
-
- getUserAffiliations userId, (error, affiliationsData) ->
- return callback error if error?
- callback null, decorateFullEmails(user.email, user.emails or [], affiliationsData)
-
- getUserByMainEmail: (email, projection, callback = (error, user) ->) ->
- email = email.trim()
- if arguments.length == 2
- callback = projection
- projection = {}
- db.users.findOne email: email, projection, callback
-
- getUserByAnyEmail: (email, projection, callback = (error, user) ->) ->
- email = email.trim()
- if arguments.length == 2
- callback = projection
- projection = {}
- # $exists: true MUST be set to use the partial index
- query = emails: { $exists: true }, 'emails.email': email
- db.users.findOne query, projection, (error, user) =>
- return callback(error, user) if error? or user?
-
- # While multiple emails are being rolled out, check for the main email as
- # well
- @getUserByMainEmail email, projection, callback
-
- getUsersByAnyConfirmedEmail: (emails, projection, callback = (error, user) ->) ->
- if arguments.length == 2
- callback = projection
- projection = {}
- # $exists: true MUST be set to use the partial index
- query = emails: { $exists: true, $elemMatch: { email: { $in: emails }, confirmedAt: { $exists: true }}}
- db.users.find query, projection, (error, users) =>
- callback(error, users)
-
- getUsersByHostname: (hostname, projection, callback = (error, users) ->) ->
- reversedHostname = hostname.trim().split('').reverse().join('')
- query = emails: { $exists: true }, 'emails.reversedHostname': reversedHostname
- db.users.find query, projection, callback
-
- getUsers: (user_ids, projection, callback = (error, users) ->) ->
- try
- user_ids = user_ids.map (u) -> ObjectId(u.toString())
- catch error
- return callback error
-
- db.users.find { _id: { $in: user_ids} }, projection, callback
-
- getUserOrUserStubById: (user_id, projection, callback = (error, user, isStub) ->) ->
- try
- query = _id: ObjectId(user_id.toString())
- catch e
- return callback(new Error(e))
- db.users.findOne query, projection, (error, user) ->
- return callback(error) if error?
- return callback(null, user, false) if user?
- db.userstubs.findOne query, projection, (error, user) ->
- return callback(error) if error
- return callback() if !user?
- callback(null, user, true)
-
- # check for duplicate email address. This is also enforced at the DB level
- ensureUniqueEmailAddress: (newEmail, callback) ->
- @getUserByAnyEmail newEmail, (error, user) ->
- return callback(new Errors.EmailExistsError('alread_exists')) if user?
- callback(error)
-
-decorateFullEmails = (defaultEmail, emailsData, affiliationsData) ->
- emailsData.map (emailData) ->
- emailData.default = emailData.email == defaultEmail
-
- affiliation = affiliationsData.find (aff) -> aff.email == emailData.email
- if affiliation?
- { institution, inferred, role, department } = affiliation
- emailData.affiliation = { institution, inferred, role, department }
- else
- emailsData.affiliation = null
-
- emailData
-
-[
- 'getUser',
- 'getUserEmail',
- 'getUserByMainEmail',
- 'getUserByAnyEmail',
- 'getUsers',
- 'getUserOrUserStubById',
- 'ensureUniqueEmailAddress',
-].map (method) ->
- metrics.timeAsyncMethod UserGetter, method, 'mongo.UserGetter', logger
diff --git a/services/web/app/coffee/Features/User/UserHandler.coffee b/services/web/app/coffee/Features/User/UserHandler.coffee
deleted file mode 100644
index b3e62f79a0..0000000000
--- a/services/web/app/coffee/Features/User/UserHandler.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-TeamInvitesHandler = require("../Subscription/TeamInvitesHandler")
-
-module.exports = UserHandler =
- populateTeamInvites: (user, callback) ->
- TeamInvitesHandler.createTeamInvitesForLegacyInvitedEmail(user.email, callback)
-
- setupLoginData: (user, callback = ->)->
- @populateTeamInvites user, callback
diff --git a/services/web/app/coffee/Features/User/UserInfoController.coffee b/services/web/app/coffee/Features/User/UserInfoController.coffee
deleted file mode 100644
index 659c17416a..0000000000
--- a/services/web/app/coffee/Features/User/UserInfoController.coffee
+++ /dev/null
@@ -1,49 +0,0 @@
-UserGetter = require "./UserGetter"
-logger = require("logger-sharelatex")
-UserDeleter = require("./UserDeleter")
-UserUpdater = require("./UserUpdater")
-sanitize = require('sanitizer')
-AuthenticationController = require('../Authentication/AuthenticationController')
-ObjectId = require("mongojs").ObjectId
-
-module.exports = UserController =
- getLoggedInUsersPersonalInfo: (req, res, next = (error) ->) ->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log user_id: user_id, "reciving request for getting logged in users personal info"
- return next(new Error("User is not logged in")) if !user_id?
- UserGetter.getUser user_id, {
- first_name: true, last_name: true,
- role:true, institution:true,
- email: true, signUpDate: true
- }, (error, user) ->
- return next(error) if error?
- UserController.sendFormattedPersonalInfo(user, res, next)
-
- getPersonalInfo: (req, res, next = (error) ->) ->
- {user_id} = req.params
-
- if /^\d+$/.test(user_id)
- query = { "overleaf.id": parseInt(user_id, 10) }
- else if /^[a-f0-9]{24}$/.test(user_id)
- query = { _id: ObjectId(user_id) }
- else
- return res.send(400)
-
- UserGetter.getUser query, { _id: true, first_name: true, last_name: true, email: true}, (error, user) ->
- logger.log user_id: req.params.user_id, "receiving request for getting users personal info"
- return next(error) if error?
- return res.send(404) if !user?
- UserController.sendFormattedPersonalInfo(user, res, next)
-
- sendFormattedPersonalInfo: (user, res, next = (error) ->) ->
- info = UserController.formatPersonalInfo(user)
- res.json info
-
- formatPersonalInfo: (user, callback = (error, info) ->) ->
- if !user?
- return {}
- formatted_user = { id: user._id.toString() }
- for key in ["first_name", "last_name", "email", "signUpDate", "role", "institution"]
- if user[key]?
- formatted_user[key] = user[key]
- return formatted_user
diff --git a/services/web/app/coffee/Features/User/UserInfoManager.coffee b/services/web/app/coffee/Features/User/UserInfoManager.coffee
deleted file mode 100644
index 90971e31a5..0000000000
--- a/services/web/app/coffee/Features/User/UserInfoManager.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-UserGetter = require "./UserGetter"
-
-module.exports = UserInfoManager =
- getPersonalInfo: (user_id, callback = (error) ->) ->
- UserGetter.getUser user_id, { _id: true, first_name: true, last_name: true, email: true }, callback
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/User/UserPagesController.coffee b/services/web/app/coffee/Features/User/UserPagesController.coffee
deleted file mode 100644
index 70bda3596d..0000000000
--- a/services/web/app/coffee/Features/User/UserPagesController.coffee
+++ /dev/null
@@ -1,135 +0,0 @@
-UserGetter = require("./UserGetter")
-UserSessionsManager = require("./UserSessionsManager")
-ErrorController = require("../Errors/ErrorController")
-logger = require("logger-sharelatex")
-Settings = require("settings-sharelatex")
-request = require 'request'
-fs = require('fs')
-AuthenticationController = require('../Authentication/AuthenticationController')
-
-module.exports = UserPagesController =
-
- registerPage : (req, res)->
- sharedProjectData =
- project_name:req.query.project_name
- user_first_name:req.query.user_first_name
-
- newTemplateData = {}
- if req.session.templateData?
- newTemplateData.templateName = req.session.templateData.templateName
-
- res.render 'user/register',
- title: 'register'
- sharedProjectData: sharedProjectData
- newTemplateData: newTemplateData
- new_email:req.query.new_email || ""
-
- activateAccountPage: (req, res) ->
- # An 'activation' is actually just a password reset on an account that
- # was set with a random password originally.
- logger.log query:req.query, "activiate account page called"
- if !req.query?.user_id? or !req.query?.token?
- return ErrorController.notFound(req, res)
-
- UserGetter.getUser req.query.user_id, {email: 1, loginCount: 1}, (error, user) ->
- return next(error) if error?
- if !user
- return ErrorController.notFound(req, res)
- if user.loginCount > 0
- logger.log user:user, "user has already logged in so is active, sending them to /login"
- # Already seen this user, so account must be activate
- # This lets users keep clicking the 'activate' link in their email
- # as a way to log in which, if I know our users, they will.
- res.redirect "/login?email=#{encodeURIComponent(user.email)}"
- else
- res.render 'user/activate',
- title: 'activate_account'
- email: user.email,
- token: req.query.token
-
- loginPage : (req, res)->
- # if user is being sent to /login with explicit redirect (redir=/foo),
- # such as being sent from the editor to /login, then set the redirect explicitly
- if req.query.redir? and !AuthenticationController._getRedirectFromSession(req)?
- logger.log {redir: req.query.redir}, "setting explicit redirect from login page"
- AuthenticationController.setRedirectInSession(req, req.query.redir)
- res.render 'user/login',
- title: 'login',
- email: req.query.email
-
- logoutPage: (req, res) ->
- res.render 'user/logout'
-
- renderReconfirmAccountPage: (req, res) ->
- page_data = {
- reconfirm_email: req?.session?.reconfirm_email
- }
- # when a user must reconfirm their account
- res.render 'user/reconfirm', page_data
-
- settingsPage : (req, res, next)->
- user_id = AuthenticationController.getLoggedInUserId(req)
- logger.log user: user_id, "loading settings page"
- shouldAllowEditingDetails = !(Settings?.ldap?.updateUserDetailsOnLogin) and !(Settings?.saml?.updateUserDetailsOnLogin)
- oauthProviders = Settings.oauthProviders || {}
-
- UserGetter.getUser user_id, (err, user)->
- return next(err) if err?
-
- UserPagesController._hasPassword user, (err, passwordPresent) ->
- if err
- logger.err {err}, "error getting password status from v1"
- res.render 'user/settings',
- title:'account_settings'
- user: user,
- hasPassword: passwordPresent,
- shouldAllowEditingDetails: shouldAllowEditingDetails
- languages: Settings.languages,
- accountSettingsTabActive: true,
- oauthProviders: UserPagesController._translateProviderDescriptions(oauthProviders, req),
- thirdPartyIds: UserPagesController._restructureThirdPartyIds(user),
- previewOauth: req.query.prvw?
-
- sessionsPage: (req, res, next) ->
- user = AuthenticationController.getSessionUser(req)
- logger.log user_id: user._id, "loading sessions page"
- UserSessionsManager.getAllUserSessions user, [req.sessionID], (err, sessions) ->
- if err?
- logger.err {user_id: user._id}, "error getting all user sessions"
- return next(err)
- res.render 'user/sessions',
- title: "sessions"
- sessions: sessions
-
- _hasPassword: (user, callback) ->
- request.get {
- url: "#{Settings.apis.v1.url}/api/v1/sharelatex/has_password"
- auth: { user: Settings.apis.v1.user, pass: Settings.apis.v1.pass }
- body: { user_id: user?.overleaf?.id }
- timeout: 20 * 1000
- json: true
- }, (err, response, body) ->
- if err
- # for errors assume password and show password setting form
- return callback(err, true)
- else if body?.has_password
- return callback(err, true)
- return callback(err, false)
-
- _restructureThirdPartyIds: (user) ->
- # 3rd party identifiers are an array of objects
- # this turn them into a single object, which
- # makes data easier to use in template
- return null if !user.thirdPartyIdentifiers || user.thirdPartyIdentifiers.length == 0
- user.thirdPartyIdentifiers.reduce (obj, identifier) ->
- obj[identifier.providerId] = identifier.externalUserId
- obj
- , {}
-
- _translateProviderDescriptions: (providers, req) ->
- result = {}
- if providers
- for provider, data of providers
- data.description = req.i18n.translate(data.descriptionKey, data.descriptionOptions)
- result[provider] = data
- return result
\ No newline at end of file
diff --git a/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee b/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee
deleted file mode 100644
index 52d731c4bc..0000000000
--- a/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee
+++ /dev/null
@@ -1,84 +0,0 @@
-User = require("../../models/User").User
-UserCreator = require("./UserCreator")
-UserGetter = require("./UserGetter")
-AuthenticationManager = require("../Authentication/AuthenticationManager")
-NewsLetterManager = require("../Newsletter/NewsletterManager")
-async = require("async")
-logger = require("logger-sharelatex")
-crypto = require("crypto")
-EmailHandler = require("../Email/EmailHandler")
-OneTimeTokenHandler = require "../Security/OneTimeTokenHandler"
-Analytics = require "../Analytics/AnalyticsManager"
-settings = require "settings-sharelatex"
-EmailHelper = require("../Helpers/EmailHelper")
-
-module.exports = UserRegistrationHandler =
- _registrationRequestIsValid : (body, callback)->
- invalidEmail = AuthenticationManager.validateEmail(body.email or '')
- invalidPassword = AuthenticationManager.validatePassword(body.password or '')
- if invalidEmail? or invalidPassword?
- return false
- else
- return true
-
- _createNewUserIfRequired: (user, userDetails, callback)->
- if !user?
- userDetails.holdingAccount = false
- UserCreator.createNewUser {holdingAccount:false, email:userDetails.email, first_name:userDetails.first_name, last_name:userDetails.last_name}, callback
- else
- callback null, user
-
- registerNewUser: (userDetails, callback)->
- self = @
- requestIsValid = @_registrationRequestIsValid userDetails
- if !requestIsValid
- return callback(new Error("request is not valid"))
- userDetails.email = EmailHelper.parseEmail(userDetails.email)
- UserGetter.getUserByAnyEmail userDetails.email, (err, user) =>
- if err?
- return callback err
- if user?.holdingAccount == false
- return callback(new Error("EmailAlreadyRegistered"), user)
- self._createNewUserIfRequired user, userDetails, (err, user)->
- if err?
- return callback(err)
- async.series [
- (cb)-> User.update {_id: user._id}, {"$set":{holdingAccount:false}}, cb
- (cb)-> AuthenticationManager.setUserPassword user._id, userDetails.password, cb
- (cb)->
- if userDetails.subscribeToNewsletter == "true"
- NewsLetterManager.subscribe user, ->
- cb() #this can be slow, just fire it off
- ], (err)->
- logger.log user: user, "registered"
- Analytics.recordEvent user._id, "user-registered"
- callback(err, user)
-
- registerNewUserAndSendActivationEmail: (email, callback = (error, user, setNewPasswordUrl) ->) ->
- logger.log {email}, "registering new user"
- UserRegistrationHandler.registerNewUser {
- email: email
- password: crypto.randomBytes(32).toString("hex")
- }, (err, user)->
- if err? and err?.message != "EmailAlreadyRegistered"
- return callback(err)
-
- if err?.message == "EmailAlreadyRegistered"
- logger.log {email}, "user already exists, resending welcome email"
-
- ONE_WEEK = 7 * 24 * 60 * 60 # seconds
- OneTimeTokenHandler.getNewToken 'password', user._id, { expiresIn: ONE_WEEK }, (err, token)->
- return callback(err) if err?
-
- setNewPasswordUrl = "#{settings.siteUrl}/user/activate?token=#{token}&user_id=#{user._id}"
-
- EmailHandler.sendEmail "registered", {
- to: user.email
- setNewPasswordUrl: setNewPasswordUrl
- }, () ->
-
- callback null, user, setNewPasswordUrl
-
-
-
-
diff --git a/services/web/app/coffee/Features/User/UserSessionsManager.coffee b/services/web/app/coffee/Features/User/UserSessionsManager.coffee
deleted file mode 100644
index 57590a42b4..0000000000
--- a/services/web/app/coffee/Features/User/UserSessionsManager.coffee
+++ /dev/null
@@ -1,157 +0,0 @@
-Settings = require('settings-sharelatex')
-logger = require("logger-sharelatex")
-Async = require('async')
-_ = require('underscore')
-UserSessionsRedis = require('./UserSessionsRedis')
-rclient = UserSessionsRedis.client()
-
-module.exports = UserSessionsManager =
- # mimic the key used by the express sessions
- _sessionKey: (sessionId) ->
- return "sess:#{sessionId}"
-
- trackSession: (user, sessionId, callback=(err)-> ) ->
- if !user?
- logger.log {sessionId}, "no user to track, returning"
- return callback(null)
- if !sessionId?
- logger.log {user_id: user._id}, "no sessionId to track, returning"
- return callback(null)
- logger.log {user_id: user._id, sessionId}, "onLogin handler"
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- value = UserSessionsManager._sessionKey sessionId
- rclient.multi()
- .sadd(sessionSetKey, value)
- .expire(sessionSetKey, "#{Settings.cookieSessionLength}")
- .exec (err, response) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "error while adding session key to UserSessions set"
- return callback(err)
- UserSessionsManager._checkSessions(user, () ->)
- callback()
-
- untrackSession: (user, sessionId, callback=(err)-> ) ->
- if !user?
- logger.log {sessionId}, "no user to untrack, returning"
- return callback(null)
- if !sessionId?
- logger.log {user_id: user._id}, "no sessionId to untrack, returning"
- return callback(null)
- logger.log {user_id: user._id, sessionId}, "onLogout handler"
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- value = UserSessionsManager._sessionKey sessionId
- rclient.multi()
- .srem(sessionSetKey, value)
- .expire(sessionSetKey, "#{Settings.cookieSessionLength}")
- .exec (err, response) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "error while removing session key from UserSessions set"
- return callback(err)
- UserSessionsManager._checkSessions(user, () ->)
- callback()
-
- getAllUserSessions: (user, exclude, callback=(err, sessionKeys)->) ->
- exclude = _.map(exclude, UserSessionsManager._sessionKey)
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- rclient.smembers sessionSetKey, (err, sessionKeys) ->
- if err?
- logger.err user_id: user._id, "error getting all session keys for user from redis"
- return callback(err)
- sessionKeys = _.filter sessionKeys, (k) -> !(_.contains(exclude, k))
- if sessionKeys.length == 0
- logger.log {user_id: user._id}, "no other sessions found, returning"
- return callback(null, [])
-
- Async.mapSeries sessionKeys, ((k, cb) -> rclient.get(k, cb)), (err, sessions) ->
- if err?
- logger.err {user_id: user._id}, "error getting all sessions for user from redis"
- return callback(err)
-
- result = []
- for session in sessions
- if session is null
- continue
- session = JSON.parse(session)
- session_user = session?.user or session?.passport?.user
- result.push {
- ip_address: session_user.ip_address,
- session_created: session_user.session_created
- }
-
- return callback(null, result)
-
- revokeAllUserSessions: (user, retain, callback=(err)->) ->
- if !retain?
- retain = []
- retain = retain.map((i) -> UserSessionsManager._sessionKey(i))
- if !user?
- logger.log {}, "no user to revoke sessions for, returning"
- return callback(null)
- logger.log {user_id: user._id}, "revoking all existing sessions for user"
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- rclient.smembers sessionSetKey, (err, sessionKeys) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "error getting contents of UserSessions set"
- return callback(err)
- keysToDelete = _.filter(sessionKeys, (k) -> k not in retain)
- if keysToDelete.length == 0
- logger.log {user_id: user._id}, "no sessions in UserSessions set to delete, returning"
- return callback(null)
- logger.log {user_id: user._id, count: keysToDelete.length}, "deleting sessions for user"
-
- deletions = keysToDelete.map (k) ->
- (cb) ->
- rclient.del k, cb
-
- Async.series deletions, (err, _result) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "errror revoking all sessions for user"
- return callback(err)
- rclient.srem sessionSetKey, keysToDelete, (err) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "error removing session set for user"
- return callback(err)
- callback(null)
-
- touch: (user, callback=(err)->) ->
- if !user?
- logger.log {}, "no user to touch sessions for, returning"
- return callback(null)
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- rclient.expire sessionSetKey, "#{Settings.cookieSessionLength}", (err, response) ->
- if err?
- logger.err {err, user_id: user._id}, "error while updating ttl on UserSessions set"
- return callback(err)
- callback(null)
-
- _checkSessions: (user, callback=(err)->) ->
- if !user?
- logger.log {}, "no user, returning"
- return callback(null)
- logger.log {user_id: user._id}, "checking sessions for user"
- sessionSetKey = UserSessionsRedis.sessionSetKey(user)
- rclient.smembers sessionSetKey, (err, sessionKeys) ->
- if err?
- logger.err {err, user_id: user._id, sessionSetKey}, "error getting contents of UserSessions set"
- return callback(err)
- logger.log {user_id: user._id, count: sessionKeys.length}, "checking sessions for user"
- Async.series(
- sessionKeys.map(
- (key) ->
- (next) ->
- rclient.get key, (err, val) ->
- if err?
- return next(err)
- if !val?
- logger.log {user_id: user._id, key}, ">> removing key from UserSessions set"
- rclient.srem sessionSetKey, key, (err, result) ->
- if err?
- return next(err)
- return next(null)
- else
- next()
- )
- , (err, results) ->
- logger.log {user_id: user._id}, "done checking sessions for user"
- return callback(err)
- )
diff --git a/services/web/app/coffee/Features/User/UserSessionsRedis.coffee b/services/web/app/coffee/Features/User/UserSessionsRedis.coffee
deleted file mode 100644
index 0c460b4604..0000000000
--- a/services/web/app/coffee/Features/User/UserSessionsRedis.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-RedisWrapper = require("../../infrastructure/RedisWrapper")
-rclient = RedisWrapper.client("websessions")
-
-module.exports = Redis =
- client: () ->
- return rclient
-
- sessionSetKey: (user) ->
- return "UserSessions:{#{user._id}}"
diff --git a/services/web/app/coffee/Features/User/UserUpdater.coffee b/services/web/app/coffee/Features/User/UserUpdater.coffee
deleted file mode 100644
index 05e37b9870..0000000000
--- a/services/web/app/coffee/Features/User/UserUpdater.coffee
+++ /dev/null
@@ -1,203 +0,0 @@
-logger = require("logger-sharelatex")
-mongojs = require("../../infrastructure/mongojs")
-metrics = require("metrics-sharelatex")
-db = mongojs.db
-async = require("async")
-ObjectId = mongojs.ObjectId
-UserGetter = require("./UserGetter")
-{ addAffiliation, removeAffiliation } = require("../Institutions/InstitutionsAPI")
-FeaturesUpdater = require("../Subscription/FeaturesUpdater")
-EmailHelper = require "../Helpers/EmailHelper"
-Errors = require "../Errors/Errors"
-Settings = require "settings-sharelatex"
-request = require 'request'
-NewsletterManager = require "../Newsletter/NewsletterManager"
-
-module.exports = UserUpdater =
- updateUser: (query, update, callback = (error) ->) ->
- if typeof query == "string"
- query = _id: ObjectId(query)
- else if query instanceof ObjectId
- query = _id: query
- else if typeof query._id == "string"
- query._id = ObjectId(query._id)
-
- db.users.update query, update, callback
-
-
- #
- # DEPRECATED
- #
- # Change the user's main email address by adding a new email, switching the
- # default email and removing the old email. Prefer manipulating multiple
- # emails and the default rather than calling this method directly
- #
- changeEmailAddress: (userId, newEmail, callback)->
- newEmail = EmailHelper.parseEmail(newEmail)
- return callback(new Error('invalid email')) if !newEmail?
- logger.log userId: userId, newEmail: newEmail, "updaing email address of user"
-
- oldEmail = null
- async.series [
- (cb) ->
- UserGetter.getUserEmail userId, (error, email) ->
- oldEmail = email
- cb(error)
- (cb) -> UserUpdater.addEmailAddress userId, newEmail, cb
- (cb) -> UserUpdater.setDefaultEmailAddress userId, newEmail, cb
- (cb) -> UserUpdater.removeEmailAddress userId, oldEmail, cb
- ], callback
-
-
- # Add a new email address for the user. Email cannot be already used by this
- # or any other user
- addEmailAddress: (userId, newEmail, affiliationOptions, callback) ->
- unless callback? # affiliationOptions is optional
- callback = affiliationOptions
- affiliationOptions = {}
- newEmail = EmailHelper.parseEmail(newEmail)
- return callback(new Error('invalid email')) if !newEmail?
-
- UserGetter.ensureUniqueEmailAddress newEmail, (error) =>
- return callback(error) if error?
-
- addAffiliation userId, newEmail, affiliationOptions, (error) =>
- if error?
- logger.err error: error, 'problem adding affiliation while adding email'
- return callback(error)
-
- reversedHostname = newEmail.split('@')[1].split('').reverse().join('')
- update = $push: emails: email: newEmail, createdAt: new Date(), reversedHostname: reversedHostname
- @updateUser userId, update, (error) ->
- if error?
- logger.err error: error, 'problem updating users emails'
- return callback(error)
- callback()
-
-
- # remove one of the user's email addresses. The email cannot be the user's
- # default email address
- removeEmailAddress: (userId, email, callback) ->
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- removeAffiliation userId, email, (error) =>
- if error?
- logger.err error: error, 'problem removing affiliation'
- return callback(error)
-
- query = _id: userId, email: $ne: email
- update = $pull: emails: email: email
- @updateUser query, update, (error, res) ->
- if error?
- logger.err error:error, 'problem removing users email'
- return callback(error)
- if res.n == 0
- return callback(new Error('Cannot remove email'))
- callback()
-
-
- # set the default email address by setting the `email` attribute. The email
- # must be one of the user's multiple emails (`emails` attribute)
- setDefaultEmailAddress: (userId, email, callback) ->
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- UserGetter.getUserEmail userId, (error, oldEmail) =>
- if err?
- return callback(error)
- query = _id: userId, 'emails.email': email
- update = $set: email: email
- @updateUser query, update, (error, res) ->
- if error?
- logger.err error:error, 'problem setting default emails'
- return callback(error)
- else if res.n == 0 # TODO: Check n or nMatched?
- return callback(new Error('Default email does not belong to user'))
- else
- NewsletterManager.changeEmail oldEmail, email, ->
- callback()
-
-
-
- updateV1AndSetDefaultEmailAddress: (userId, email, callback) ->
- @updateEmailAddressInV1 userId, email, (error) =>
- return callback(error) if error?
- @setDefaultEmailAddress userId, email, callback
-
- updateEmailAddressInV1: (userId, newEmail, callback) ->
- if !Settings.apis?.v1?.url?
- return callback()
- UserGetter.getUser userId, { 'overleaf.id': 1, emails: 1 }, (error, user) ->
- return callback(error) if error?
- return callback(new Errors.NotFoundError('no user found')) if !user?
- if !user.overleaf?.id?
- return callback()
- newEmailIsConfirmed = false
- for email in user.emails
- if email.email == newEmail and email.confirmedAt?
- newEmailIsConfirmed = true
- break
- if !newEmailIsConfirmed
- return callback(new Errors.UnconfirmedEmailError("can't update v1 with unconfirmed email"))
- request {
- baseUrl: Settings.apis.v1.url
- url: "/api/v1/sharelatex/users/#{user.overleaf.id}/email"
- method: 'PUT'
- auth:
- user: Settings.apis.v1.user
- pass: Settings.apis.v1.pass
- sendImmediately: true
- json:
- user:
- email: newEmail
- timeout: 5 * 1000
- }, (error, response, body) ->
- if error?
- error = new Errors.V1ConnectionError('No V1 connection') if error.code == 'ECONNREFUSED'
- return callback(error)
- if response.statusCode == 409 # Conflict
- return callback(new Errors.EmailExistsError('email exists in v1'))
- else if 200 <= response.statusCode < 300
- return callback()
- else
- return callback new Error("non-success code from v1: #{response.statusCode}")
-
- confirmEmail: (userId, email, confirmedAt, callback) ->
- if arguments.length == 3
- callback = confirmedAt
- confirmedAt = new Date()
- email = EmailHelper.parseEmail(email)
- return callback(new Error('invalid email')) if !email?
- logger.log {userId, email}, 'confirming user email'
- addAffiliation userId, email, {confirmedAt: confirmedAt}, (error) =>
- if error?
- logger.err error: error, 'problem adding affiliation while confirming email'
- return callback(error)
-
- query =
- _id: userId
- 'emails.email': email
- update =
- $set:
- 'emails.$.confirmedAt': confirmedAt
- @updateUser query, update, (error, res) ->
- return callback(error) if error?
- logger.log {res, userId, email}, "tried to confirm email"
- if res.n == 0
- return callback(new Errors.NotFoundError('user id and email do no match'))
- FeaturesUpdater.refreshFeatures userId, true, callback
-
- removeReconfirmFlag: (user_id, callback) ->
- UserUpdater.updateUser user_id.toString(), {
- $set: { "must_reconfirm": false }
- }, (error) ->
- callback(error)
-
-[
- 'updateUser'
- 'changeEmailAddress'
- 'setDefaultEmailAddress'
- 'addEmailAddress'
- 'removeEmailAddress'
- 'removeReconfirmFlag'
-].map (method) ->
- metrics.timeAsyncMethod(UserUpdater, method, 'mongo.UserUpdater', logger)
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipAuthorization.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipAuthorization.coffee
deleted file mode 100644
index 5273942714..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipAuthorization.coffee
+++ /dev/null
@@ -1,125 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
-UserMembershipHandler = require('./UserMembershipHandler')
-EntityConfigs = require('./UserMembershipEntityConfigs')
-Errors = require('../Errors/Errors')
-logger = require("logger-sharelatex")
-settings = require 'settings-sharelatex'
-request = require 'request'
-
-module.exports = UserMembershipAuthorization =
- requireTeamMetricsAccess: (req, res, next) ->
- requireAccessToEntity('team', req.params.id, req, res, next, 'groupMetrics')
-
- requireGroupManagementAccess: (req, res, next) ->
- requireAccessToEntity('group', req.params.id, req, res, next, 'groupManagement')
-
- requireGroupMetricsAccess: (req, res, next) ->
- requireAccessToEntity('group', req.params.id, req, res, next, 'groupMetrics')
-
- requireGroupManagersManagementAccess: (req, res, next) ->
- requireAccessToEntity('groupManagers', req.params.id, req, res, next, 'groupManagement')
-
- requireInstitutionMetricsAccess: (req, res, next) ->
- requireAccessToEntity('institution', req.params.id, req, res, next, 'institutionMetrics')
-
- requireInstitutionManagementAccess: (req, res, next) ->
- requireAccessToEntity('institution', req.params.id, req, res, next, 'institutionManagement')
-
- requirePublisherMetricsAccess: (req, res, next) ->
- requireAccessToEntity('publisher', req.params.id, req, res, next, 'publisherMetrics')
-
- requirePublisherManagementAccess: (req, res, next) ->
- requireAccessToEntity('publisher', req.params.id, req, res, next, 'publisherManagement')
-
- requireTemplateMetricsAccess: (req, res, next) ->
- templateId = req.params.id
- request {
- baseUrl: settings.apis.v1.url
- url: "/api/v2/templates/#{templateId}"
- method: 'GET'
- auth:
- user: settings.apis.v1.user
- pass: settings.apis.v1.pass
- sendImmediately: true
- }, (error, response, body) =>
- if response.statusCode == 404
- return next(new Errors.NotFoundError())
-
- if response.statusCode != 200
- logger.err { templateId }, "[TemplateMetrics] Couldn't fetch template data from v1"
- return next(new Error("Couldn't fetch template data from v1"))
-
- return next(error) if error?
- try
- body = JSON.parse(body)
- catch error
- return next(error)
-
- req.template =
- id: body.id
- title: body.title
- if body?.brand?.slug
- req.params.id = body.brand.slug
- UserMembershipAuthorization.requirePublisherMetricsAccess(req, res, next)
- else
- AuthorizationMiddleware.ensureUserIsSiteAdmin(req, res, next)
-
- requireGraphAccess: (req, res, next) ->
- req.params.id = req.query.resource_id
- if req.query.resource_type == 'template'
- return UserMembershipAuthorization.requireTemplateMetricsAccess(req, res, next)
- else if req.query.resource_type == 'institution'
- return UserMembershipAuthorization.requireInstitutionMetricsAccess(req, res, next)
- else if req.query.resource_type == 'group'
- return UserMembershipAuthorization.requireGroupMetricsAccess(req, res, next)
- else if req.query.resource_type == 'team'
- return UserMembershipAuthorization.requireTeamMetricsAccess(req, res, next)
- requireAccessToEntity(req.query.resource_type, req.query.resource_id, req, res, next)
-
- requireEntityCreationAccess: (req, res, next) ->
- loggedInUser = AuthenticationController.getSessionUser(req)
- unless loggedInUser and hasEntityCreationAccess(loggedInUser)
- return AuthorizationMiddleware.redirectToRestricted req, res, next
- next()
-
-requireAccessToEntity = (entityName, entityId, req, res, next, requiredStaffAccess=null) ->
- loggedInUser = AuthenticationController.getSessionUser(req)
- unless loggedInUser
- return AuthorizationMiddleware.redirectToRestricted req, res, next
-
- getEntity entityName, entityId, loggedInUser, requiredStaffAccess, (error, entity, entityConfig, entityExists) ->
- return next(error) if error?
-
- if entity?
- req.entity = entity
- req.entityConfig = entityConfig
- return next()
-
- if entityExists # user doesn't have access to entity
- return AuthorizationMiddleware.redirectToRestricted(req, res, next)
-
- if hasEntityCreationAccess(loggedInUser) and entityConfig.canCreate
- # entity doesn't exists, admin can create it
- return res.redirect "/entities/#{entityName}/create/#{entityId}"
-
- next(new Errors.NotFoundError())
-
-getEntity = (entityName, entityId, user, requiredStaffAccess, callback = (error, entity, entityConfig, entityExists)->) ->
- entityConfig = EntityConfigs[entityName]
- unless entityConfig
- return callback(new Errors.NotFoundError("No such entity: #{entityName}"))
-
- UserMembershipHandler.getEntity entityId, entityConfig, user, requiredStaffAccess, (error, entity)->
- return callback(error) if error?
- return callback(null, entity, entityConfig, true) if entity?
-
- # no access to entity. Check if entity exists
- UserMembershipHandler.getEntityWithoutAuthorizationCheck entityId, entityConfig, (error, entity)->
- return callback(error) if error?
- callback(null, null, entityConfig, entity?)
-
-hasEntityCreationAccess = (user) ->
- user.isAdmin or
- user.staffAccess?['institutionManagement'] or
- user.staffAccess?['publisherManagement']
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipController.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipController.coffee
deleted file mode 100644
index 1aced1c2a6..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipController.coffee
+++ /dev/null
@@ -1,100 +0,0 @@
-AuthenticationController = require('../Authentication/AuthenticationController')
-UserMembershipHandler = require('./UserMembershipHandler')
-EntityConfigs = require('./UserMembershipEntityConfigs')
-Errors = require('../Errors/Errors')
-EmailHelper = require("../Helpers/EmailHelper")
-logger = require("logger-sharelatex")
-
-module.exports =
- index: (req, res, next)->
- { entity, entityConfig } = req
- entity.fetchV1Data (error, entity) ->
- return next(error) if error?
- UserMembershipHandler.getUsers entity, entityConfig, (error, users)->
- return next(error) if error?
- entityPrimaryKey = entity[entityConfig.fields.primaryKey].toString()
- entityName = entity[entityConfig.fields.name] if entityConfig.fields.name
- res.render "user_membership/index",
- name: entityName
- users: users
- groupSize: entity.membersLimit if entityConfig.hasMembersLimit
- translations: entityConfig.translations
- paths: entityConfig.pathsFor(entityPrimaryKey)
-
- add: (req, res, next)->
- { entity, entityConfig } = req
- email = EmailHelper.parseEmail(req.body.email)
- if !email?
- return res.status(400).json error:
- code: 'invalid_email'
- message: req.i18n.translate('invalid_email')
-
-
- if entityConfig.readOnly
- return next(new Errors.NotFoundError("Cannot add users to entity"))
-
- UserMembershipHandler.addUser entity, entityConfig, email, (error, user)->
- if error?.alreadyAdded
- return res.status(400).json error:
- code: 'user_already_added'
- message: req.i18n.translate('user_already_added')
- if error?.userNotFound
- return res.status(404).json error:
- code: 'user_not_found'
- message: req.i18n.translate('user_not_found')
- return next(error) if error?
- res.json(user: user)
-
- remove: (req, res, next)->
- { entity, entityConfig } = req
- userId = req.params.userId
-
- if entityConfig.readOnly
- return next(new Errors.NotFoundError("Cannot remove users from entity"))
-
- loggedInUserId = AuthenticationController.getLoggedInUserId(req)
- if loggedInUserId == userId
- return res.status(400).json error:
- code: 'managers_cannot_remove_self'
- message: req.i18n.translate('managers_cannot_remove_self')
-
- UserMembershipHandler.removeUser entity, entityConfig, userId, (error, user)->
- if error?.isAdmin
- return res.status(400).json error:
- code: 'managers_cannot_remove_admin'
- message: req.i18n.translate('managers_cannot_remove_admin')
- return next(error) if error?
- res.send()
-
- exportCsv: (req, res, next)->
- { entity, entityConfig } = req
- logger.log subscriptionId: entity._id, "exporting csv"
- UserMembershipHandler.getUsers entity, entityConfig, (error, users)->
- return next(error) if error?
- csvOutput = ""
- for user in users
- csvOutput += user.email + "\n"
- res.header(
- "Content-Disposition",
- "attachment; filename=Group.csv"
- )
- res.contentType('text/csv')
- res.send(csvOutput)
-
- new: (req, res, next)->
- res.render "user_membership/new",
- entityName: req.params.name
- entityId: req.params.id
-
- create: (req, res, next)->
- entityName = req.params.name
- entityId = req.params.id
- entityConfig = EntityConfigs[entityName]
- unless entityConfig
- return next(new Errors.NotFoundError("No such entity: #{entityName}"))
- unless entityConfig.canCreate
- return next(new Errors.NotFoundError("Cannot create new #{entityName}"))
-
- UserMembershipHandler.createEntity entityId, entityConfig, (error, entity) ->
- return next(error) if error?
- res.redirect entityConfig.pathsFor(entityId).index
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipEntityConfigs.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipEntityConfigs.coffee
deleted file mode 100644
index b5e5b9a8b4..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipEntityConfigs.coffee
+++ /dev/null
@@ -1,84 +0,0 @@
-module.exports =
- group:
- modelName: 'Subscription'
- readOnly: true
- hasMembersLimit: true
- fields:
- primaryKey: '_id'
- read: ['invited_emails', 'teamInvites', 'member_ids']
- write: null
- access: 'manager_ids'
- name: 'teamName'
- baseQuery:
- groupPlan: true
- translations:
- title: 'group_account'
- subtitle: 'members_management'
- remove: 'remove_from_group'
- pathsFor: (id) ->
- addMember: "/manage/groups/#{id}/invites"
- removeMember: "/manage/groups/#{id}/user"
- removeInvite: "/manage/groups/#{id}/invites"
- exportMembers: "/manage/groups/#{id}/members/export"
-
- team: # for metrics only
- modelName: 'Subscription'
- fields:
- primaryKey: 'overleaf.id'
- access: 'manager_ids'
- baseQuery:
- groupPlan: true
-
- groupManagers:
- modelName: 'Subscription'
- fields:
- primaryKey: '_id'
- read: ['manager_ids']
- write: 'manager_ids'
- access: 'manager_ids'
- name: 'teamName'
- baseQuery:
- groupPlan: true
- translations:
- title: 'group_account'
- subtitle: 'managers_management'
- remove: 'remove_manager'
- pathsFor: (id) ->
- addMember: "/manage/groups/#{id}/managers"
- removeMember: "/manage/groups/#{id}/managers"
-
- institution:
- modelName: 'Institution'
- canCreate: true
- fields:
- primaryKey: 'v1Id'
- read: ['managerIds']
- write: 'managerIds'
- access: 'managerIds'
- name: 'name'
- translations:
- title: 'institution_account'
- subtitle: 'managers_management'
- remove: 'remove_manager'
- pathsFor: (id) ->
- index: "/manage/institutions/#{id}/managers"
- addMember: "/manage/institutions/#{id}/managers"
- removeMember: "/manage/institutions/#{id}/managers"
-
- publisher:
- modelName: 'Publisher'
- canCreate: true
- fields:
- primaryKey: 'slug'
- read: ['managerIds']
- write: 'managerIds'
- access: 'managerIds'
- name: 'name'
- translations:
- title: 'publisher_account'
- subtitle: 'managers_management'
- remove: 'remove_manager'
- pathsFor: (id) ->
- index: "/manage/publishers/#{id}/managers"
- addMember: "/manage/publishers/#{id}/managers"
- removeMember: "/manage/publishers/#{id}/managers"
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipHandler.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipHandler.coffee
deleted file mode 100644
index fd8c30bb22..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipHandler.coffee
+++ /dev/null
@@ -1,77 +0,0 @@
-ObjectId = require('mongoose').Types.ObjectId
-async = require("async")
-Errors = require('../Errors/Errors')
-EntityModels =
- Institution: require('../../models/Institution').Institution
- Subscription: require('../../models/Subscription').Subscription
- Publisher: require('../../models/Publisher').Publisher
-UserMembershipViewModel = require('./UserMembershipViewModel')
-UserGetter = require('../User/UserGetter')
-logger = require('logger-sharelatex')
-UserMembershipEntityConfigs = require "./UserMembershipEntityConfigs"
-
-module.exports =
- getEntity: (entityId, entityConfig, loggedInUser, requiredStaffAccess, callback = (error, entity) ->) ->
- query = buildEntityQuery(entityId, entityConfig)
- unless loggedInUser.isAdmin or loggedInUser.staffAccess?[requiredStaffAccess]
- query[entityConfig.fields.access] = ObjectId(loggedInUser._id)
- EntityModels[entityConfig.modelName].findOne query, callback
-
- getEntityWithoutAuthorizationCheck: (entityId, entityConfig, callback = (error, entity) ->) ->
- query = buildEntityQuery(entityId, entityConfig)
- EntityModels[entityConfig.modelName].findOne query, callback
-
- createEntity: (entityId, entityConfig, callback = (error, entity) ->) ->
- data = buildEntityQuery(entityId, entityConfig)
- EntityModels[entityConfig.modelName].create data, callback
-
- getUsers: (entity, entityConfig, callback = (error, users) ->) ->
- attributes = entityConfig.fields.read
- getPopulatedListOfMembers(entity, attributes, callback)
-
- addUser: (entity, entityConfig, email, callback = (error, user) ->) ->
- attribute = entityConfig.fields.write
- UserGetter.getUserByAnyEmail email, (error, user) ->
- return callback(error) if error?
- unless user
- return callback(userNotFound: true)
- if entity[attribute].some((managerId) -> managerId.equals(user._id))
- return callback(alreadyAdded: true)
-
- addUserToEntity entity, attribute, user, (error) ->
- callback(error, UserMembershipViewModel.build(user))
-
- removeUser: (entity, entityConfig, userId, callback = (error) ->) ->
- attribute = entityConfig.fields.write
- if entity.admin_id?.equals(userId)
- return callback(isAdmin: true)
- removeUserFromEntity entity, attribute, userId, callback
-
-getPopulatedListOfMembers = (entity, attributes, callback = (error, users)->)->
- userObjects = []
-
- for attribute in attributes
- for userObject in entity[attribute] or []
- # userObject can be an email as String, a user id as ObjectId or an
- # invite as Object with an email attribute as String. We want to pass to
- # UserMembershipViewModel either an email as (String) or a user id (ObjectId)
- userIdOrEmail = userObject.email || userObject
- userObjects.push userIdOrEmail
-
- async.map userObjects, UserMembershipViewModel.buildAsync, callback
-
-addUserToEntity = (entity, attribute, user, callback = (error)->) ->
- fieldUpdate = {}
- fieldUpdate[attribute] = user._id
- entity.update { $addToSet: fieldUpdate }, callback
-
-removeUserFromEntity = (entity, attribute, userId, callback = (error)->) ->
- fieldUpdate = {}
- fieldUpdate[attribute] = userId
- entity.update { $pull: fieldUpdate }, callback
-
-buildEntityQuery = (entityId, entityConfig, loggedInUser) ->
- entityId = ObjectId(entityId) if ObjectId.isValid(entityId.toString())
- query = Object.assign({}, entityConfig.baseQuery)
- query[entityConfig.fields.primaryKey] = entityId
- query
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipRouter.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipRouter.coffee
deleted file mode 100644
index 5f05d9281b..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipRouter.coffee
+++ /dev/null
@@ -1,75 +0,0 @@
-UserMembershipAuthorization = require './UserMembershipAuthorization'
-UserMembershipController = require './UserMembershipController'
-SubscriptionGroupController = require '../Subscription/SubscriptionGroupController'
-TeamInvitesController = require '../Subscription/TeamInvitesController'
-RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
-
-module.exports =
- apply: (webRouter) ->
- # group members routes
- webRouter.get '/manage/groups/:id/members',
- UserMembershipAuthorization.requireGroupManagementAccess,
- UserMembershipController.index
- webRouter.post '/manage/groups/:id/invites',
- UserMembershipAuthorization.requireGroupManagementAccess,
- RateLimiterMiddleware.rateLimit({
- endpointName: "create-team-invite"
- maxRequests: 100
- timeInterval: 60
- }),
- TeamInvitesController.createInvite
- webRouter.delete '/manage/groups/:id/user/:user_id',
- UserMembershipAuthorization.requireGroupManagementAccess,
- SubscriptionGroupController.removeUserFromGroup
- webRouter.delete '/manage/groups/:id/invites/:email',
- UserMembershipAuthorization.requireGroupManagementAccess,
- TeamInvitesController.revokeInvite
- webRouter.get '/manage/groups/:id/members/export',
- UserMembershipAuthorization.requireGroupManagementAccess,
- RateLimiterMiddleware.rateLimit({
- endpointName: "export-team-csv"
- maxRequests: 30
- timeInterval: 60
- }),
- UserMembershipController.exportCsv
-
- # group managers routes
- webRouter.get "/manage/groups/:id/managers",
- UserMembershipAuthorization.requireGroupManagersManagementAccess,
- UserMembershipController.index
- webRouter.post "/manage/groups/:id/managers",
- UserMembershipAuthorization.requireGroupManagersManagementAccess,
- UserMembershipController.add
- webRouter.delete "/manage/groups/:id/managers/:userId",
- UserMembershipAuthorization.requireGroupManagersManagementAccess,
- UserMembershipController.remove
-
- # institution members routes
- webRouter.get "/manage/institutions/:id/managers",
- UserMembershipAuthorization.requireInstitutionManagementAccess,
- UserMembershipController.index
- webRouter.post "/manage/institutions/:id/managers",
- UserMembershipAuthorization.requireInstitutionManagementAccess,
- UserMembershipController.add
- webRouter.delete "/manage/institutions/:id/managers/:userId",
- UserMembershipAuthorization.requireInstitutionManagementAccess,
- UserMembershipController.remove
-
- # publisher members routes
- webRouter.get "/manage/publishers/:id/managers",
- UserMembershipAuthorization.requirePublisherManagementAccess,
- UserMembershipController.index
- webRouter.post "/manage/publishers/:id/managers",
- UserMembershipAuthorization.requirePublisherManagementAccess,
- UserMembershipController.add
- webRouter.delete "/manage/publishers/:id/managers/:userId",
- UserMembershipAuthorization.requirePublisherManagementAccess,
- UserMembershipController.remove
-
- # create new entitites
- webRouter.get "/entities/:name/create/:id",
- UserMembershipAuthorization.requireEntityCreationAccess,
- UserMembershipController.new
- webRouter.post "/entities/:name/create/:id",
- UserMembershipAuthorization.requireEntityCreationAccess,
- UserMembershipController.create
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipViewModel.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipViewModel.coffee
deleted file mode 100644
index ac5ba42168..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipViewModel.coffee
+++ /dev/null
@@ -1,45 +0,0 @@
-ObjectId = require('mongojs').ObjectId
-UserGetter = require('../User/UserGetter')
-
-module.exports = UserMembershipViewModel =
- build: (userOrEmail) ->
- if userOrEmail._id
- buildUserViewModel userOrEmail
- else
- buildUserViewModelWithEmail userOrEmail
-
-
- buildAsync: (userOrIdOrEmail, callback = (error, viewModel)->) ->
- unless userOrIdOrEmail instanceof ObjectId
- # userOrIdOrEmail is a user or an email and can be parsed by #build
- return callback(null, UserMembershipViewModel.build(userOrIdOrEmail))
-
- userId = userOrIdOrEmail
- projection = { email: 1, first_name: 1, last_name: 1 }
- UserGetter.getUserOrUserStubById userId, projection, (error, user, isStub) ->
- if error? or !user?
- return callback(null, buildUserViewModelWithId(userId.toString()))
- if isStub
- return callback(null, buildUserViewModelWithStub(user))
- callback(null, buildUserViewModel(user))
-
-
-buildUserViewModel = (user, isInvite = false) ->
- _id: user._id or null
- email: user.email or null
- first_name: user.first_name or null
- last_name: user.last_name or null
- invite: isInvite
-
-
-buildUserViewModelWithEmail = (email) ->
- buildUserViewModel({ email }, true)
-
-
-buildUserViewModelWithStub = (user) ->
- # user stubs behave as invites
- buildUserViewModel(user, true)
-
-
-buildUserViewModelWithId = (id) ->
- buildUserViewModel({ _id: id }, false)
diff --git a/services/web/app/coffee/Features/UserMembership/UserMembershipsHandler.coffee b/services/web/app/coffee/Features/UserMembership/UserMembershipsHandler.coffee
deleted file mode 100644
index 41d3f5ef0f..0000000000
--- a/services/web/app/coffee/Features/UserMembership/UserMembershipsHandler.coffee
+++ /dev/null
@@ -1,32 +0,0 @@
-async = require("async")
-EntityModels =
- Institution: require('../../models/Institution').Institution
- Subscription: require('../../models/Subscription').Subscription
- Publisher: require('../../models/Publisher').Publisher
-UserMembershipEntityConfigs = require "./UserMembershipEntityConfigs"
-
-module.exports = UserMembershipsHandler =
- removeUserFromAllEntities: (userId, callback = (error) ->) ->
- # get all writable entity types
- entityConfigs = []
- for key, entityConfig of UserMembershipEntityConfigs
- entityConfigs.push(entityConfig) if entityConfig.fields.write?
-
- # remove the user from all entities types
- async.map entityConfigs, ((entityConfig, innerCallback) ->
- UserMembershipsHandler.removeUserFromEntities entityConfig, userId, innerCallback
- ), callback
-
- removeUserFromEntities: (entityConfig, userId, callback = (error) ->) ->
- removeOperation = "$pull": {}
- removeOperation["$pull"][entityConfig.fields.write] = userId
- EntityModels[entityConfig.modelName].updateMany {}, removeOperation, callback
-
- getEntitiesByUser: (entityConfig, userId, callback = (error, entities) ->) ->
- query = Object.assign({}, entityConfig.baseQuery)
- query[entityConfig.fields.access] = userId
- EntityModels[entityConfig.modelName].find query, (error, entities = []) ->
- return callback(error) if error?
- async.mapSeries entities,
- (entity, cb) -> entity.fetchV1Data(cb),
- callback
diff --git a/services/web/app/coffee/Features/V1/V1Api.coffee b/services/web/app/coffee/Features/V1/V1Api.coffee
deleted file mode 100644
index 50ba940da5..0000000000
--- a/services/web/app/coffee/Features/V1/V1Api.coffee
+++ /dev/null
@@ -1,49 +0,0 @@
-request = require 'request'
-settings = require 'settings-sharelatex'
-Errors = require '../Errors/Errors'
-
-# TODO: check what happens when these settings aren't defined
-DEFAULT_V1_PARAMS = {
- baseUrl: settings?.apis?.v1?.url
- auth:
- user: settings?.apis?.v1?.user
- pass: settings?.apis?.v1?.pass
- json: true,
- timeout: 30 * 1000
-}
-
-v1Request = request.defaults(DEFAULT_V1_PARAMS)
-
-DEFAULT_V1_OAUTH_PARAMS = {
- baseUrl: settings?.apis?.v1?.url
- json: true,
- timeout: 30 * 1000
-}
-
-v1OauthRequest = request.defaults(DEFAULT_V1_OAUTH_PARAMS)
-
-module.exports = V1Api =
- request: (options, callback) ->
- return request(options) if !callback?
- v1Request options, (error, response, body) ->
- V1Api._responseHandler options, error, response, body, callback
-
- oauthRequest: (options, token, callback) ->
- return callback(new Error "uri required") unless options.uri?
- options.method = "GET" unless options.method?
- options.auth = bearer: token
- v1OauthRequest options, (error, response, body) ->
- V1Api._responseHandler options, error, response, body, callback
-
- _responseHandler: (options, error, response, body, callback) ->
- return callback(error, response, body) if error?
- if 200 <= response.statusCode < 300 or response.statusCode in (options.expectedStatusCodes or [])
- callback null, response, body
- else if response.statusCode == 403
- error = new Errors.ForbiddenError("overleaf v1 returned forbidden")
- error.statusCode = response.statusCode
- callback error
- else
- error = new Error("overleaf v1 returned non-success code: #{response.statusCode} #{options.method} #{options.uri}")
- error.statusCode = response.statusCode
- callback error
diff --git a/services/web/app/coffee/Features/V1/V1Handler.coffee b/services/web/app/coffee/Features/V1/V1Handler.coffee
deleted file mode 100644
index f6dd20b268..0000000000
--- a/services/web/app/coffee/Features/V1/V1Handler.coffee
+++ /dev/null
@@ -1,60 +0,0 @@
-V1Api = require './V1Api'
-Settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-
-
-module.exports = V1Handler =
-
- authWithV1: (email, password, callback=(err, isValid, v1Profile)->) ->
- V1Api.request {
- method: 'POST',
- url: '/api/v1/sharelatex/login',
- json: {email, password},
- expectedStatusCodes: [403]
- }, (err, response, body) ->
- if err?
- logger.err {email, err},
- "[V1Handler] error while talking to v1 login api"
- return callback(err)
- if response.statusCode in [200, 403]
- isValid = body.valid
- userProfile = body.user_profile
- logger.log {email, isValid, v1UserId: body?.user_profile?.id},
- "[V1Handler] got response from v1 login api"
- callback(null, isValid, userProfile)
- else
- err = new Error("Unexpected status from v1 login api: #{response.statusCode}")
- callback(err)
-
- doPasswordReset: (v1_user_id, password, callback=(err, created)->) ->
- logger.log({v1_user_id},
- "sending password reset request to v1 login api")
- V1Api.request {
- method: 'POST'
- url: "/api/v1/sharelatex/reset_password"
- json: {
- user_id: v1_user_id,
- password: password
- }
- expectedStatusCodes: [200]
- }, (err, response, body) ->
- if err?
- logger.err {v1_user_id, err}, "error while talking to v1 password reset api"
- return callback(err, false)
- if response.statusCode in [200]
- logger.log {v1_user_id, changed: true}, "got success response from v1 password reset api"
- callback(null, true)
- else
- err = new Error("Unexpected status from v1 password reset api: #{response.statusCode}")
- callback(err, false)
-
- getDocExported: (token, callback=(err, info)->) ->
- # default to not exported
- return callback(null, {
- exported: false
- exporting: false
- }) unless Settings.apis?.v1?
-
- V1Api.request { url: "/api/v1/sharelatex/docs/#{token}/exported_to_v2" }, (err, response, body) ->
- return callback err if err?
- callback null, body
diff --git a/services/web/app/coffee/infrastructure/CrawlerLogger.coffee b/services/web/app/coffee/infrastructure/CrawlerLogger.coffee
deleted file mode 100644
index 4b3a2cd702..0000000000
--- a/services/web/app/coffee/infrastructure/CrawlerLogger.coffee
+++ /dev/null
@@ -1,11 +0,0 @@
-metrics = require('metrics-sharelatex')
-module.exports =
- log: (req)->
- if req.headers["user-agent"]?
- userAgent = req.headers["user-agent"].toLowerCase()
- if userAgent.indexOf("google") != -1
- metrics.inc "crawler.google"
- else if userAgent.indexOf("facebook") != -1
- metrics.inc "crawler.facebook"
- else if userAgent.indexOf("bing") != -1
- metrics.inc "crawler.bing"
diff --git a/services/web/app/coffee/infrastructure/Csrf.coffee b/services/web/app/coffee/infrastructure/Csrf.coffee
deleted file mode 100644
index 660e2d5a66..0000000000
--- a/services/web/app/coffee/infrastructure/Csrf.coffee
+++ /dev/null
@@ -1,56 +0,0 @@
-csurf = require('csurf')
-csrf = csurf()
-
-# Wrapper for `csurf` middleware that provides a list of routes that can be excluded from csrf checks.
-#
-# Include with `Csrf = require('./Csrf')`
-#
-# Add the middleware to the router with:
-# myRouter.csrf = new Csrf()
-# myRouter.use webRouter.csrf.middleware
-# When building routes, specify a route to exclude from csrf checks with:
-# myRouter.csrf.disableDefaultCsrfProtection "/path" "METHOD"
-#
-# To validate the csrf token in a request to ensure that it's valid, you can use `validateRequest`, which takes a
-# request object and calls a callback with either true or false.
-
-module.exports = class Csrf
- constructor: ->
- @excluded_routes = {}
-
- disableDefaultCsrfProtection: (route, method) ->
- @excluded_routes[route] = {} unless @excluded_routes[route]
- @excluded_routes[route][method] = 1
-
- middleware: (req, res, next) =>
- # We want to call the middleware for all routes, even if excluded, because csurf sets up a csrfToken() method on
- # the request, to get a new csrf token for any rendered forms. For excluded routes we'll then ignore a 'bad csrf
- # token' error from csurf and continue on...
-
- # check whether the request method is excluded for the specified route
- if @excluded_routes[req.path]?[req.method] == 1
- # ignore the error if it's due to a bad csrf token, and continue
- csrf req, res, (err) =>
- if (err && err.code != 'EBADCSRFTOKEN')
- next(err)
- else
- next()
- else
- csrf req, res, next
-
- @validateRequest: (req, cb = (valid)->) ->
- # run a dummy csrf check to see if it returns an error
- csrf req, null, (err) ->
- cb(!err?)
-
- @validateToken: (token, session, cb = (valid)->) ->
- return cb(false) unless token?
- # run a dummy csrf check to see if it returns an error
- # use this to simulate a csrf check regardless of req method, headers &c.
- req =
- body:
- _csrf: token
- headers: {}
- method: 'POST'
- session: session
- Csrf.validateRequest(req, cb)
diff --git a/services/web/app/coffee/infrastructure/Events.coffee b/services/web/app/coffee/infrastructure/Events.coffee
deleted file mode 100644
index a7ff219b7a..0000000000
--- a/services/web/app/coffee/infrastructure/Events.coffee
+++ /dev/null
@@ -1,2 +0,0 @@
-events = require "events"
-module.exports = new events.EventEmitter()
\ No newline at end of file
diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee
deleted file mode 100644
index c0a91e7c91..0000000000
--- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee
+++ /dev/null
@@ -1,378 +0,0 @@
-logger = require 'logger-sharelatex'
-fs = require 'fs'
-crypto = require 'crypto'
-Settings = require('settings-sharelatex')
-SubscriptionFormatters = require('../Features/Subscription/SubscriptionFormatters')
-querystring = require('querystring')
-SystemMessageManager = require("../Features/SystemMessages/SystemMessageManager")
-AuthenticationController = require("../Features/Authentication/AuthenticationController")
-_ = require("underscore")
-async = require("async")
-Modules = require "./Modules"
-Url = require "url"
-PackageVersions = require "./PackageVersions"
-htmlEncoder = new require("node-html-encoder").Encoder("numerical")
-hashedFiles = {}
-Path = require 'path'
-Features = require "./Features"
-Modules = require "./Modules"
-moment = require 'moment'
-
-jsPath =
- if Settings.useMinifiedJs
- "/minjs/"
- else
- "/js/"
-
-ace = PackageVersions.lib('ace')
-pdfjs = PackageVersions.lib('pdfjs')
-fineuploader = PackageVersions.lib('fineuploader')
-
-getFileContent = (filePath)->
- filePath = Path.join __dirname, "../../../", "public#{filePath}"
- exists = fs.existsSync filePath
- if exists
- content = fs.readFileSync filePath, "UTF-8"
- return content
- else
- logger.log filePath:filePath, "file does not exist for hashing"
- return ""
-
-pathList = [
- "#{jsPath}libs/require.js"
- "#{jsPath}ide.js"
- "#{jsPath}main.js"
- "#{jsPath}libraries.js"
- "/stylesheets/style.css"
- "/stylesheets/light-style.css"
- "/stylesheets/ieee-style.css"
- "/stylesheets/sl-style.css"
-].concat(Modules.moduleAssetFiles(jsPath))
-
-if !Settings.useMinifiedJs
- logger.log "not using minified JS, not hashing static files"
-else
- logger.log "Generating file hashes..."
- for path in pathList
- content = getFileContent(path)
- hash = crypto.createHash("md5").update(content).digest("hex")
-
- splitPath = path.split("/")
- filenameSplit = splitPath.pop().split(".")
- filenameSplit.splice(filenameSplit.length-1, 0, hash)
- splitPath.push(filenameSplit.join("."))
-
- hashPath = splitPath.join("/")
- hashedFiles[path] = hashPath
-
- fsHashPath = Path.join __dirname, "../../../", "public#{hashPath}"
- fs.writeFileSync(fsHashPath, content)
-
-
- logger.log "Finished hashing static content"
-
-cdnAvailable = Settings.cdn?.web?.host?
-darkCdnAvailable = Settings.cdn?.web?.darkHost?
-
-module.exports = (app, webRouter, privateApiRouter, publicApiRouter)->
- webRouter.use (req, res, next)->
- res.locals.session = req.session
- next()
-
- addSetContentDisposition = (req, res, next) ->
- res.setContentDisposition = (type, opts) ->
- directives = for k, v of opts
- "#{k}=\"#{encodeURIComponent(v)}\""
- contentDispositionValue = "#{type}; #{directives.join('; ')}"
- res.setHeader(
- 'Content-Disposition',
- contentDispositionValue
- )
- next()
- webRouter.use addSetContentDisposition
- privateApiRouter.use addSetContentDisposition
- publicApiRouter.use addSetContentDisposition
-
- webRouter.use (req, res, next)->
- req.externalAuthenticationSystemUsed = Features.externalAuthenticationSystemUsed
- res.locals.externalAuthenticationSystemUsed = Features.externalAuthenticationSystemUsed
- req.hasFeature = res.locals.hasFeature = Features.hasFeature
- res.locals.userIsFromOLv1 = (user) ->
- user.overleaf?.id?
- res.locals.userIsFromSL = (user) ->
- !user.overleaf?.id?
- next()
-
- webRouter.use (req, res, next)->
-
- cdnBlocked = req.query.nocdn == 'true' or req.session.cdnBlocked
- user_id = AuthenticationController.getLoggedInUserId(req)
-
- if cdnBlocked and !req.session.cdnBlocked?
- logger.log user_id:user_id, ip:req?.ip, "cdnBlocked for user, not using it and turning it off for future requets"
- req.session.cdnBlocked = true
-
- isDark = req.headers?.host?.slice(0,7)?.toLowerCase().indexOf("dark") != -1
- isSmoke = req.headers?.host?.slice(0,5)?.toLowerCase() == "smoke"
- isLive = !isDark and !isSmoke
-
- if cdnAvailable and isLive and !cdnBlocked
- staticFilesBase = Settings.cdn?.web?.host
- else if darkCdnAvailable and isDark
- staticFilesBase = Settings.cdn?.web?.darkHost
- else
- staticFilesBase = ""
-
- res.locals.jsPath = jsPath
- res.locals.fullJsPath = Url.resolve(staticFilesBase, jsPath)
- res.locals.lib = PackageVersions.lib
-
- res.locals.moment = moment
-
- res.locals.buildJsPath = (jsFile, opts = {})->
- path = Path.join(jsPath, jsFile)
-
- if opts.hashedPath && hashedFiles[path]?
- path = hashedFiles[path]
-
- if !opts.qs?
- opts.qs = {}
-
- if opts.cdn != false
- path = Url.resolve(staticFilesBase, path)
-
- qs = querystring.stringify(opts.qs)
-
- if opts.removeExtension == true
- path = path.slice(0,-3)
-
- if qs? and qs.length > 0
- path = path + "?" + qs
- return path
-
- res.locals.buildWebpackPath = (jsFile, opts = {}) ->
- if Settings.webpack? and !Settings.useMinifiedJs
- path = Path.join(jsPath, jsFile)
- if opts.removeExtension == true
- path = path.slice(0,-3)
- return "#{Settings.webpack.url}/public#{path}"
- else
- return res.locals.buildJsPath(jsFile, opts)
-
-
- IEEE_BRAND_ID = 15
- res.locals.isIEEE = (brandVariation) ->
- brandVariation?.brand_id == IEEE_BRAND_ID
-
- _buildCssFileName = (themeModifier) ->
- return "/" + Settings.brandPrefix + (if themeModifier then themeModifier else "") + "style.css"
-
- res.locals.getCssThemeModifier = (userSettings, brandVariation) ->
- # Themes only exist in OL v2
- if Settings.overleaf?
- # The IEEE theme takes precedence over the user personal setting, i.e. a user with
- # a theme setting of "light" will still get the IEE theme in IEEE branded projects.
- if res.locals.isIEEE(brandVariation)
- themeModifier = "ieee-"
- else if userSettings?.overallTheme?
- themeModifier = userSettings.overallTheme
- return themeModifier
-
- res.locals.buildCssPath = (themeModifier, buildOpts) ->
- cssFileName = _buildCssFileName themeModifier
- path = Path.join("/stylesheets/", cssFileName)
- if buildOpts?.hashedPath && hashedFiles[path]?
- hashedPath = hashedFiles[path]
- return Url.resolve(staticFilesBase, hashedPath)
- return Url.resolve(staticFilesBase, path)
-
- res.locals.buildImgPath = (imgFile)->
- path = Path.join("/img/", imgFile)
- return Url.resolve(staticFilesBase, path)
-
- res.locals.mathJaxPath = res.locals.buildJsPath(
- 'libs/mathjax/MathJax.js',
- {cdn:false, qs:{config:'TeX-AMS_HTML,Safe'}}
- )
-
- next()
-
- webRouter.use (req, res, next)->
- res.locals.settings = Settings
- next()
-
- webRouter.use (req, res, next)->
- res.locals.translate = (key, vars = {}, htmlEncode = false) ->
- vars.appName = Settings.appName
- str = req.i18n.translate(key, vars)
- if htmlEncode then htmlEncoder.htmlEncode(str) else str
- # Don't include the query string parameters, otherwise Google
- # treats ?nocdn=true as the canonical version
- res.locals.currentUrl = Url.parse(req.originalUrl).pathname
- res.locals.capitalize = (string) ->
- return "" if string.length == 0
- return string.charAt(0).toUpperCase() + string.slice(1)
- next()
-
- webRouter.use (req, res, next)->
- res.locals.getSiteHost = ->
- Settings.siteUrl.substring(Settings.siteUrl.indexOf("//")+2)
- next()
-
- webRouter.use (req, res, next) ->
- res.locals.getUserEmail = ->
- user = AuthenticationController.getSessionUser(req)
- email = user?.email or ""
- return email
- next()
-
- webRouter.use (req, res, next) ->
- res.locals.StringHelper = require('../Features/Helpers/StringHelper')
- next()
-
- webRouter.use (req, res, next)->
- res.locals.formatProjectPublicAccessLevel = (privilegeLevel)->
- formatedPrivileges = private:"Private", readOnly:"Public: Read Only", readAndWrite:"Public: Read and Write"
- return formatedPrivileges[privilegeLevel] || "Private"
- next()
-
- webRouter.use (req, res, next)->
- res.locals.buildReferalUrl = (referal_medium) ->
- url = Settings.siteUrl
- currentUser = AuthenticationController.getSessionUser(req)
- if currentUser? and currentUser?.referal_id?
- url+="?r=#{currentUser.referal_id}&rm=#{referal_medium}&rs=b" # Referal source = bonus
- return url
- res.locals.getReferalId = ->
- currentUser = AuthenticationController.getSessionUser(req)
- if currentUser? and currentUser?.referal_id?
- return currentUser.referal_id
- res.locals.getReferalTagLine = ->
- tagLines = [
- "Roar!"
- "Shout about us!"
- "Please recommend us"
- "Tell the world!"
- "Thanks for using ShareLaTeX"
- ]
- return tagLines[Math.floor(Math.random()*tagLines.length)]
- res.locals.getRedirAsQueryString = ->
- if req.query.redir?
- return "?#{querystring.stringify({redir:req.query.redir})}"
- return ""
-
- res.locals.getLoggedInUserId = ->
- return AuthenticationController.getLoggedInUserId(req)
- res.locals.isUserLoggedIn = ->
- return AuthenticationController.isUserLoggedIn(req)
- res.locals.getSessionUser = ->
- return AuthenticationController.getSessionUser(req)
-
- next()
-
- webRouter.use (req, res, next) ->
- res.locals.csrfToken = req?.csrfToken()
- next()
-
- webRouter.use (req, res, next) ->
- res.locals.getReqQueryParam = (field)->
- return req.query?[field]
- next()
-
- webRouter.use (req, res, next)->
- res.locals.formatPrice = SubscriptionFormatters.formatPrice
- next()
-
- webRouter.use (req, res, next)->
- currentUser = AuthenticationController.getSessionUser(req)
- if currentUser?
- res.locals.user =
- email: currentUser.email
- first_name: currentUser.first_name
- last_name: currentUser.last_name
- if req.session.justRegistered
- res.locals.justRegistered = true
- delete req.session.justRegistered
- if req.session.justLoggedIn
- res.locals.justLoggedIn = true
- delete req.session.justLoggedIn
- res.locals.gaToken = Settings.analytics?.ga?.token
- res.locals.tenderUrl = Settings.tenderUrl
- res.locals.sentrySrc = Settings.sentry?.src
- res.locals.sentryPublicDSN = Settings.sentry?.publicDSN
- next()
-
- webRouter.use (req, res, next) ->
- if req.query? and req.query.scribtex_path?
- res.locals.lookingForScribtex = true
- res.locals.scribtexPath = req.query.scribtex_path
- next()
-
- webRouter.use (req, res, next) ->
- # Clone the nav settings so they can be modified for each request
- res.locals.nav = {}
- for key, value of Settings.nav
- res.locals.nav[key] = _.clone(Settings.nav[key])
- res.locals.templates = Settings.templateLinks
- if res.locals.nav.header
- console.error {}, "The `nav.header` setting is no longer supported, use `nav.header_extras` instead"
- next()
-
- webRouter.use (req, res, next) ->
- SystemMessageManager.getMessages (error, messages = []) ->
- res.locals.systemMessages = messages
- next()
-
- webRouter.use (req, res, next)->
- res.locals.query = req.query
- next()
-
- webRouter.use (req, res, next)->
- subdomain = _.find Settings.i18n.subdomainLang, (subdomain)->
- subdomain.lngCode == req.showUserOtherLng and !subdomain.hide
- res.locals.recomendSubdomain = subdomain
- res.locals.currentLngCode = req.lng
- next()
-
- webRouter.use (req, res, next) ->
- if Settings.reloadModuleViewsOnEachRequest
- Modules.loadViewIncludes()
- res.locals.moduleIncludes = Modules.moduleIncludes
- res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable
- next()
-
- webRouter.use (req, res, next) ->
- isSl = (Settings.brandPrefix == 'sl-')
- res.locals.uiConfig =
- defaultResizerSizeOpen : if isSl then 24 else 7
- defaultResizerSizeClosed : if isSl then 24 else 7
- eastResizerCursor : if isSl then null else "ew-resize"
- westResizerCursor : if isSl then null else "ew-resize"
- chatResizerSizeOpen : if isSl then 12 else 7
- chatResizerSizeClosed : 0
- chatMessageBorderSaturation: if isSl then "70%" else "85%"
- chatMessageBorderLightness : if isSl then "70%" else "40%"
- chatMessageBgSaturation : if isSl then "60%" else "85%"
- chatMessageBgLightness : if isSl then "97%" else "40%"
- defaultFontFamily : if isSl then 'monaco' else 'lucida'
- defaultLineHeight : if isSl then 'compact' else 'normal'
- renderAnnouncements : isSl
- next()
-
- webRouter.use (req, res, next) ->
- #TODO
- if Settings.overleaf?
- res.locals.overallThemes = [
- { name: "Default", val: "", path: res.locals.buildCssPath(null, { hashedPath: true }) }
- { name: "Light", val: "light-", path: res.locals.buildCssPath("light-", { hashedPath: true }) }
- ]
- next()
-
- webRouter.use (req, res, next) ->
- res.locals.ExposedSettings =
- isOverleaf: Settings.overleaf?
- appName: Settings.appName
- siteUrl: Settings.siteUrl
- recaptchaSiteKeyV3: Settings.recaptcha?.siteKeyV3
- recaptchaDisabled: Settings.recaptcha?.disabled
- next()
diff --git a/services/web/app/coffee/infrastructure/Features.coffee b/services/web/app/coffee/infrastructure/Features.coffee
deleted file mode 100644
index 7e53cbd29b..0000000000
--- a/services/web/app/coffee/infrastructure/Features.coffee
+++ /dev/null
@@ -1,34 +0,0 @@
-Settings = require 'settings-sharelatex'
-
-module.exports = Features =
- externalAuthenticationSystemUsed: ->
- Settings.ldap? or Settings.saml? or Settings.overleaf?.oauth?
-
- hasFeature: (feature) ->
- switch feature
- when 'homepage'
- return Settings.enableHomepage
- when 'registration'
- return not Features.externalAuthenticationSystemUsed() or Settings.overleaf?
- when 'github-sync'
- return Settings.enableGithubSync
- when 'git-bridge'
- return Settings.enableGitBridge
- when 'v1-return-message'
- return Settings.accountMerge? and Settings.overleaf? and !Settings.forceImportToV2
- when 'custom-togglers'
- return Settings.overleaf?
- when 'oauth'
- return Settings.oauth?
- when 'publish-templates'
- return true
- when 'view-templates'
- return !Settings.overleaf?
- when 'affiliations'
- return Settings?.apis?.v1?.url?
- when 'redirect-sl'
- return Settings.redirectToV2?
- when 'force-import-to-v2'
- return Settings.forceImportToV2
- else
- throw new Error("unknown feature: #{feature}")
diff --git a/services/web/app/coffee/infrastructure/FileWriter.coffee b/services/web/app/coffee/infrastructure/FileWriter.coffee
deleted file mode 100644
index e8b9de8fea..0000000000
--- a/services/web/app/coffee/infrastructure/FileWriter.coffee
+++ /dev/null
@@ -1,60 +0,0 @@
-fs = require 'fs'
-logger = require 'logger-sharelatex'
-uuid = require 'uuid'
-_ = require 'underscore'
-Settings = require 'settings-sharelatex'
-request = require 'request'
-
-module.exports = FileWriter =
-
- ensureDumpFolderExists: (callback=(error)->) ->
- fs.mkdir Settings.path.dumpFolder, (error) ->
- if error? and error.code != 'EEXIST'
- # Ignore error about already existing
- return callback(error)
- callback(null)
-
- writeLinesToDisk: (identifier, lines, callback = (error, fsPath)->) ->
- FileWriter.writeContentToDisk(identifier, lines.join('\n'), callback)
-
- writeContentToDisk: (identifier, content, callback = (error, fsPath)->) ->
- callback = _.once(callback)
- fsPath = "#{Settings.path.dumpFolder}/#{identifier}_#{uuid.v4()}"
- FileWriter.ensureDumpFolderExists (error) ->
- return callback(error) if error?
- fs.writeFile fsPath, content, (error) ->
- return callback(error) if error?
- callback(null, fsPath)
-
- writeStreamToDisk: (identifier, stream, callback = (error, fsPath) ->) ->
- callback = _.once(callback)
- fsPath = "#{Settings.path.dumpFolder}/#{identifier}_#{uuid.v4()}"
-
- stream.pause()
- FileWriter.ensureDumpFolderExists (error) ->
- return callback(error) if error?
- stream.resume()
-
- writeStream = fs.createWriteStream(fsPath)
- stream.pipe(writeStream)
-
- stream.on 'error', (err)->
- logger.err {err, identifier, fsPath}, "[writeStreamToDisk] something went wrong with incoming stream"
- callback(err)
- writeStream.on 'error', (err)->
- logger.err {err, identifier, fsPath}, "[writeStreamToDisk] something went wrong with writing to disk"
- callback(err)
- writeStream.on "finish", ->
- logger.log {identifier, fsPath}, "[writeStreamToDisk] write stream finished"
- callback null, fsPath
-
- writeUrlToDisk: (identifier, url, callback = (error, fsPath) ->) ->
- callback = _.once(callback)
- stream = request.get(url)
- stream.on 'response', (response) ->
- if 200 <= response.statusCode < 300
- FileWriter.writeStreamToDisk identifier, stream, callback
- else
- err = new Error("bad response from url: #{response.statusCode}")
- logger.err {err, identifier, url}, err.message
- callback(err)
diff --git a/services/web/app/coffee/infrastructure/GeoIpLookup.coffee b/services/web/app/coffee/infrastructure/GeoIpLookup.coffee
deleted file mode 100644
index e2b36e94ab..0000000000
--- a/services/web/app/coffee/infrastructure/GeoIpLookup.coffee
+++ /dev/null
@@ -1,52 +0,0 @@
-request = require("request")
-settings = require("settings-sharelatex")
-_ = require("underscore")
-logger = require("logger-sharelatex")
-URL = require("url")
-
-currencyMappings = {
- "GB":"GBP"
- "US":"USD"
- "CH":"CHF"
- "NZ":"NZD"
- "AU":"AUD"
- "DK":"DKK"
- "NO":"NOK"
- "CA":"CAD"
- "SE":"SEK"
-}
-
-# Countries which would likely prefer Euro's
-EuroCountries = ["AT", "BE", "BG", "HR", "CY", "CZ",
-"EE", "FI", "FR", "DE", "EL", "HU", "IE",
-"IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT",
-"RO", "SK", "SI", "ES"]
-
-_.each EuroCountries, (country)-> currencyMappings[country] = "EUR"
-
-module.exports = GeoIpLookup =
-
- getDetails : (ip, callback)->
- if !ip?
- e = new Error("no ip passed")
- return callback(e)
- ip = ip.trim().split(" ")[0]
- opts =
- url: URL.resolve(settings.apis.geoIpLookup.url,ip)
- timeout: 1000
- json:true
- logger.log ip:ip, opts:opts, "getting geo ip details"
- request.get opts, (err, res, ipDetails)->
- if err?
- logger.err err:err, ip:ip, "error getting ip details"
- callback(err, ipDetails)
-
- getCurrencyCode : (ip, callback)->
- GeoIpLookup.getDetails ip, (err, ipDetails)->
- if err? or !ipDetails?
- logger.err err:err, ip:ip, "problem getting currencyCode for ip, defaulting to USD"
- return callback(null, "USD")
- countryCode = ipDetails?.country_code?.toUpperCase()
- currencyCode = currencyMappings[countryCode] || "USD"
- logger.log ip:ip, currencyCode:currencyCode, ipDetails:ipDetails, "got currencyCode for ip"
- callback(err, currencyCode, countryCode)
diff --git a/services/web/app/coffee/infrastructure/Keys.coffee b/services/web/app/coffee/infrastructure/Keys.coffee
deleted file mode 100644
index 2966f35aa3..0000000000
--- a/services/web/app/coffee/infrastructure/Keys.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports =
-
- queue:
- web_to_tpds_http_requests: "web_to_tpds_http_requests"
- tpds_to_web_http_requests: "tpds_to_web_http_requests"
diff --git a/services/web/app/coffee/infrastructure/LockManager.coffee b/services/web/app/coffee/infrastructure/LockManager.coffee
deleted file mode 100644
index 14be0dbb9e..0000000000
--- a/services/web/app/coffee/infrastructure/LockManager.coffee
+++ /dev/null
@@ -1,128 +0,0 @@
-metrics = require('metrics-sharelatex')
-Settings = require('settings-sharelatex')
-RedisWrapper = require("./RedisWrapper")
-rclient = RedisWrapper.client("lock")
-logger = require "logger-sharelatex"
-os = require "os"
-crypto = require "crypto"
-async = require "async"
-
-HOST = os.hostname()
-PID = process.pid
-RND = crypto.randomBytes(4).toString('hex')
-COUNT = 0
-
-LOCK_QUEUES = new Map() # queue lock requests for each name/id so they get the lock on a first-come first-served basis
-
-module.exports = LockManager =
- LOCK_TEST_INTERVAL: 50 # 50ms between each test of the lock
- MAX_TEST_INTERVAL: 1000 # back off to 1s between each test of the lock
- MAX_LOCK_WAIT_TIME: 10000 # 10s maximum time to spend trying to get the lock
- REDIS_LOCK_EXPIRY: 30 # seconds. Time until lock auto expires in redis
- SLOW_EXECUTION_THRESHOLD: 5000 # 5s, if execution takes longer than this then log
-
- # Use a signed lock value as described in
- # http://redis.io/topics/distlock#correct-implementation-with-a-single-instance
- # to prevent accidental unlocking by multiple processes
- randomLock : () ->
- time = Date.now()
- return "locked:host=#{HOST}:pid=#{PID}:random=#{RND}:time=#{time}:count=#{COUNT++}"
-
- unlockScript: 'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end'
-
- runWithLock: (namespace, id, runner = ( (releaseLock = (error) ->) -> ), callback = ( (error) -> )) ->
- # This error is defined here so we get a useful stacktrace
- slowExecutionError = new Error "slow execution during lock"
-
- timer = new metrics.Timer("lock.#{namespace}")
- key = "lock:web:#{namespace}:#{id}"
- LockManager._getLock key, namespace, (error, lockValue) ->
- return callback(error) if error?
-
- # The lock can expire in redis but the process carry on. This setTimout call
- # is designed to log if this happens.
- countIfExceededLockTimeout = () ->
- metrics.inc "lock.#{namespace}.exceeded_lock_timeout"
- logger.log "exceeded lock timeout", { namespace, id, slowExecutionError }
- exceededLockTimeout = setTimeout countIfExceededLockTimeout, LockManager.REDIS_LOCK_EXPIRY * 1000
-
- runner (error1, values...) ->
- LockManager._releaseLock key, lockValue, (error2) ->
- clearTimeout exceededLockTimeout
-
- timeTaken = new Date - timer.start
- if timeTaken > LockManager.SLOW_EXECUTION_THRESHOLD
- logger.log "slow execution during lock", { namespace, id, timeTaken, slowExecutionError }
-
- timer.done()
- error = error1 or error2
- return callback(error) if error?
- callback null, values...
-
- _tryLock : (key, namespace, callback = (err, isFree, lockValue)->)->
- lockValue = LockManager.randomLock()
- rclient.set key, lockValue, "EX", LockManager.REDIS_LOCK_EXPIRY, "NX", (err, gotLock)->
- return callback(err) if err?
- if gotLock == "OK"
- metrics.inc "lock.#{namespace}.try.success"
- callback err, true, lockValue
- else
- metrics.inc "lock.#{namespace}.try.failed"
- logger.log key: key, redis_response: gotLock, "lock is locked"
- callback err, false
-
- # it's sufficient to serialize within a process because that is where the parallel operations occur
- _getLock: (key, namespace, callback = (error, lockValue) ->) ->
- # this is what we need to do for each lock we want to request
- task = (next) ->
- LockManager._getLockByPolling key, namespace, (error, lockValue) ->
- # tell the queue to start trying to get the next lock (if any)
- next()
- # we have got a lock result, so we can continue with our own execution
- callback(error, lockValue)
- # create a queue for this key if needed
- queueName = "#{key}:#{namespace}"
- queue = LOCK_QUEUES.get queueName
- if !queue?
- handler = (fn, cb) ->
- fn(cb) # execute any function as our task
- # set up a new queue for this key
- queue = async.queue handler, 1
- queue.push task
- # remove the queue object when queue is empty
- queue.drain = () ->
- LOCK_QUEUES.delete queueName
- # store the queue in our global map
- LOCK_QUEUES.set queueName, queue
- else
- # queue the request to get the lock
- queue.push task
-
- _getLockByPolling: (key, namespace, callback = (error, lockValue) ->) ->
- startTime = Date.now()
- testInterval = LockManager.LOCK_TEST_INTERVAL
- attempts = 0
- do attempt = () ->
- if Date.now() - startTime > LockManager.MAX_LOCK_WAIT_TIME
- metrics.inc "lock.#{namespace}.get.failed"
- return callback(new Error("Timeout"))
-
- attempts += 1
- LockManager._tryLock key, namespace, (error, gotLock, lockValue) ->
- return callback(error) if error?
- if gotLock
- metrics.gauge "lock.#{namespace}.get.success.tries", attempts
- callback(null, lockValue)
- else
- setTimeout attempt, testInterval
-
- _releaseLock: (key, lockValue, callback)->
- rclient.eval LockManager.unlockScript, 1, key, lockValue, (err, result) ->
- if err?
- return callback(err)
- else if result? and result isnt 1 # successful unlock should release exactly one key
- logger.error {key:key, lockValue:lockValue, redis_err:err, redis_result:result}, "unlocking error"
- metrics.inc "unlock-error"
- return callback(new Error("tried to release timed out lock"))
- else
- callback(null,result)
diff --git a/services/web/app/coffee/infrastructure/LoggerSerializers.coffee b/services/web/app/coffee/infrastructure/LoggerSerializers.coffee
deleted file mode 100644
index 33e0078cc8..0000000000
--- a/services/web/app/coffee/infrastructure/LoggerSerializers.coffee
+++ /dev/null
@@ -1,40 +0,0 @@
-module.exports =
- user: (user) ->
- if !user?
- return null
- if !user._id?
- user = {_id : user}
- return {
- id: user._id
- email: user.email
- first_name: user.name
- last_name: user.name
- }
-
- project: (project) ->
- if !project?
- return null
- if !project._id?
- project = {_id: project}
- return {
- id: project._id
- name: project.name
- }
-
- docs: (docs) ->
- if !docs?.map?
- return
- docs.map (doc) ->
- {
- path: doc.path
- id: doc.doc
- }
-
- files: (files) ->
- if !files?.map?
- return
- files.map (file) ->
- {
- path: file.path
- id: file.file
- }
diff --git a/services/web/app/coffee/infrastructure/Modules.coffee b/services/web/app/coffee/infrastructure/Modules.coffee
deleted file mode 100644
index a7944e54dc..0000000000
--- a/services/web/app/coffee/infrastructure/Modules.coffee
+++ /dev/null
@@ -1,81 +0,0 @@
-fs = require "fs"
-Path = require "path"
-pug = require "pug"
-async = require "async"
-
-MODULE_BASE_PATH = Path.resolve(__dirname + "/../../../modules")
-
-module.exports = Modules =
- modules: []
- loadModules: () ->
- for moduleName in fs.readdirSync(MODULE_BASE_PATH)
- if fs.existsSync(Path.join(MODULE_BASE_PATH, moduleName, "index.js"))
- loadedModule = require(Path.join(MODULE_BASE_PATH, moduleName, "index"))
- loadedModule.name = moduleName
- @modules.push loadedModule
- Modules.attachHooks()
-
- applyRouter: (webRouter, privateApiRouter, publicApiRouter) ->
- for module in @modules
- module.router?.apply?(webRouter, privateApiRouter, publicApiRouter)
-
- applyNonCsrfRouter: (webRouter, privateApiRouter, publicApiRouter) ->
- for module in @modules
- module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter)
- module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter)
-
- viewIncludes: {}
- loadViewIncludes: (app) ->
- @viewIncludes = {}
- for module in @modules
- for view, partial of module.viewIncludes or {}
- @viewIncludes[view] ||= []
- filePath = Path.join(MODULE_BASE_PATH, module.name, "app/views", partial + ".pug")
- @viewIncludes[view].push pug.compileFile(filePath, doctype: "html")
-
- moduleIncludes: (view, locals) ->
- compiledPartials = Modules.viewIncludes[view] or []
- html = ""
- for compiledPartial in compiledPartials
- d = new Date()
- html += compiledPartial(locals)
- return html
-
- moduleIncludesAvailable: (view) ->
- return (Modules.viewIncludes[view] or []).length > 0
-
- moduleAssetFiles: (pathPrefix) ->
- assetFiles = []
- for module in @modules
- for assetFile in module.assetFiles or []
- assetFiles.push "#{pathPrefix}#{assetFile}"
- return assetFiles
-
- linkedFileAgentsIncludes: () ->
- agents = {}
- for module in @modules
- for name, agentFunction of module.linkedFileAgents
- agents[name] = agentFunction()
- return agents
-
- attachHooks: () ->
- for module in @modules
- if module.hooks?
- for hook, method of module.hooks
- Modules.hooks.attach hook, method
-
- hooks:
- _hooks: {}
- attach: (name, method) ->
- @_hooks[name] ?= []
- @_hooks[name].push method
-
- fire: (name, args..., callback) ->
- methods = @_hooks[name] or []
- call_methods = methods.map (method) ->
- return (cb) -> method(args..., cb)
- async.series call_methods, (error, results) ->
- return callback(error) if error?
- return callback null, results
-
-Modules.loadModules()
diff --git a/services/web/app/coffee/infrastructure/Mongoose.coffee b/services/web/app/coffee/infrastructure/Mongoose.coffee
deleted file mode 100644
index b1af2ac664..0000000000
--- a/services/web/app/coffee/infrastructure/Mongoose.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-mongoose = require('mongoose')
-Settings = require 'settings-sharelatex'
-logger = require('logger-sharelatex')
-
-mongoose.connect(Settings.mongo.url, {
- server: {poolSize: 10},
- config: {autoIndex: false}
-})
-
-mongoose.connection.on 'connected', () ->
- logger.log {url:Settings.mongo.url}, 'mongoose default connection open'
-
-mongoose.connection.on 'error', (err) ->
- logger.err err:err, 'mongoose error on default connection';
-
-mongoose.connection.on 'disconnected', () ->
- logger.log 'mongoose default connection disconnected'
-
-if process.env.MONGOOSE_DEBUG
- mongoose.set 'debug', (collectionName, method, query, doc) ->
- logger.debug 'mongoose debug', collectionName: collectionName, method: method, query: query, doc: doc
-
-module.exports = mongoose
diff --git a/services/web/app/coffee/infrastructure/PackageVersions.coffee b/services/web/app/coffee/infrastructure/PackageVersions.coffee
deleted file mode 100644
index d1c81b301d..0000000000
--- a/services/web/app/coffee/infrastructure/PackageVersions.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-version = {
- "pdfjs": "2.0.943"
- "moment": "2.9.0"
- "ace": "1.4.4" # Upgrade instructions: https://github.com/overleaf/write_latex/wiki/Upgrading-Ace
- "fineuploader": "5.15.4"
-}
-
-module.exports = {
- version: version
-
- lib: (name) ->
- if version[name]?
- return "#{name}-#{version[name]}"
- else
- return "#{name}"
-}
diff --git a/services/web/app/coffee/infrastructure/ProxyManager.coffee b/services/web/app/coffee/infrastructure/ProxyManager.coffee
deleted file mode 100644
index 3e7a037054..0000000000
--- a/services/web/app/coffee/infrastructure/ProxyManager.coffee
+++ /dev/null
@@ -1,46 +0,0 @@
-settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-request = require 'request'
-URL = require 'url'
-
-module.exports = ProxyManager =
- apply: (publicApiRouter) ->
- for proxyUrl, target of settings.proxyUrls
- do (target) ->
- method = target.options?.method || 'get'
- publicApiRouter[method] proxyUrl, ProxyManager.createProxy(target)
-
- createProxy: (target) ->
- (req, res, next) ->
- targetUrl = makeTargetUrl(target, req)
- logger.log targetUrl: targetUrl, reqUrl: req.url, "proxying url"
-
- options =
- url: targetUrl
- options.headers = { Cookie: req.headers.cookie } if req.headers?.cookie
- Object.assign(options, target.options) if target?.options?
- options.form = req.body if options.method in ['post', 'put']
- upstream = request(options)
- upstream.on "error", (error) ->
- logger.error err: error, "error in ProxyManager"
-
- # TODO: better handling of status code
- # see https://github.com/overleaf/write_latex/wiki/Streams-and-pipes-in-Node.js
- upstream.pipe(res)
-
-# make a URL from a proxy target.
-# if the query is specified, set/replace the target's query with the given query
-makeTargetUrl = (target, req) ->
- targetUrl = URL.parse(parseSettingUrl(target, req))
- if req.query? and Object.keys(req.query).length > 0
- targetUrl.query = req.query
- targetUrl.search = null # clear `search` as it takes precedence over `query`
- targetUrl.format()
-
-parseSettingUrl = (target, { params }) ->
- return target if typeof target is 'string'
- if typeof target.path is 'function'
- path = target.path(params)
- else
- path = target.path
- "#{target.baseUrl}#{path or ''}"
diff --git a/services/web/app/coffee/infrastructure/RandomLogging.coffee b/services/web/app/coffee/infrastructure/RandomLogging.coffee
deleted file mode 100644
index 6657fb3aae..0000000000
--- a/services/web/app/coffee/infrastructure/RandomLogging.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-_ = require('underscore')
-metrics = require('metrics-sharelatex')
-
-do trackOpenSockets = ->
- metrics.gauge("http.open-sockets", _.size(require('http').globalAgent.sockets.length), 0.5)
- setTimeout(trackOpenSockets, 1000)
diff --git a/services/web/app/coffee/infrastructure/RateLimiter.coffee b/services/web/app/coffee/infrastructure/RateLimiter.coffee
deleted file mode 100644
index 519bf5fc87..0000000000
--- a/services/web/app/coffee/infrastructure/RateLimiter.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-settings = require("settings-sharelatex")
-Metrics = require('metrics-sharelatex')
-RedisWrapper = require('./RedisWrapper')
-rclient = RedisWrapper.client('ratelimiter')
-RollingRateLimiter = require('rolling-rate-limiter')
-
-
-module.exports = RateLimiter =
-
- addCount: (opts, callback = (err, shouldProcess)->)->
- namespace = "RateLimit:#{opts.endpointName}:"
- k = "{#{opts.subjectName}}"
- limiter = RollingRateLimiter({
- redis: rclient,
- namespace: namespace,
- interval: opts.timeInterval * 1000,
- maxInInterval: opts.throttle
- })
- limiter k, (err, timeLeft, actionsLeft) ->
- if err?
- return callback(err)
- allowed = timeLeft == 0
- Metrics.inc "rate-limit-hit.#{opts.endpointName}", 1, {path: opts.endpointName} unless allowed
- callback(null, allowed)
-
- clearRateLimit: (endpointName, subject, callback) ->
- # same as the key which will be built by RollingRateLimiter (namespace+k)
- keyName = "RateLimit:#{endpointName}:{#{subject}}"
- rclient.del keyName, callback
diff --git a/services/web/app/coffee/infrastructure/RedirectManager.coffee b/services/web/app/coffee/infrastructure/RedirectManager.coffee
deleted file mode 100644
index d2a9f4b5cc..0000000000
--- a/services/web/app/coffee/infrastructure/RedirectManager.coffee
+++ /dev/null
@@ -1,44 +0,0 @@
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-URL = require('url')
-querystring = require('querystring')
-
-module.exports = RedirectManager =
- apply: (webRouter) ->
- for redirectUrl, target of settings.redirects
- for method in (target.methods or ['get'])
- webRouter[method] redirectUrl, RedirectManager.createRedirect(target)
-
- createRedirect: (target) ->
- (req, res, next) ->
- return next() if req.headers?['x-skip-redirects']?
- code = 302
- if typeof target is 'string'
- url = target
- else
- if req.method != "GET"
- code = 307
-
- if typeof target.url == "function"
- url = target.url(req.params)
- if !url
- return next()
- else
- url = target.url
-
- # Special handling for redirecting to v1, to ensure that query params
- # are encoded
- if target.authWithV1
- url = "/sign_in_to_v1?" + querystring.stringify(return_to: url + getQueryString(req))
- return res.redirect code, url
-
- if target.baseUrl?
- url = "#{target.baseUrl}#{url}"
- res.redirect code, url + getQueryString(req)
-
-# Naively get the query params string. Stringifying the req.query object may
-# have differences between Express and Rails, so safer to just pass the raw
-# string
-getQueryString = (req) ->
- {search} = URL.parse(req.url)
- if search then search else ""
diff --git a/services/web/app/coffee/infrastructure/RedisWrapper.coffee b/services/web/app/coffee/infrastructure/RedisWrapper.coffee
deleted file mode 100644
index 523785427e..0000000000
--- a/services/web/app/coffee/infrastructure/RedisWrapper.coffee
+++ /dev/null
@@ -1,14 +0,0 @@
-Settings = require 'settings-sharelatex'
-redis = require 'redis-sharelatex'
-
-# A per-feature interface to Redis,
-# looks up the feature in `settings.redis`
-# and returns an appropriate client.
-# Necessary because we don't want to migrate web over
-# to redis-cluster all at once.
-module.exports = Redis =
- # feature = 'websessions' | 'ratelimiter' | ...
- client: (feature) ->
- redisFeatureSettings = Settings.redis[feature] or Settings.redis.web
- rclient = redis.createClient(redisFeatureSettings)
- return rclient
diff --git a/services/web/app/coffee/infrastructure/Server.coffee b/services/web/app/coffee/infrastructure/Server.coffee
deleted file mode 100644
index 913020cf83..0000000000
--- a/services/web/app/coffee/infrastructure/Server.coffee
+++ /dev/null
@@ -1,208 +0,0 @@
-Path = require "path"
-express = require('express')
-Settings = require('settings-sharelatex')
-logger = require 'logger-sharelatex'
-metrics = require('metrics-sharelatex')
-crawlerLogger = require('./CrawlerLogger')
-expressLocals = require('./ExpressLocals')
-Router = require('../router')
-helmet = require "helmet"
-UserSessionsRedis = require('../Features/User/UserSessionsRedis')
-Csrf = require('./Csrf')
-
-sessionsRedisClient = UserSessionsRedis.client()
-
-session = require("express-session")
-RedisStore = require('connect-redis')(session)
-bodyParser = require('body-parser')
-methodOverride = require('method-override')
-cookieParser = require('cookie-parser')
-bearerToken = require('express-bearer-token')
-
-# Init the session store
-sessionStore = new RedisStore(client:sessionsRedisClient)
-
-passport = require('passport')
-LocalStrategy = require('passport-local').Strategy
-
-Mongoose = require("./Mongoose")
-
-oneDayInMilliseconds = 86400000
-ReferalConnect = require('../Features/Referal/ReferalConnect')
-RedirectManager = require("./RedirectManager")
-ProxyManager = require("./ProxyManager")
-translations = require("translations-sharelatex").setup(Settings.i18n)
-Modules = require "./Modules"
-
-ErrorController = require "../Features/Errors/ErrorController"
-UserSessionsManager = require "../Features/User/UserSessionsManager"
-AuthenticationController = require "../Features/Authentication/AuthenticationController"
-
-
-metrics.event_loop?.monitor(logger)
-
-if Settings.cacheStaticAssets
- staticCacheAge = (oneDayInMilliseconds * 365)
-else
- staticCacheAge = 0
-
-app = express()
-
-webRouter = express.Router()
-privateApiRouter = express.Router()
-publicApiRouter = express.Router()
-
-if Settings.behindProxy
- app.enable('trust proxy')
-
-webRouter.use express.static(__dirname + '/../../../public', {maxAge: staticCacheAge })
-app.set 'views', __dirname + '/../../views'
-app.set 'view engine', 'pug'
-Modules.loadViewIncludes app
-
-
-
-app.use bodyParser.urlencoded({ extended: true, limit: "2mb"})
-# Make sure we can process twice the max doc length, to allow for
-# - the doc content
-# - text ranges spanning the whole doc
-# Also allow some overhead for JSON encoding
-app.use bodyParser.json({limit: 2 * Settings.max_doc_length + 64 * 1024}) # 64kb overhead
-app.use methodOverride()
-app.use bearerToken()
-
-app.use metrics.http.monitor(logger)
-RedirectManager.apply(webRouter)
-ProxyManager.apply(publicApiRouter)
-
-
-webRouter.use cookieParser(Settings.security.sessionSecret)
-webRouter.use session
- resave: false
- saveUninitialized:false
- secret:Settings.security.sessionSecret
- proxy: Settings.behindProxy
- cookie:
- domain: Settings.cookieDomain
- maxAge: Settings.cookieSessionLength
- secure: Settings.secureCookie
- store: sessionStore
- key: Settings.cookieName
- rolling: true
-
-# passport
-webRouter.use passport.initialize()
-webRouter.use passport.session()
-
-passport.use(new LocalStrategy(
- {
- passReqToCallback: true,
- usernameField: 'email',
- passwordField: 'password'
- },
- AuthenticationController.doPassportLogin
-))
-passport.serializeUser(AuthenticationController.serializeUser)
-passport.deserializeUser(AuthenticationController.deserializeUser)
-
-Modules.hooks.fire 'passportSetup', passport, (err) ->
- if err?
- logger.err {err}, "error setting up passport in modules"
-
-Modules.applyNonCsrfRouter(webRouter, privateApiRouter, publicApiRouter)
-
-webRouter.csrf = new Csrf()
-webRouter.use webRouter.csrf.middleware
-webRouter.use translations.expressMiddlewear
-webRouter.use translations.setLangBasedOnDomainMiddlewear
-
-# Measure expiry from last request, not last login
-webRouter.use (req, res, next) ->
- req.session.touch()
- if AuthenticationController.isUserLoggedIn(req)
- UserSessionsManager.touch(AuthenticationController.getSessionUser(req), (err)->)
- next()
-
-webRouter.use ReferalConnect.use
-expressLocals(app, webRouter, privateApiRouter, publicApiRouter)
-
-if app.get('env') == 'production'
- logger.info "Production Enviroment"
- app.enable('view cache')
-
-app.use (req, res, next)->
- metrics.inc "http-request"
- crawlerLogger.log(req)
- next()
-
-webRouter.use (req, res, next) ->
- if Settings.siteIsOpen
- next()
- else
- res.status(503)
- res.render("general/closed", {title:"maintenance"})
-
-webRouter.use (req, res, next) ->
- if Settings.editorIsOpen
- next()
- else if req.url.indexOf("/admin") == 0
- next()
- else
- res.status(503)
- res.render("general/closed", {title:"maintenance"})
-
-# add security headers using Helmet
-webRouter.use (req, res, next) ->
- isLoggedIn = AuthenticationController.isUserLoggedIn(req)
- isProjectPage = !!req.path.match('^/project/[a-f0-9]{24}$')
-
- helmet({ # note that more headers are added by default
- dnsPrefetchControl: false
- referrerPolicy: { policy: 'origin-when-cross-origin' }
- noCache: isLoggedIn || isProjectPage
- noSniff: false
- hsts: false
- frameguard: false
- })(req, res, next)
-
-profiler = require "v8-profiler-node8"
-privateApiRouter.get "/profile", (req, res) ->
- time = parseInt(req.query.time || "1000")
- profiler.startProfiling("test")
- setTimeout () ->
- profile = profiler.stopProfiling("test")
- res.json(profile)
- , time
-
-privateApiRouter.get "/heapdump", (req, res)->
- require('heapdump').writeSnapshot '/tmp/' + Date.now() + '.web.heapsnapshot', (err, filename)->
- res.send filename
-
-logger.info ("creating HTTP server").yellow
-server = require('http').createServer(app)
-
-# provide settings for separate web and api processes
-# if enableApiRouter and enableWebRouter are not defined they default
-# to true.
-notDefined = (x) -> !x?
-enableApiRouter = Settings.web?.enableApiRouter
-if enableApiRouter or notDefined(enableApiRouter)
- logger.info("providing api router");
- app.use(privateApiRouter)
- app.use(ErrorController.handleApiError)
-
-enableWebRouter = Settings.web?.enableWebRouter
-if enableWebRouter or notDefined(enableWebRouter)
- logger.info("providing web router");
- app.use(publicApiRouter) # public API goes with web router for public access
- app.use(ErrorController.handleApiError)
- app.use(webRouter)
- app.use(ErrorController.handleError)
-
-metrics.injectMetricsRoute(webRouter)
-
-router = new Router(webRouter, privateApiRouter, publicApiRouter)
-
-module.exports =
- app: app
- server: server
diff --git a/services/web/app/coffee/infrastructure/Sixpack.coffee b/services/web/app/coffee/infrastructure/Sixpack.coffee
deleted file mode 100644
index 769300c397..0000000000
--- a/services/web/app/coffee/infrastructure/Sixpack.coffee
+++ /dev/null
@@ -1,104 +0,0 @@
-settings = require("settings-sharelatex")
-request = require("request")
-logger = require("logger-sharelatex")
-
-
-
-timeout = if process.env.NODE_ENV == "production" then 500 else 5000
-logger.log "using timeout of #{timeout}ms for sixpack server calls"
-
-generate_client_id = ->
- # from http://stackoverflow.com/questions/105034
- 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace /[xy]/g, (c) ->
- r = Math.random() * 16 | 0
- v = if c == 'x' then r else r & 0x3 | 0x8
- v.toString 16
-
-_request_uri = (endpoint, params) ->
- query_string = []
- e = encodeURIComponent
- for key of params
- if params.hasOwnProperty(key)
- vals = params[key]
- if Object::toString.call(vals) != '[object Array]'
- vals = [ vals ]
- i = 0
- while i < vals.length
- query_string.push e(key) + '=' + e(vals[i])
- i += 1
- if query_string.length
- endpoint += '?' + query_string.join('&')
- endpoint
-
-_request = (uri, params, callback)->
- opts =
- uri:_request_uri(uri, params)
- json:true
- timeout:timeout
- request.get opts, (err, res, body)->
- callback err, body
-
-module.exports = sixpack =
-
- client: (user_id)->
- client = new sixpack.Session(user_id, settings.apis.sixpack.url)
- return client
-
- Session : (client_id, base_url, ip_address, user_agent) ->
-
- @client_id = client_id or sixpack.generate_client_id()
- @base_url = base_url or sixpack.base_url
-
- participate: (experiment_name, alternatives, force, callback) =>
- if typeof force == 'function'
- callback = force
- force = null
- if !/^[a-z0-9][a-z0-9\-_ ]*$/.test(experiment_name)
- return callback(new Error('Bad experiment_name'))
- if alternatives.length < 2
- return callback(new Error('Must specify at least 2 alternatives'))
- i = 0
- while i < alternatives.length
- if !/^[a-z0-9][a-z0-9\-_ ]*$/.test(alternatives[i])
- return callback(new Error('Bad alternative name: ' + alternatives[i]))
- i += 1
- params =
- client_id: @client_id
- experiment: experiment_name
- alternatives: alternatives
-
- if force != null and _in_array(alternatives, force)
- return callback(null,
- 'status': 'ok'
- 'alternative': 'name': force
- 'experiment':
- 'version': 0
- 'name': experiment_name
- 'client_id': @client_id)
-
- _request @base_url + '/participate', params, (err, res) ->
- if err?
- res =
- status: 'failed'
- error: err
- alternative: name: alternatives[0]
- callback null, res
-
- convert: (experiment_name, callback)=>
- if !/^[a-z0-9][a-z0-9\-_ ]*$/.test(experiment_name)
- return callback(new Error('Bad experiment_name'))
- params =
- client_id: @client_id
- experiment: experiment_name
- if @ip_address
- params.ip_address = @ip_address
- if @user_agent
- params.user_agent = @user_agent
- _request @base_url + '/convert', params, (err, res) ->
- if err?
- res =
- status: 'failed'
- error: err
- callback null, res
-
-
diff --git a/services/web/app/coffee/infrastructure/mongojs.coffee b/services/web/app/coffee/infrastructure/mongojs.coffee
deleted file mode 100644
index 4bf6a2b970..0000000000
--- a/services/web/app/coffee/infrastructure/mongojs.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-Settings = require "settings-sharelatex"
-mongojs = require "mongojs"
-db = mongojs(Settings.mongo.url, ["projects", "users", "userstubs", "tokens", "docSnapshots", "projectHistoryFailures"])
-module.exports =
- db: db
- ObjectId: mongojs.ObjectId
diff --git a/services/web/app/coffee/models/DeletedProject.coffee b/services/web/app/coffee/models/DeletedProject.coffee
deleted file mode 100644
index 7a2fdc16ad..0000000000
--- a/services/web/app/coffee/models/DeletedProject.coffee
+++ /dev/null
@@ -1,27 +0,0 @@
-mongoose = require('mongoose')
-Settings = require 'settings-sharelatex'
-ProjectSchema = require('./Project.js').ProjectSchema
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-DeleterDataSchema = new Schema
- deleterId: {type: ObjectId, ref: 'User'}
- deleterIpAddress: { type: String }
- deletedAt: { type: Date }
-
-DeletedProjectSchema = new Schema({
- deleterData : [DeleterDataSchema]
- project: [ProjectSchema]
-}, collection: 'deletedProjects')
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-DeletedProject = conn.model('DeletedProject', DeletedProjectSchema)
-
-mongoose.model 'DeletedProject', DeletedProjectSchema
-exports.DeletedProject = DeletedProject
-exports.DeletedProjectSchema = DeletedProjectSchema
diff --git a/services/web/app/coffee/models/Doc.coffee b/services/web/app/coffee/models/Doc.coffee
deleted file mode 100644
index 862638acb7..0000000000
--- a/services/web/app/coffee/models/Doc.coffee
+++ /dev/null
@@ -1,13 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-DocSchema = new Schema
- name : {type:String, default:'new doc'}
-
-
-mongoose.model 'Doc', DocSchema
-exports.Doc = mongoose.model 'Doc'
-exports.DocSchema = DocSchema
diff --git a/services/web/app/coffee/models/File.coffee b/services/web/app/coffee/models/File.coffee
deleted file mode 100644
index 121a8cabb6..0000000000
--- a/services/web/app/coffee/models/File.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-FileSchema = new Schema
- name : type:String, default:''
- created : type:Date, default: () -> new Date()
- rev : {type:Number, default:0}
- linkedFileData: { type: Schema.Types.Mixed }
- hash : type:String
-
-mongoose.model 'File', FileSchema
-exports.File = mongoose.model 'File'
-exports.FileSchema = FileSchema
diff --git a/services/web/app/coffee/models/Folder.coffee b/services/web/app/coffee/models/Folder.coffee
deleted file mode 100644
index 4c2bf04b64..0000000000
--- a/services/web/app/coffee/models/Folder.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-mongoose = require('mongoose')
-Settings = require 'settings-sharelatex'
-DocSchema = require('./Doc').DocSchema
-FileSchema = require('./File').FileSchema
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-FolderSchema = new Schema
- name : {type:String, default:'new folder'}
-
-FolderSchema.add
- docs : [DocSchema]
- fileRefs : [FileSchema]
- folders : [FolderSchema]
-
-
-mongoose.model('Folder', FolderSchema)
-exports.Folder = mongoose.model('Folder')
-exports.FolderSchema = FolderSchema
diff --git a/services/web/app/coffee/models/Institution.coffee b/services/web/app/coffee/models/Institution.coffee
deleted file mode 100644
index f025b00ea2..0000000000
--- a/services/web/app/coffee/models/Institution.coffee
+++ /dev/null
@@ -1,37 +0,0 @@
-mongoose = require 'mongoose'
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-request = require 'request'
-
-InstitutionSchema = new Schema
- v1Id: { type: Number, required: true }
- managerIds: [ type:ObjectId, ref:'User' ]
- metricsEmail: {
- optedOutUserIds: [ type:ObjectId, ref:'User' ]
- lastSent: { type : Date }
- }
-
-# fetch institution's data from v1 API. Errors are ignored
-InstitutionSchema.method 'fetchV1Data', (callback = (error, institution)->) ->
- url = "#{settings.apis.v1.url}/universities/list/#{this.v1Id}"
- request.get url, (error, response, body) =>
- try
- parsedBody = JSON.parse(body)
- catch error # log error and carry on without v1 data
- logger.err { model: 'Institution', v1Id: this.v1Id, error }, '[fetchV1DataError]'
- this.name = parsedBody?.name
- this.countryCode = parsedBody?.country_code
- this.departments = parsedBody?.departments
- this.portalSlug = parsedBody?.portal_slug
- callback(null, this)
-
-conn = mongoose.createConnection(settings.mongo.url, {
- server: {poolSize: settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-Institution = conn.model 'Institution', InstitutionSchema
-exports.Institution = Institution
-exports.InstitutionSchema = InstitutionSchema
diff --git a/services/web/app/coffee/models/OauthAccessToken.coffee b/services/web/app/coffee/models/OauthAccessToken.coffee
deleted file mode 100644
index 22f68c743a..0000000000
--- a/services/web/app/coffee/models/OauthAccessToken.coffee
+++ /dev/null
@@ -1,31 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-OauthAccessTokenSchema = new Schema(
- {
- accessToken: String
- accessTokenExpiresAt: Date
- oauthApplication_id: { type: ObjectId, ref: 'OauthApplication' }
- refreshToken: String
- refreshTokenExpiresAt: Date
- scope: String
- user_id: { type: ObjectId, ref: 'User' }
- },
- {
- collection: 'oauthAccessTokens'
- }
-)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-OauthAccessToken = conn.model('OauthAccessToken', OauthAccessTokenSchema)
-
-mongoose.model 'OauthAccessToken', OauthAccessTokenSchema
-exports.OauthAccessToken = OauthAccessToken
-exports.OauthAccessTokenSchema = OauthAccessTokenSchema
diff --git a/services/web/app/coffee/models/OauthApplication.coffee b/services/web/app/coffee/models/OauthApplication.coffee
deleted file mode 100644
index af68376d45..0000000000
--- a/services/web/app/coffee/models/OauthApplication.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-OauthApplicationSchema = new Schema(
- {
- id: String
- clientSecret: String
- grants: [ String ]
- name: String
- redirectUris: [ String ]
- scopes: [ String ]
- },
- {
- collection: 'oauthApplications'
- }
-)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-OauthApplication = conn.model('OauthApplication', OauthApplicationSchema)
-
-mongoose.model 'OauthApplication', OauthApplicationSchema
-exports.OauthApplication = OauthApplication
-exports.OauthApplicationSchema = OauthApplicationSchema
diff --git a/services/web/app/coffee/models/OauthAuthorizationCode.coffee b/services/web/app/coffee/models/OauthAuthorizationCode.coffee
deleted file mode 100644
index a37a469a1e..0000000000
--- a/services/web/app/coffee/models/OauthAuthorizationCode.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-OauthAuthorizationCodeSchema = new Schema(
- {
- authorizationCode: String
- expiresAt: Date
- oauthApplication_id: { type: ObjectId, ref: 'OauthApplication' }
- redirectUri: String
- scope: String
- user_id: { type: ObjectId, ref: 'User' }
- },
- {
- collection: 'oauthAuthorizationCodes'
- }
-)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-OauthAuthorizationCode = conn.model('OauthAuthorizationCode', OauthAuthorizationCodeSchema)
-
-mongoose.model 'OauthAuthorizationCode', OauthAuthorizationCodeSchema
-exports.OauthAuthorizationCode = OauthAuthorizationCode
-exports.OauthAuthorizationCodeSchema = OauthAuthorizationCodeSchema
diff --git a/services/web/app/coffee/models/Project.coffee b/services/web/app/coffee/models/Project.coffee
deleted file mode 100644
index 0a46935d82..0000000000
--- a/services/web/app/coffee/models/Project.coffee
+++ /dev/null
@@ -1,115 +0,0 @@
-mongoose = require('mongoose')
-Settings = require 'settings-sharelatex'
-_ = require('underscore')
-FolderSchema = require('./Folder.js').FolderSchema
-logger = require('logger-sharelatex')
-concreteObjectId = require('mongoose').Types.ObjectId
-Errors = require "../Features/Errors/Errors"
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-DeletedDocSchema = new Schema
- name: String
- deletedAt: {type: Date}
-
-DeletedFileSchema = new Schema
- name : String
- created : type:Date
- linkedFileData : { type: Schema.Types.Mixed }
- hash : type:String
- deletedAt : {type: Date}
-
-ProjectSchema = new Schema
- name : {type:String, default:'new project'}
- lastUpdated : {type:Date, default: () -> new Date()}
- lastUpdatedBy : {type:ObjectId, ref: 'User'}
- lastOpened : {type:Date}
- active : { type: Boolean, default: true }
- owner_ref : {type:ObjectId, ref:'User'}
- collaberator_refs : [ type:ObjectId, ref:'User' ]
- readOnly_refs : [ type:ObjectId, ref:'User' ]
- rootDoc_id : {type: ObjectId}
- rootFolder : [FolderSchema]
- version : {type: Number} # incremented for every change in the project structure (folders and filenames)
- publicAccesLevel : {type: String, default: 'private'}
- compiler : {type:String, default:'pdflatex'}
- spellCheckLanguage : {type:String, default:'en'}
- deletedByExternalDataSource : {type: Boolean, default: false}
- description : {type:String, default:''}
- archived : { type: Boolean }
- deletedDocs : [DeletedDocSchema]
- deletedFiles : [DeletedFileSchema]
- imageName : { type: String }
- brandVariationId : { type: String }
- track_changes : { type: Object }
- tokens :
- readOnly : {
- type: String,
- index: {
- unique: true,
- partialFilterExpression: {'tokens.readOnly': {$exists: true}}
- }
- }
- readAndWrite : {
- type: String,
- index: {
- unique: true,
- partialFilterExpression: {'tokens.readAndWrite': {$exists: true}}
- }
- }
- readAndWritePrefix: {
- type: String,
- index: {
- unique: true,
- partialFilterExpression: {'tokens.readAndWritePrefix': {$exists: true}}
- }
- }
- tokenAccessReadOnly_refs : [ type:ObjectId, ref:'User' ]
- tokenAccessReadAndWrite_refs : [ type:ObjectId, ref:'User' ]
- fromV1TemplateId: { type: Number }
- fromV1TemplateVersionId: { type: Number }
- overleaf :
- id : { type: Number }
- imported_at_ver_id : { type: Number }
- token : { type: String }
- read_token : { type: String }
- history :
- id : { type: Number }
- display : { type: Boolean }
- upgradedAt : { type: Date }
- collabratecUsers : [
- {
- user_id : { type: ObjectId, ref:'User' }
- collabratec_document_id : { type: String }
- collabratec_privategroup_id : { type: String }
- added_at : { type: Date, default: () -> new Date() }
- }
- ]
-
-ProjectSchema.statics.getProject = (project_or_id, fields, callback)->
- if project_or_id._id?
- callback null, project_or_id
- else
- try
- concreteObjectId(project_or_id.toString())
- catch e
- return callback(new Errors.NotFoundError(e.message))
- this.findById project_or_id, fields, callback
-
-applyToAllFilesRecursivly = ProjectSchema.statics.applyToAllFilesRecursivly = (folder, fun)->
- _.each folder.fileRefs, (file)->
- fun(file)
- _.each folder.folders, (folder)->
- applyToAllFilesRecursivly(folder, fun)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-Project = conn.model('Project', ProjectSchema)
-
-mongoose.model 'Project', ProjectSchema
-exports.Project = Project
-exports.ProjectSchema = ProjectSchema
diff --git a/services/web/app/coffee/models/ProjectInvite.coffee b/services/web/app/coffee/models/ProjectInvite.coffee
deleted file mode 100644
index 3be74f63ac..0000000000
--- a/services/web/app/coffee/models/ProjectInvite.coffee
+++ /dev/null
@@ -1,43 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-
-EXPIRY_IN_SECONDS = 60 * 60 * 24 * 30
-
-ExpiryDate = () ->
- timestamp = new Date()
- timestamp.setSeconds(timestamp.getSeconds() + EXPIRY_IN_SECONDS)
- return timestamp
-
-
-
-ProjectInviteSchema = new Schema(
- {
- email: String
- token: String
- sendingUserId: ObjectId
- projectId: ObjectId
- privileges: String
- createdAt: {type: Date, default: Date.now}
- expires: {type: Date, default: ExpiryDate, index: {expireAfterSeconds: 10}}
- },
- {
- collection: 'projectInvites'
- }
-)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-ProjectInvite = conn.model('ProjectInvite', ProjectInviteSchema)
-
-mongoose.model 'ProjectInvite', ProjectInviteSchema
-exports.ProjectInvite = ProjectInvite
-exports.ProjectInviteSchema = ProjectInviteSchema
-exports.EXPIRY_IN_SECONDS = EXPIRY_IN_SECONDS
diff --git a/services/web/app/coffee/models/Publisher.coffee b/services/web/app/coffee/models/Publisher.coffee
deleted file mode 100644
index e4496b0d42..0000000000
--- a/services/web/app/coffee/models/Publisher.coffee
+++ /dev/null
@@ -1,38 +0,0 @@
-mongoose = require 'mongoose'
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-settings = require 'settings-sharelatex'
-logger = require 'logger-sharelatex'
-request = require 'request'
-
-PublisherSchema = new Schema
- slug: { type: String, required: true }
- managerIds: [ type:ObjectId, ref:'User' ]
-
-# fetch publisher's (brand on v1) data from v1 API. Errors are ignored
-PublisherSchema.method 'fetchV1Data', (callback = (error, publisher)->) ->
- request {
- baseUrl: settings.apis.v1.url
- url: "/api/v2/brands/#{this.slug}"
- method: 'GET'
- auth:
- user: settings.apis.v1.user
- pass: settings.apis.v1.pass
- sendImmediately: true
- }, (error, response, body) =>
- try
- parsedBody = JSON.parse(body)
- catch error # log error and carry on without v1 data
- logger.err { model: 'Publisher', slug: this.slug, error }, '[fetchV1DataError]'
- this.name = parsedBody?.name
- this.partner = parsedBody?.partner
- callback(null, this)
-
-conn = mongoose.createConnection(settings.mongo.url, {
- server: {poolSize: settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-Publisher = conn.model 'Publisher', PublisherSchema
-exports.Publisher = Publisher
-exports.PublisherSchema = PublisherSchema
diff --git a/services/web/app/coffee/models/Subscription.coffee b/services/web/app/coffee/models/Subscription.coffee
deleted file mode 100644
index d094f88971..0000000000
--- a/services/web/app/coffee/models/Subscription.coffee
+++ /dev/null
@@ -1,47 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-TeamInviteSchema = require('./TeamInvite').TeamInviteSchema
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-SubscriptionSchema = new Schema
- admin_id : {type:ObjectId, ref:'User', index: {unique: true, dropDups: true}}
- manager_ids : [ type:ObjectId, ref:'User' ]
- member_ids : [ type:ObjectId, ref:'User' ]
- invited_emails: [ String ]
- teamInvites : [ TeamInviteSchema ]
- recurlySubscription_id : String
- teamName : {type: String}
- teamNotice : {type: String}
- planCode : {type: String}
- groupPlan : {type: Boolean, default: false}
- membersLimit: {type:Number, default:0}
- customAccount: Boolean
- overleaf:
- id:
- type: Number
- index:
- unique: true,
- partialFilterExpression: {'overleaf.id': {$exists: true}}
-
-
-SubscriptionSchema.statics.findAndModify = (query, update, callback)->
- self = @
- this.update query, update, ->
- self.findOne query, callback
-
-# Subscriptions have no v1 data to fetch
-SubscriptionSchema.method 'fetchV1Data', (callback = (error, subscription)->) ->
- callback(null, this)
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-Subscription = conn.model('Subscription', SubscriptionSchema)
-
-mongoose.model 'Subscription', SubscriptionSchema
-exports.Subscription = Subscription
-exports.SubscriptionSchema = SubscriptionSchema
diff --git a/services/web/app/coffee/models/SystemMessage.coffee b/services/web/app/coffee/models/SystemMessage.coffee
deleted file mode 100644
index ccaa2028e2..0000000000
--- a/services/web/app/coffee/models/SystemMessage.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-SystemMessageSchema = new Schema
- content : type: String, default:''
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-
-exports.SystemMessage = conn.model('SystemMessage', SystemMessageSchema)
diff --git a/services/web/app/coffee/models/TeamInvite.coffee b/services/web/app/coffee/models/TeamInvite.coffee
deleted file mode 100644
index e488724745..0000000000
--- a/services/web/app/coffee/models/TeamInvite.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-mongoose = require 'mongoose'
-Settings = require 'settings-sharelatex'
-
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-TeamInviteSchema = new Schema
- email : { type: String, required: true }
- token : { type: String }
- inviterName : { type: String }
- sentAt : { type: Date }
-
-mongoose.model 'TeamInvite', TeamInviteSchema
-exports.TeamInvite = mongoose.model 'TeamInvite'
-exports.TeamInviteSchema = TeamInviteSchema
diff --git a/services/web/app/coffee/models/User.coffee b/services/web/app/coffee/models/User.coffee
deleted file mode 100644
index d0f76a4d27..0000000000
--- a/services/web/app/coffee/models/User.coffee
+++ /dev/null
@@ -1,92 +0,0 @@
-Project = require('./Project').Project
-Settings = require 'settings-sharelatex'
-_ = require('underscore')
-mongoose = require('mongoose')
-uuid = require('uuid')
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-# See https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address/574698#574698
-MAX_EMAIL_LENGTH = 254
-
-UserSchema = new Schema
- email : {type : String, default : '', maxlength: MAX_EMAIL_LENGTH }
- emails: [{
- email: { type : String, default : '', maxlength: MAX_EMAIL_LENGTH },
- reversedHostname: { type : String, default : '' },
- createdAt: { type : Date, default: () -> new Date() },
- confirmedAt: { type: Date }
- }],
- first_name : {type : String, default : ''}
- last_name : {type : String, default : ''}
- role : {type : String, default : ''}
- institution : {type : String, default : ''}
- hashedPassword : String
- isAdmin : {type : Boolean, default : false}
- staffAccess: {
- publisherMetrics: {type : Boolean, default: false}
- publisherManagement: {type : Boolean, default: false}
- institutionMetrics: {type : Boolean, default: false}
- institutionManagement: {type : Boolean, default: false}
- groupMetrics: {type : Boolean, default: false}
- groupManagement: {type : Boolean, default: false}
- }
- signUpDate : {type : Date, default: () -> new Date() }
- lastLoggedIn : {type : Date}
- lastLoginIp : {type : String, default : ''}
- loginCount : {type : Number, default: 0}
- holdingAccount : {type : Boolean, default: false}
- ace : {
- mode : {type : String, default: 'none'}
- theme : {type : String, default: 'textmate'}
- overallTheme : {type: String, default: "" }
- fontSize : {type : Number, default:'12'}
- autoComplete : {type : Boolean, default: true}
- autoPairDelimiters : {type : Boolean, default: true}
- spellCheckLanguage : {type : String, default: "en"}
- pdfViewer : {type : String, default: "pdfjs"}
- syntaxValidation : {type : Boolean}
- fontFamily : {type : String}
- lineHeight : {type : String}
- }
- features : {
- collaborators: { type:Number, default: Settings.defaultFeatures.collaborators }
- versioning: { type:Boolean, default: Settings.defaultFeatures.versioning }
- dropbox: { type:Boolean, default: Settings.defaultFeatures.dropbox }
- github: { type:Boolean, default: Settings.defaultFeatures.github }
- gitBridge: { type:Boolean, default: Settings.defaultFeatures.gitBridge }
- compileTimeout: { type:Number, default: Settings.defaultFeatures.compileTimeout }
- compileGroup: { type:String, default: Settings.defaultFeatures.compileGroup }
- templates: { type:Boolean, default: Settings.defaultFeatures.templates }
- references: { type:Boolean, default: Settings.defaultFeatures.references }
- trackChanges: { type:Boolean, default: Settings.defaultFeatures.trackChanges }
- mendeley: { type:Boolean, default: Settings.defaultFeatures.mendeley }
- zotero: { type:Boolean, default: Settings.defaultFeatures.zotero }
- referencesSearch: { type:Boolean, default: Settings.defaultFeatures.referencesSearch }
- }
- must_reconfirm:{ type:Boolean, default: false }
- referal_id : {type:String, default:() -> uuid.v4().split("-")[0]}
- refered_users: [ type:ObjectId, ref:'User' ]
- refered_user_count: { type:Number, default: 0 }
- refProviders: {
- mendeley: Boolean # coerce the refProviders values to Booleans
- zotero: Boolean
- }
- betaProgram: { type:Boolean, default: false}
- overleaf:
- id: { type: Number }
- accessToken: { type: String }
- refreshToken: { type: String }
- awareOfV2: { type:Boolean, default: false }
- thirdPartyIdentifiers: { type: Array, default: [] }
- migratedAt: { type: Date }
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-User = conn.model('User', UserSchema)
-
-model = mongoose.model 'User', UserSchema
-exports.User = User
diff --git a/services/web/app/coffee/models/UserStub.coffee b/services/web/app/coffee/models/UserStub.coffee
deleted file mode 100644
index 70dd1e60dc..0000000000
--- a/services/web/app/coffee/models/UserStub.coffee
+++ /dev/null
@@ -1,22 +0,0 @@
-Settings = require "settings-sharelatex"
-mongoose = require('mongoose')
-Schema = mongoose.Schema
-ObjectId = Schema.ObjectId
-
-UserStubSchema = new Schema
- email : { type : String, default : '' }
- first_name : { type : String, default : '' }
- last_name : { type : String, default : '' }
- overleaf : { id: { type: Number } }
- thirdPartyIdentifiers: { type: Array, default: [] }
- confirmed_at: Date
-
-conn = mongoose.createConnection(Settings.mongo.url, {
- server: {poolSize: Settings.mongo.poolSize || 10},
- config: {autoIndex: false}
-})
-
-UserStub = conn.model('UserStub', UserStubSchema)
-
-model = mongoose.model 'UserStub', UserStubSchema
-exports.UserStub = UserStub
diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee
deleted file mode 100644
index afb7c76a47..0000000000
--- a/services/web/app/coffee/router.coffee
+++ /dev/null
@@ -1,543 +0,0 @@
-AdminController = require('./Features/ServerAdmin/AdminController')
-ErrorController = require('./Features/Errors/ErrorController')
-ProjectController = require("./Features/Project/ProjectController")
-ProjectApiController = require("./Features/Project/ProjectApiController")
-SpellingController = require('./Features/Spelling/SpellingController')
-EditorController = require("./Features/Editor/EditorController")
-EditorRouter = require("./Features/Editor/EditorRouter")
-Settings = require('settings-sharelatex')
-TpdsController = require('./Features/ThirdPartyDataStore/TpdsController')
-SubscriptionRouter = require './Features/Subscription/SubscriptionRouter'
-UploadsRouter = require './Features/Uploads/UploadsRouter'
-metrics = require('metrics-sharelatex')
-ReferalController = require('./Features/Referal/ReferalController')
-AuthenticationController = require('./Features/Authentication/AuthenticationController')
-TagsController = require("./Features/Tags/TagsController")
-NotificationsController = require("./Features/Notifications/NotificationsController")
-CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter')
-UserInfoController = require('./Features/User/UserInfoController')
-UserController = require("./Features/User/UserController")
-UserEmailsController = require("./Features/User/UserEmailsController")
-UserPagesController = require('./Features/User/UserPagesController')
-DocumentController = require('./Features/Documents/DocumentController')
-CompileManager = require("./Features/Compile/CompileManager")
-CompileController = require("./Features/Compile/CompileController")
-ClsiCookieManager = require("./Features/Compile/ClsiCookieManager")(Settings.apis.clsi?.backendGroupName)
-HealthCheckController = require("./Features/HealthCheck/HealthCheckController")
-ProjectDownloadsController = require "./Features/Downloads/ProjectDownloadsController"
-FileStoreController = require("./Features/FileStore/FileStoreController")
-HistoryController = require("./Features/History/HistoryController")
-ExportsController = require("./Features/Exports/ExportsController")
-PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
-StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter")
-ChatController = require("./Features/Chat/ChatController")
-BlogController = require("./Features/Blog/BlogController")
-Modules = require "./infrastructure/Modules"
-RateLimiterMiddleware = require('./Features/Security/RateLimiterMiddleware')
-CooldownMiddleware = require('./Features/Cooldown/CooldownMiddleware')
-RealTimeProxyRouter = require('./Features/RealTimeProxy/RealTimeProxyRouter')
-InactiveProjectController = require("./Features/InactiveData/InactiveProjectController")
-ContactRouter = require("./Features/Contacts/ContactRouter")
-ReferencesController = require('./Features/References/ReferencesController')
-AuthorizationMiddleware = require('./Features/Authorization/AuthorizationMiddleware')
-BetaProgramController = require('./Features/BetaProgram/BetaProgramController')
-SudoModeController = require('./Features/SudoMode/SudoModeController')
-SudoModeMiddleware = require('./Features/SudoMode/SudoModeMiddleware')
-AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
-AnnouncementsController = require("./Features/Announcements/AnnouncementsController")
-MetaController = require('./Features/Metadata/MetaController')
-TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
-Features = require('./infrastructure/Features')
-LinkedFilesRouter = require './Features/LinkedFiles/LinkedFilesRouter'
-TemplatesRouter = require './Features/Templates/TemplatesRouter'
-InstitutionsController = require './Features/Institutions/InstitutionsController'
-UserMembershipRouter = require './Features/UserMembership/UserMembershipRouter'
-
-logger = require("logger-sharelatex")
-_ = require("underscore")
-
-module.exports = class Router
- constructor: (webRouter, privateApiRouter, publicApiRouter)->
- if !Settings.allowPublicAccess
- webRouter.all '*', AuthenticationController.requireGlobalLogin
-
-
- webRouter.get '/login', UserPagesController.loginPage
- AuthenticationController.addEndpointToLoginWhitelist '/login'
-
- webRouter.post '/login', AuthenticationController.passportLogin
-
- webRouter.get '/logout', UserPagesController.logoutPage
- webRouter.post '/logout', UserController.logout
-
- webRouter.get '/restricted', AuthorizationMiddleware.restricted
-
-
- if Features.hasFeature('registration')
- webRouter.get '/register', UserPagesController.registerPage
- AuthenticationController.addEndpointToLoginWhitelist '/register'
-
- EditorRouter.apply(webRouter, privateApiRouter)
- CollaboratorsRouter.apply(webRouter, privateApiRouter)
- SubscriptionRouter.apply(webRouter, privateApiRouter, publicApiRouter)
- UploadsRouter.apply(webRouter, privateApiRouter)
- PasswordResetRouter.apply(webRouter, privateApiRouter)
- StaticPagesRouter.apply(webRouter, privateApiRouter)
- RealTimeProxyRouter.apply(webRouter, privateApiRouter)
- ContactRouter.apply(webRouter, privateApiRouter)
- AnalyticsRouter.apply(webRouter, privateApiRouter, publicApiRouter)
- LinkedFilesRouter.apply(webRouter, privateApiRouter, publicApiRouter)
- TemplatesRouter.apply(webRouter)
- UserMembershipRouter.apply(webRouter)
-
- Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
-
- if Settings.enableSubscriptions
- webRouter.get '/user/bonus', AuthenticationController.requireLogin(), ReferalController.bonus
-
- if !Settings.overleaf?
- webRouter.get '/blog', BlogController.getIndexPage
- webRouter.get '/blog/*', BlogController.getPage
-
- webRouter.get '/user/activate', UserPagesController.activateAccountPage
- AuthenticationController.addEndpointToLoginWhitelist '/user/activate'
-
- webRouter.get '/user/settings',
- AuthenticationController.requireLogin(),
- SudoModeMiddleware.protectPage,
- UserPagesController.settingsPage
- webRouter.post '/user/settings', AuthenticationController.requireLogin(), UserController.updateUserSettings
- webRouter.post '/user/password/update',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: "change-password"
- maxRequests: 10
- timeInterval: 60
- }),
- UserController.changePassword
- webRouter.get '/user/emails',
- AuthenticationController.requireLogin(),
- UserEmailsController.list
- webRouter.get '/user/emails/confirm',
- UserEmailsController.showConfirm
- webRouter.post '/user/emails/confirm',
- RateLimiterMiddleware.rateLimit({
- endpointName: "confirm-email"
- maxRequests: 10
- timeInterval: 60
- }),
- UserEmailsController.confirm
- webRouter.post '/user/emails/resend_confirmation',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: "resend-confirmation"
- maxRequests: 10
- timeInterval: 60
- }),
- UserEmailsController.resendConfirmation
-
- if Features.hasFeature 'affiliations'
- webRouter.post '/user/emails',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: 'add-email',
- maxRequests: 10
- timeInterval: 60
- }),
- UserEmailsController.add
- webRouter.post '/user/emails/delete',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: 'delete-email',
- maxRequests: 10
- timeInterval: 60
- }),
- UserEmailsController.remove
- webRouter.post '/user/emails/default',
- AuthenticationController.requireLogin(),
- UserEmailsController.setDefault
- webRouter.post '/user/emails/endorse',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: "endorse-email"
- maxRequests: 30
- timeInterval: 60
- }),
- UserEmailsController.endorse
-
-
- webRouter.get '/user/sessions',
- AuthenticationController.requireLogin(),
- SudoModeMiddleware.protectPage,
- UserPagesController.sessionsPage
- webRouter.post '/user/sessions/clear', AuthenticationController.requireLogin(), UserController.clearSessions
-
- webRouter.delete '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe
- webRouter.post '/user/delete',
- RateLimiterMiddleware.rateLimit({
- endpointName: "delete-user"
- maxRequests: 10
- timeInterval: 60
- }),
- AuthenticationController.requireLogin(),
- UserController.tryDeleteUser
-
- webRouter.get '/user/personal_info', AuthenticationController.requireLogin(), UserInfoController.getLoggedInUsersPersonalInfo
- privateApiRouter.get '/user/:user_id/personal_info', AuthenticationController.httpAuth, UserInfoController.getPersonalInfo
-
- webRouter.get '/user/reconfirm', UserPagesController.renderReconfirmAccountPage
- # for /user/reconfirm POST, see password router
-
- webRouter.get '/user/projects', AuthenticationController.requireLogin(), ProjectController.userProjectsJson
- webRouter.get '/project/:Project_id/entities', AuthenticationController.requireLogin(),
- AuthorizationMiddleware.ensureUserCanReadProject,
- ProjectController.projectEntitiesJson
-
- webRouter.get '/project', AuthenticationController.requireLogin(), ProjectController.projectListPage
- webRouter.post '/project/new', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "create-project"
- maxRequests: 20
- timeInterval: 60
- }), ProjectController.newProject
-
- webRouter.get '/Project/:Project_id', RateLimiterMiddleware.rateLimit({
- endpointName: "open-project"
- params: ["Project_id"]
- maxRequests: 15
- timeInterval: 60
- }), AuthorizationMiddleware.ensureUserCanReadProject, ProjectController.loadEditor
- webRouter.get '/Project/:Project_id/file/:File_id', AuthorizationMiddleware.ensureUserCanReadProject, FileStoreController.getFile
- webRouter.post '/project/:Project_id/settings', AuthorizationMiddleware.ensureUserCanWriteProjectSettings, ProjectController.updateProjectSettings
- webRouter.post '/project/:Project_id/settings/admin', AuthorizationMiddleware.ensureUserCanAdminProject, ProjectController.updateProjectAdminSettings
-
- webRouter.post '/project/:Project_id/compile', RateLimiterMiddleware.rateLimit({
- endpointName: "compile-project-http"
- params: ["Project_id"]
- maxRequests: 800
- timeInterval: 60 * 60
- }), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.compile
-
- webRouter.post '/project/:Project_id/compile/stop', AuthorizationMiddleware.ensureUserCanReadProject, CompileController.stopCompile
-
- # LEGACY: Used by the web download buttons, adds filename header, TODO: remove at some future date
- webRouter.get '/project/:Project_id/output/output.pdf', AuthorizationMiddleware.ensureUserCanReadProject, CompileController.downloadPdf
-
- # PDF Download button
- webRouter.get /^\/download\/project\/([^\/]*)\/output\/output\.pdf$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.downloadPdf
-
- # PDF Download button for specific build
- webRouter.get /^\/download\/project\/([^\/]*)\/build\/([0-9a-f-]+)\/output\/output\.pdf$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "build_id": req.params[1]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.downloadPdf
-
- # Used by the pdf viewers
- webRouter.get /^\/project\/([^\/]*)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "file": req.params[1]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.getFileFromClsi
- # direct url access to output files for a specific build (query string not required)
- webRouter.get /^\/project\/([^\/]*)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "build_id": req.params[1]
- "file": req.params[2]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.getFileFromClsi
-
- # direct url access to output files for user but no build, to retrieve files when build fails
- webRouter.get /^\/project\/([^\/]*)\/user\/([0-9a-f-]+)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "user_id": req.params[1]
- "file": req.params[2]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.getFileFromClsi
-
- # direct url access to output files for a specific user and build (query string not required)
- webRouter.get /^\/project\/([^\/]*)\/user\/([0-9a-f]+)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "user_id": req.params[1]
- "build_id": req.params[2]
- "file": req.params[3]
- req.params = params
- next()
- ), AuthorizationMiddleware.ensureUserCanReadProject, CompileController.getFileFromClsi
-
-
- webRouter.delete "/project/:Project_id/output", AuthorizationMiddleware.ensureUserCanReadProject, CompileController.deleteAuxFiles
- webRouter.get "/project/:Project_id/sync/code", AuthorizationMiddleware.ensureUserCanReadProject, CompileController.proxySyncCode
- webRouter.get "/project/:Project_id/sync/pdf", AuthorizationMiddleware.ensureUserCanReadProject, CompileController.proxySyncPdf
- webRouter.get "/project/:Project_id/wordcount", AuthorizationMiddleware.ensureUserCanReadProject, CompileController.wordCount
-
- webRouter.delete '/Project/:Project_id', AuthorizationMiddleware.ensureUserCanAdminProject, ProjectController.deleteProject
- webRouter.post '/Project/:Project_id/restore', AuthorizationMiddleware.ensureUserCanAdminProject, ProjectController.restoreProject
- webRouter.post '/Project/:Project_id/clone', AuthorizationMiddleware.ensureUserCanReadProject, ProjectController.cloneProject
-
- webRouter.post '/project/:Project_id/rename', AuthorizationMiddleware.ensureUserCanAdminProject, ProjectController.renameProject
-
- webRouter.get "/project/:Project_id/updates", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApiAndInjectUserDetails
- webRouter.get "/project/:Project_id/doc/:doc_id/diff", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi
- webRouter.get "/project/:Project_id/diff", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApiAndInjectUserDetails
- webRouter.get "/project/:Project_id/filetree/diff", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi
- webRouter.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", AuthorizationMiddleware.ensureUserCanWriteProjectContent, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi
- webRouter.post '/project/:project_id/doc/:doc_id/restore', AuthorizationMiddleware.ensureUserCanWriteProjectContent, HistoryController.restoreDocFromDeletedDoc
- webRouter.post "/project/:project_id/restore_file", AuthorizationMiddleware.ensureUserCanWriteProjectContent, HistoryController.restoreFileFromV2
- webRouter.get "/project/:project_id/version/:version/zip", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.downloadZipOfVersion
- privateApiRouter.post "/project/:Project_id/history/resync", AuthenticationController.httpAuth, HistoryController.resyncProjectHistory
-
- webRouter.get "/project/:Project_id/labels", AuthorizationMiddleware.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.ensureProjectHistoryEnabled, HistoryController.getLabels
- webRouter.post "/project/:Project_id/labels", AuthorizationMiddleware.ensureUserCanWriteProjectContent, HistoryController.selectHistoryApi, HistoryController.ensureProjectHistoryEnabled, HistoryController.createLabel
- webRouter.delete "/project/:Project_id/labels/:label_id", AuthorizationMiddleware.ensureUserCanWriteProjectContent, HistoryController.selectHistoryApi, HistoryController.ensureProjectHistoryEnabled, HistoryController.deleteLabel
-
- webRouter.post '/project/:project_id/export/:brand_variation_id', AuthorizationMiddleware.ensureUserCanWriteProjectContent, ExportsController.exportProject
- webRouter.get '/project/:project_id/export/:export_id', AuthorizationMiddleware.ensureUserCanWriteProjectContent, ExportsController.exportStatus
- webRouter.get '/project/:project_id/export/:export_id/:type', AuthorizationMiddleware.ensureUserCanWriteProjectContent, ExportsController.exportDownload
-
- webRouter.get '/Project/:Project_id/download/zip', AuthorizationMiddleware.ensureUserCanReadProject, ProjectDownloadsController.downloadProject
- webRouter.get '/project/download/zip', AuthorizationMiddleware.ensureUserCanReadMultipleProjects, ProjectDownloadsController.downloadMultipleProjects
-
- webRouter.get '/project/:project_id/metadata', AuthorizationMiddleware.ensureUserCanReadProject, AuthenticationController.requireLogin(), MetaController.getMetadata
- webRouter.post '/project/:project_id/doc/:doc_id/metadata', AuthorizationMiddleware.ensureUserCanReadProject, AuthenticationController.requireLogin(), MetaController.broadcastMetadataForDoc
-
-
- webRouter.get '/tag', AuthenticationController.requireLogin(), TagsController.getAllTags
- webRouter.post '/tag', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "create-tag"
- maxRequests: 30
- timeInterval: 60
- }), TagsController.createTag
- webRouter.post '/tag/:tag_id/rename', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "rename-tag"
- maxRequests: 30
- timeInterval: 60
- }), TagsController.renameTag
- webRouter.delete '/tag/:tag_id', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "delete-tag"
- maxRequests: 30
- timeInterval: 60
- }), TagsController.deleteTag
- webRouter.post '/tag/:tag_id/project/:project_id', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "add-project-to-tag"
- maxRequests: 30
- timeInterval: 60
- }), TagsController.addProjectToTag
- webRouter.delete '/tag/:tag_id/project/:project_id', AuthenticationController.requireLogin(), RateLimiterMiddleware.rateLimit({
- endpointName: "remove-project-from-tag"
- maxRequests: 30
- timeInterval: 60
- }), TagsController.removeProjectFromTag
-
- webRouter.get '/notifications', AuthenticationController.requireLogin(), NotificationsController.getAllUnreadNotifications
- webRouter.delete '/notifications/:notification_id', AuthenticationController.requireLogin(), NotificationsController.markNotificationAsRead
-
- webRouter.get '/announcements', AuthenticationController.requireLogin(), AnnouncementsController.getUndreadAnnouncements
-
-
- # Deprecated in favour of /internal/project/:project_id but still used by versioning
- privateApiRouter.get '/project/:project_id/details', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails
-
- # New 'stable' /internal API end points
- privateApiRouter.get '/internal/project/:project_id', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails
- privateApiRouter.get '/internal/project/:Project_id/zip', AuthenticationController.httpAuth, ProjectDownloadsController.downloadProject
- privateApiRouter.get '/internal/project/:project_id/compile/pdf', AuthenticationController.httpAuth, CompileController.compileAndDownloadPdf
-
- privateApiRouter.post '/internal/deactivateOldProjects', AuthenticationController.httpAuth, InactiveProjectController.deactivateOldProjects
- privateApiRouter.post '/internal/project/:project_id/deactivate', AuthenticationController.httpAuth, InactiveProjectController.deactivateProject
-
- webRouter.get /^\/internal\/project\/([^\/]*)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "Project_id": req.params[0]
- "file": req.params[1]
- req.params = params
- next()
- ), AuthenticationController.httpAuth, CompileController.getFileFromClsi
-
- privateApiRouter.get '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.getDocument
- privateApiRouter.post '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.setDocument
-
- privateApiRouter.post '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.mergeUpdate
- privateApiRouter.delete '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.deleteUpdate
-
- privateApiRouter.post '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.updateProjectContents
- privateApiRouter.delete '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.deleteProjectContents
-
- webRouter.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
- webRouter.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
-
- webRouter.get "/project/:project_id/messages", AuthorizationMiddleware.ensureUserCanReadProject, ChatController.getMessages
- webRouter.post "/project/:project_id/messages", AuthorizationMiddleware.ensureUserCanReadProject, RateLimiterMiddleware.rateLimit({
- endpointName: "send-chat-message"
- maxRequests: 100
- timeInterval: 60
- }), ChatController.sendMessage
-
- webRouter.post "/project/:Project_id/references/index", AuthorizationMiddleware.ensureUserCanReadProject, RateLimiterMiddleware.rateLimit({
- endpointName: "index-project-references"
- maxRequests: 30
- timeInterval: 60
- }), ReferencesController.index
- webRouter.post "/project/:Project_id/references/indexAll", AuthorizationMiddleware.ensureUserCanReadProject, RateLimiterMiddleware.rateLimit({
- endpointName: "index-all-project-references"
- maxRequests: 30
- timeInterval: 60
- }), ReferencesController.indexAll
-
- # disable beta program while v2 is in beta
- webRouter.get "/beta/participate", AuthenticationController.requireLogin(), BetaProgramController.optInPage
- webRouter.post "/beta/opt-in", AuthenticationController.requireLogin(), BetaProgramController.optIn
- webRouter.post "/beta/opt-out", AuthenticationController.requireLogin(), BetaProgramController.optOut
- webRouter.get "/confirm-password", AuthenticationController.requireLogin(), SudoModeController.sudoModePrompt
- webRouter.post "/confirm-password",
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit({
- endpointName: "confirm-password"
- maxRequests: 10
- timeInterval: 60
- }),
- SudoModeController.submitPassword
-
- # New "api" endpoints. Started as a way for v1 to call over to v2 (for
- # long-term features, as opposed to the nominally temporary ones in the
- # overleaf-integration module), but may expand beyond that role.
- publicApiRouter.post '/api/clsi/compile/:submission_id', AuthenticationController.httpAuth, CompileController.compileSubmission
- publicApiRouter.get /^\/api\/clsi\/compile\/([^\/]*)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
- ((req, res, next) ->
- params =
- "submission_id": req.params[0]
- "build_id": req.params[1]
- "file": req.params[2]
- req.params = params
- next()
- ),
- AuthenticationController.httpAuth,
- CompileController.getFileFromClsiWithoutUser
- publicApiRouter.post '/api/institutions/confirm_university_domain', RateLimiterMiddleware.rateLimit({
- endpointName: 'confirm-university-domain',
- maxRequests: 1,
- timeInterval: 60
- }), AuthenticationController.httpAuth, InstitutionsController.confirmDomain
-
- webRouter.get '/chrome', (req, res, next) ->
- # Match v1 behaviour - this is used for a Chrome web app
- if AuthenticationController.isUserLoggedIn(req)
- res.redirect('/project')
- else
- res.redirect('/register')
-
- #Admin Stuff
- webRouter.get '/admin', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.index
- webRouter.get '/admin/user', AuthorizationMiddleware.ensureUserIsSiteAdmin, (req, res)-> res.redirect("/admin/register") #this gets removed by admin-panel addon
- webRouter.get '/admin/register', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.registerNewUser
- webRouter.post '/admin/register', AuthorizationMiddleware.ensureUserIsSiteAdmin, UserController.register
- webRouter.post '/admin/closeEditor', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.closeEditor
- webRouter.post '/admin/dissconectAllUsers', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.dissconectAllUsers
- webRouter.post '/admin/syncUserToSubscription', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.syncUserToSubscription
- webRouter.post '/admin/flushProjectToTpds', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.flushProjectToTpds
- webRouter.post '/admin/pollDropboxForUser', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.pollDropboxForUser
- webRouter.post '/admin/messages', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.createMessage
- webRouter.post '/admin/messages/clear', AuthorizationMiddleware.ensureUserIsSiteAdmin, AdminController.clearMessages
-
- privateApiRouter.post '/disconnectAllUsers', AdminController.dissconectAllUsers
-
- privateApiRouter.get '/perfTest', (req,res)->
- res.send("hello")
-
- publicApiRouter.get '/status', (req,res)->
- res.send("web sharelatex is alive (web)")
- privateApiRouter.get '/status', (req,res)->
- res.send("web sharelatex is alive (api)")
-
- webRouter.get '/dev/csrf', (req, res) ->
- res.send res.locals.csrfToken
-
- publicApiRouter.get '/health_check', HealthCheckController.check
- privateApiRouter.get '/health_check', HealthCheckController.check
-
- publicApiRouter.get '/health_check/redis', HealthCheckController.checkRedis
- privateApiRouter.get '/health_check/redis', HealthCheckController.checkRedis
-
- publicApiRouter.get '/health_check/mongo', HealthCheckController.checkMongo
- privateApiRouter.get '/health_check/mongo', HealthCheckController.checkMongo
-
- webRouter.get "/status/compiler/:Project_id", AuthorizationMiddleware.ensureUserCanReadProject, (req, res) ->
- project_id = req.params.Project_id
- sendRes = _.once (statusCode, message)->
- res.status statusCode
- res.send message
- ClsiCookieManager.clearServerId project_id # force every compile to a new server
- # set a timeout
- handler = setTimeout (() ->
- sendRes 500, "Compiler timed out"
- handler = null
- ), 10000
- # use a valid user id for testing
- test_user_id = "123456789012345678901234"
- # run the compile
- CompileManager.compile project_id, test_user_id, {}, (error, status) ->
- clearTimeout handler if handler?
- if error?
- sendRes 500, "Compiler returned error #{error.message}"
- else if status is "success"
- sendRes 200, "Compiler returned in less than 10 seconds"
- else
- sendRes 500, "Compiler returned failure #{status}"
-
- webRouter.get "/no-cache", (req, res, next)->
- res.header("Cache-Control", "max-age=0")
- res.sendStatus(404)
-
- webRouter.get '/oops-express', (req, res, next) -> next(new Error("Test error"))
- webRouter.get '/oops-internal', (req, res, next) -> throw new Error("Test error")
- webRouter.get '/oops-mongo', (req, res, next) ->
- require("./models/Project").Project.findOne {}, () ->
- throw new Error("Test error")
-
- privateApiRouter.get '/opps-small', (req, res, next)->
- logger.err "test error occured"
- res.send()
-
- webRouter.post '/error/client', (req, res, next) ->
- logger.warn err: req.body.error, meta: req.body.meta, "client side error"
- metrics.inc("client-side-error")
- res.sendStatus(204)
-
-
- webRouter.get '/read/:read_only_token([a-z]+)',
- RateLimiterMiddleware.rateLimit({
- endpointName: 'read-only-token',
- maxRequests: 15,
- timeInterval: 60
- }),
- TokenAccessController.readOnlyToken
-
- webRouter.get '/:read_and_write_token([0-9]+[a-z]+)',
- RateLimiterMiddleware.rateLimit({
- endpointName: 'read-and-write-token',
- maxRequests: 15,
- timeInterval: 60
- }),
- TokenAccessController.readAndWriteToken
-
- webRouter.get '*', ErrorController.notFound
diff --git a/services/web/app/src/Features/Analytics/AnalyticsController.js b/services/web/app/src/Features/Analytics/AnalyticsController.js
new file mode 100644
index 0000000000..af2fe87e7d
--- /dev/null
+++ b/services/web/app/src/Features/Analytics/AnalyticsController.js
@@ -0,0 +1,86 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AnalyticsController
+const AnalyticsManager = require('./AnalyticsManager')
+const Errors = require('../Errors/Errors')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const InstitutionsAPI = require('../Institutions/InstitutionsAPI')
+const GeoIpLookup = require('../../infrastructure/GeoIpLookup')
+
+module.exports = AnalyticsController = {
+ updateEditingSession(req, res, next) {
+ const userId = AuthenticationController.getLoggedInUserId(req)
+ const { projectId } = req.params
+ let countryCode = null
+
+ if (userId != null) {
+ return GeoIpLookup.getDetails(req.ip, function(err, geoDetails) {
+ if (
+ (geoDetails != null ? geoDetails.country_code : undefined) != null &&
+ geoDetails.country_code !== ''
+ ) {
+ countryCode = geoDetails.country_code
+ }
+ return AnalyticsManager.updateEditingSession(
+ userId,
+ projectId,
+ countryCode,
+ error => respondWith(error, res, next)
+ )
+ })
+ } else {
+ return res.send(204)
+ }
+ },
+
+ recordEvent(req, res, next) {
+ const user_id =
+ AuthenticationController.getLoggedInUserId(req) || req.sessionID
+ return AnalyticsManager.recordEvent(
+ user_id,
+ req.params.event,
+ req.body,
+ error => respondWith(error, res, next)
+ )
+ },
+
+ licences(req, res, next) {
+ const { resource_id, start_date, end_date, lag } = req.query
+ return InstitutionsAPI.getInstitutionLicences(
+ resource_id,
+ start_date,
+ end_date,
+ lag,
+ function(error, licences) {
+ if (error != null) {
+ return next(error)
+ } else {
+ return res.send(licences)
+ }
+ }
+ )
+ }
+}
+
+var respondWith = function(error, res, next) {
+ if (error instanceof Errors.ServiceNotConfiguredError) {
+ // ignore, no-op
+ return res.send(204)
+ } else if (error != null) {
+ return next(error)
+ } else {
+ return res.send(204)
+ }
+}
diff --git a/services/web/app/src/Features/Analytics/AnalyticsManager.js b/services/web/app/src/Features/Analytics/AnalyticsManager.js
new file mode 100644
index 0000000000..e076db0d2b
--- /dev/null
+++ b/services/web/app/src/Features/Analytics/AnalyticsManager.js
@@ -0,0 +1,177 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+const _ = require('underscore')
+const request = require('requestretry')
+const Errors = require('../Errors/Errors')
+
+const makeFaultTolerantRequest = function(userId, options, callback) {
+ if (
+ userId + '' ===
+ (settings.smokeTest != null ? settings.smokeTest.userId : undefined) + ''
+ ) {
+ return callback()
+ }
+
+ options = Object.assign(options, {
+ delayStrategy: exponentialBackoffStrategy(),
+ timeout: 30000
+ })
+
+ if (settings.overleaf != null) {
+ options.qs = Object.assign({}, options.qs, { fromV2: 1 })
+ }
+
+ makeRequest(options, function(err) {
+ if (err != null) {
+ return logger.err({ err }, 'Request to analytics failed')
+ }
+ })
+
+ return callback() // Do not wait for all the attempts
+}
+
+var makeRequest = function(opts, callback) {
+ if (
+ __guard__(
+ settings.apis != null ? settings.apis.analytics : undefined,
+ x => x.url
+ ) != null
+ ) {
+ const urlPath = opts.url
+ opts.url = `${settings.apis.analytics.url}${urlPath}`
+ return request(opts, callback)
+ } else {
+ return callback(
+ new Errors.ServiceNotConfiguredError('Analytics service not configured')
+ )
+ }
+}
+
+// Set an exponential backoff to retry calls to analytics. First retry will
+// happen after 4s, then 8, 16, 32, 64...
+var exponentialBackoffStrategy = function() {
+ let attempts = 1 // This won't be called until there has been 1 failure
+
+ return function() {
+ attempts += 1
+ return exponentialBackoffDelay(attempts)
+ }
+}
+
+var exponentialBackoffDelay = function(attempts) {
+ const delay = Math.pow(2, attempts) * 1000
+
+ logger.warn(
+ 'Error comunicating with the analytics service. ' +
+ `Will try again attempt ${attempts} in ${delay}ms`
+ )
+
+ return delay
+}
+
+module.exports = {
+ identifyUser(user_id, old_user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const opts = {
+ body: {
+ old_user_id
+ },
+ json: true,
+ method: 'POST',
+ timeout: 1000,
+ url: `/user/${user_id}/identify`
+ }
+ return makeRequest(opts, callback)
+ },
+
+ recordEvent(user_id, event, segmentation, callback) {
+ if (segmentation == null) {
+ segmentation = {}
+ }
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const opts = {
+ body: {
+ event,
+ segmentation
+ },
+ json: true,
+ method: 'POST',
+ url: `/user/${user_id}/event`,
+ maxAttempts: 7 // Give up after ~ 8min
+ }
+
+ return makeFaultTolerantRequest(user_id, opts, callback)
+ },
+
+ updateEditingSession(userId, projectId, countryCode, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const query = {
+ userId,
+ projectId
+ }
+
+ if (countryCode) {
+ query.countryCode = countryCode
+ }
+
+ const opts = {
+ method: 'PUT',
+ url: '/editingSession',
+ qs: query,
+ maxAttempts: 6 // Give up after ~ 4min
+ }
+
+ return makeFaultTolerantRequest(userId, opts, callback)
+ },
+
+ getLastOccurrence(user_id, event, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const opts = {
+ body: {
+ event
+ },
+ json: true,
+ method: 'POST',
+ timeout: 1000,
+ url: `/user/${user_id}/event/last_occurrence`
+ }
+ return makeRequest(opts, function(err, response, body) {
+ if (err != null) {
+ console.log(response, opts)
+ logger.err({ user_id, err }, 'error getting last occurance of event')
+ return callback(err)
+ } else {
+ return callback(null, body)
+ }
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Analytics/AnalyticsProxy.js b/services/web/app/src/Features/Analytics/AnalyticsProxy.js
new file mode 100644
index 0000000000..9510025a16
--- /dev/null
+++ b/services/web/app/src/Features/Analytics/AnalyticsProxy.js
@@ -0,0 +1,53 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const settings = require('settings-sharelatex')
+const Errors = require('../Errors/Errors')
+const httpProxy = require('express-http-proxy')
+const URL = require('url')
+
+module.exports = {
+ call(basePath) {
+ const analyticsUrl = __guard__(
+ __guard__(
+ settings != null ? settings.apis : undefined,
+ x1 => x1.analytics
+ ),
+ x => x.url
+ )
+ if (analyticsUrl != null) {
+ return httpProxy(analyticsUrl, {
+ proxyReqPathResolver(req) {
+ const requestPath = URL.parse(req.url).path
+ return `${basePath}${requestPath}`
+ },
+ proxyReqOptDecorator(proxyReqOpts, srcReq) {
+ proxyReqOpts.headers = {} // unset all headers
+ return proxyReqOpts
+ }
+ })
+ } else {
+ return (req, res, next) =>
+ next(
+ new Errors.ServiceNotConfiguredError(
+ 'Analytics service not configured'
+ )
+ )
+ }
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Analytics/AnalyticsRouter.js b/services/web/app/src/Features/Analytics/AnalyticsRouter.js
new file mode 100644
index 0000000000..6ffcf51704
--- /dev/null
+++ b/services/web/app/src/Features/Analytics/AnalyticsRouter.js
@@ -0,0 +1,45 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const AuthenticationController = require('./../Authentication/AuthenticationController')
+const AnalyticsController = require('./AnalyticsController')
+const AnalyticsProxy = require('./AnalyticsProxy')
+
+module.exports = {
+ apply(webRouter, privateApiRouter, publicApiRouter) {
+ webRouter.post('/event/:event', AnalyticsController.recordEvent)
+
+ webRouter.put(
+ '/editingSession/:projectId',
+ AnalyticsController.updateEditingSession
+ )
+
+ publicApiRouter.use(
+ '/analytics/graphs',
+ AuthenticationController.httpAuth,
+ AnalyticsProxy.call('/graphs')
+ )
+
+ publicApiRouter.use(
+ '/analytics/recentTeamActivity',
+ AuthenticationController.httpAuth,
+ AnalyticsProxy.call('/recentTeamActivity')
+ )
+
+ publicApiRouter.use(
+ '/analytics/recentV1TemplateIdsActivity',
+ AuthenticationController.httpAuth,
+ AnalyticsProxy.call('/recentV1TemplateIdsActivity')
+ )
+
+ return publicApiRouter.use(
+ '/analytics/uniExternalCollaboration',
+ AuthenticationController.httpAuth,
+ AnalyticsProxy.call('/uniExternalCollaboration')
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Announcements/AnnouncementsController.js b/services/web/app/src/Features/Announcements/AnnouncementsController.js
new file mode 100644
index 0000000000..d515c6620e
--- /dev/null
+++ b/services/web/app/src/Features/Announcements/AnnouncementsController.js
@@ -0,0 +1,59 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const AnnouncementsHandler = require('./AnnouncementsHandler')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const logger = require('logger-sharelatex')
+const settings = require('settings-sharelatex')
+
+module.exports = {
+ getUndreadAnnouncements(req, res, next) {
+ if (
+ __guard__(
+ __guard__(
+ settings != null ? settings.apis : undefined,
+ x1 => x1.analytics
+ ),
+ x => x.url
+ ) == null ||
+ settings.apis.blog.url == null
+ ) {
+ return res.json([])
+ }
+
+ const user = AuthenticationController.getSessionUser(req)
+ logger.log(
+ { user_id: user != null ? user._id : undefined },
+ 'getting unread announcements'
+ )
+ return AnnouncementsHandler.getUnreadAnnouncements(user, function(
+ err,
+ announcements
+ ) {
+ if (err != null) {
+ logger.err(
+ { err, user_id: user._id },
+ 'unable to get unread announcements'
+ )
+ return next(err)
+ } else {
+ return res.json(announcements)
+ }
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Announcements/AnnouncementsHandler.js b/services/web/app/src/Features/Announcements/AnnouncementsHandler.js
new file mode 100644
index 0000000000..36b24e2f85
--- /dev/null
+++ b/services/web/app/src/Features/Announcements/AnnouncementsHandler.js
@@ -0,0 +1,135 @@
+/* eslint-disable
+ handle-callback-err,
+ max-len,
+ standard/no-callback-literal,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AnnouncementsHandler
+const AnalyticsManager = require('../Analytics/AnalyticsManager')
+const BlogHandler = require('../Blog/BlogHandler')
+const logger = require('logger-sharelatex')
+const settings = require('settings-sharelatex')
+const async = require('async')
+const _ = require('lodash')
+
+module.exports = AnnouncementsHandler = {
+ _domainSpecificAnnouncements(email) {
+ const domainSpecific = _.filter(
+ settings != null ? settings.domainAnnouncements : undefined,
+ function(domainAnnouncment) {
+ const matches = _.filter(
+ domainAnnouncment.domains,
+ domain => email.indexOf(domain) !== -1
+ )
+ return matches.length > 0 && domainAnnouncment.id != null
+ }
+ )
+ return domainSpecific || []
+ },
+
+ getUnreadAnnouncements(user, callback) {
+ if (callback == null) {
+ callback = function(err, announcements) {}
+ }
+ if (user == null && user._id == null) {
+ return callback('user not supplied')
+ }
+
+ const timestamp = user._id.toString().substring(0, 8)
+ const userSignupDate = new Date(parseInt(timestamp, 16) * 1000)
+
+ return async.parallel(
+ {
+ lastEvent(cb) {
+ return AnalyticsManager.getLastOccurrence(
+ user._id,
+ 'announcement-alert-dismissed',
+ cb
+ )
+ },
+ announcements(cb) {
+ return BlogHandler.getLatestAnnouncements(cb)
+ }
+ },
+ function(err, results) {
+ if (err != null) {
+ logger.err(
+ { err, user_id: user._id },
+ 'error getting unread announcements'
+ )
+ return callback(err)
+ }
+
+ let domainSpecific = AnnouncementsHandler._domainSpecificAnnouncements(
+ user != null ? user.email : undefined
+ )
+
+ domainSpecific = _.map(domainSpecific, function(domainAnnouncment) {
+ try {
+ domainAnnouncment.date = new Date(domainAnnouncment.date)
+ return domainAnnouncment
+ } catch (e) {
+ return callback(e)
+ }
+ })
+
+ let { announcements } = results
+ announcements = _.union(announcements, domainSpecific)
+ announcements = _.sortBy(announcements, 'date').reverse()
+
+ const lastSeenBlogId = __guard__(
+ __guard__(
+ results != null ? results.lastEvent : undefined,
+ x1 => x1.segmentation
+ ),
+ x => x.blogPostId
+ )
+
+ const announcementIndex = _.findIndex(
+ announcements,
+ announcement => announcement.id === lastSeenBlogId
+ )
+
+ announcements = _.map(announcements, function(announcement, index) {
+ let read
+ if (announcement.date < userSignupDate) {
+ read = true
+ } else if (announcementIndex === -1) {
+ read = false
+ } else if (index >= announcementIndex) {
+ read = true
+ } else {
+ read = false
+ }
+ announcement.read = read
+ return announcement
+ })
+
+ logger.log(
+ {
+ announcementsLength:
+ announcements != null ? announcements.length : undefined,
+ user_id: user != null ? user._id : undefined
+ },
+ 'returning announcements'
+ )
+
+ return callback(null, announcements)
+ }
+ )
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Authentication/AuthenticationController.js b/services/web/app/src/Features/Authentication/AuthenticationController.js
new file mode 100644
index 0000000000..0a89cea909
--- /dev/null
+++ b/services/web/app/src/Features/Authentication/AuthenticationController.js
@@ -0,0 +1,578 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-return-assign,
+ no-undef,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS205: Consider reworking code to avoid use of IIFEs
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AuthenticationController
+const AuthenticationManager = require('./AuthenticationManager')
+const LoginRateLimiter = require('../Security/LoginRateLimiter')
+const UserUpdater = require('../User/UserUpdater')
+const Metrics = require('metrics-sharelatex')
+const logger = require('logger-sharelatex')
+const querystring = require('querystring')
+const Url = require('url')
+const Settings = require('settings-sharelatex')
+const basicAuth = require('basic-auth-connect')
+const UserHandler = require('../User/UserHandler')
+const UserSessionsManager = require('../User/UserSessionsManager')
+const Analytics = require('../Analytics/AnalyticsManager')
+const passport = require('passport')
+const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
+const SudoModeHandler = require('../SudoMode/SudoModeHandler')
+const V1Api = require('../V1/V1Api')
+const { User } = require('../../models/User')
+const { URL } = require('url')
+
+module.exports = AuthenticationController = {
+ serializeUser(user, callback) {
+ const lightUser = {
+ _id: user._id,
+ first_name: user.first_name,
+ last_name: user.last_name,
+ isAdmin: user.isAdmin,
+ staffAccess: user.staffAccess,
+ email: user.email,
+ referal_id: user.referal_id,
+ session_created: new Date().toISOString(),
+ ip_address: user._login_req_ip,
+ must_reconfirm: user.must_reconfirm,
+ v1_id: user.overleaf != null ? user.overleaf.id : undefined
+ }
+ return callback(null, lightUser)
+ },
+
+ deserializeUser(user, cb) {
+ return cb(null, user)
+ },
+
+ afterLoginSessionSetup(req, user, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return req.login(user, function(err) {
+ if (err != null) {
+ logger.err({ user_id: user._id, err }, 'error from req.login')
+ return callback(err)
+ }
+ // Regenerate the session to get a new sessionID (cookie value) to
+ // protect against session fixation attacks
+ const oldSession = req.session
+ return req.session.destroy(function(err) {
+ if (err != null) {
+ logger.err(
+ { user_id: user._id, err },
+ 'error when trying to destroy old session'
+ )
+ return callback(err)
+ }
+ req.sessionStore.generate(req)
+ for (let key in oldSession) {
+ const value = oldSession[key]
+ if (key !== '__tmp') {
+ req.session[key] = value
+ }
+ }
+ // copy to the old `session.user` location, for backward-comptability
+ req.session.user = req.session.passport.user
+ return req.session.save(function(err) {
+ if (err != null) {
+ logger.err(
+ { user_id: user._id },
+ 'error saving regenerated session after login'
+ )
+ return callback(err)
+ }
+ UserSessionsManager.trackSession(user, req.sessionID, function() {})
+ return callback(null)
+ })
+ })
+ })
+ },
+
+ passportLogin(req, res, next) {
+ // This function is middleware which wraps the passport.authenticate middleware,
+ // so we can send back our custom `{message: {text: "", type: ""}}` responses on failure,
+ // and send a `{redir: ""}` response on success
+ return passport.authenticate('local', function(err, user, info) {
+ if (err != null) {
+ return next(err)
+ }
+ if (user) {
+ // `user` is either a user object or false
+ return AuthenticationController.finishLogin(user, req, res, next)
+ } else {
+ if (info.redir != null) {
+ return res.json({ redir: info.redir })
+ } else {
+ return res.json({ message: info })
+ }
+ }
+ })(req, res, next)
+ },
+
+ finishLogin(user, req, res, next) {
+ if (user === false) {
+ return res.redirect('/login')
+ } // OAuth2 'state' mismatch
+ if (user.must_reconfirm) {
+ return AuthenticationController._redirectToReconfirmPage(req, res, user)
+ } else {
+ const redir =
+ AuthenticationController._getRedirectFromSession(req) || '/project'
+ AuthenticationController._loginAsyncHandlers(req, user)
+ return AuthenticationController.afterLoginSessionSetup(
+ req,
+ user,
+ function(err) {
+ if (err != null) {
+ return next(err)
+ }
+ return SudoModeHandler.activateSudoMode(user._id, function(err) {
+ if (err != null) {
+ logger.err(
+ { err, user_id: user._id },
+ 'Error activating Sudo Mode on login, continuing'
+ )
+ }
+ AuthenticationController._clearRedirectFromSession(req)
+ if (
+ __guard__(
+ req.headers != null ? req.headers['accept'] : undefined,
+ x => x.match(/^application\/json.*$/)
+ )
+ ) {
+ return res.json({ redir })
+ } else {
+ return res.redirect(redir)
+ }
+ })
+ }
+ )
+ }
+ },
+
+ doPassportLogin(req, username, password, done) {
+ const email = username.toLowerCase()
+ const Modules = require('../../infrastructure/Modules')
+ return Modules.hooks.fire('preDoPassportLogin', req, email, function(
+ err,
+ infoList
+ ) {
+ if (err != null) {
+ return next(err)
+ }
+ const info = infoList.find(i => i != null)
+ if (info != null) {
+ return done(null, false, info)
+ }
+ return LoginRateLimiter.processLoginRequest(email, function(
+ err,
+ isAllowed
+ ) {
+ if (err != null) {
+ return done(err)
+ }
+ if (!isAllowed) {
+ logger.log({ email }, 'too many login requests')
+ return done(null, null, {
+ text: req.i18n.translate('to_many_login_requests_2_mins'),
+ type: 'error'
+ })
+ }
+ return AuthenticationManager.authenticate({ email }, password, function(
+ error,
+ user
+ ) {
+ if (error != null) {
+ return done(error)
+ }
+ if (user != null) {
+ // async actions
+ return done(null, user)
+ } else {
+ AuthenticationController._recordFailedLogin()
+ logger.log({ email }, 'failed log in')
+ return done(null, false, {
+ text: req.i18n.translate('email_or_password_wrong_try_again'),
+ type: 'error'
+ })
+ }
+ })
+ })
+ })
+ },
+
+ _loginAsyncHandlers(req, user) {
+ UserHandler.setupLoginData(user, function() {})
+ LoginRateLimiter.recordSuccessfulLogin(user.email)
+ AuthenticationController._recordSuccessfulLogin(user._id)
+ AuthenticationController.ipMatchCheck(req, user)
+ Analytics.recordEvent(user._id, 'user-logged-in', { ip: req.ip })
+ Analytics.identifyUser(user._id, req.sessionID)
+ logger.log(
+ { email: user.email, user_id: user._id.toString() },
+ 'successful log in'
+ )
+ req.session.justLoggedIn = true
+ // capture the request ip for use when creating the session
+ return (user._login_req_ip = req.ip)
+ },
+
+ ipMatchCheck(req, user) {
+ if (req.ip !== user.lastLoginIp) {
+ NotificationsBuilder.ipMatcherAffiliation(user._id).create(req.ip)
+ }
+ return UserUpdater.updateUser(user._id.toString(), {
+ $set: { lastLoginIp: req.ip }
+ })
+ },
+
+ setInSessionUser(req, props) {
+ return (() => {
+ const result = []
+ for (let key in props) {
+ const value = props[key]
+ if (
+ __guard__(
+ __guard__(req != null ? req.session : undefined, x1 => x1.passport),
+ x => x.user
+ ) != null
+ ) {
+ req.session.passport.user[key] = value
+ }
+ if (
+ __guard__(req != null ? req.session : undefined, x2 => x2.user) !=
+ null
+ ) {
+ result.push((req.session.user[key] = value))
+ } else {
+ result.push(undefined)
+ }
+ }
+ return result
+ })()
+ },
+
+ isUserLoggedIn(req) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return ![null, undefined, false].includes(user_id)
+ },
+
+ // TODO: perhaps should produce an error if the current user is not present
+ getLoggedInUserId(req) {
+ const user = AuthenticationController.getSessionUser(req)
+ if (user) {
+ return user._id
+ } else {
+ return null
+ }
+ },
+
+ getLoggedInUserV1Id(req) {
+ const user = AuthenticationController.getSessionUser(req)
+ if ((user != null ? user.v1_id : undefined) != null) {
+ return user.v1_id
+ } else {
+ return null
+ }
+ },
+
+ getSessionUser(req) {
+ if (__guard__(req != null ? req.session : undefined, x => x.user) != null) {
+ return req.session.user
+ } else if (
+ __guard__(
+ __guard__(req != null ? req.session : undefined, x2 => x2.passport),
+ x1 => x1.user
+ )
+ ) {
+ return req.session.passport.user
+ } else {
+ return null
+ }
+ },
+
+ requireLogin() {
+ const doRequest = function(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ if (!AuthenticationController.isUserLoggedIn(req)) {
+ return AuthenticationController._redirectToLoginOrRegisterPage(req, res)
+ } else {
+ req.user = AuthenticationController.getSessionUser(req)
+ return next()
+ }
+ }
+
+ return doRequest
+ },
+
+ // access tokens might be associated with user stubs if the user is
+ // not yet migrated to v2. if api can work with user stubs then set
+ // allowUserStub true when adding middleware to route.
+ requireOauth(allowUserStub) {
+ // require this here because module may not be included in some versions
+ if (allowUserStub == null) {
+ allowUserStub = false
+ }
+ const Oauth2Server = require('../../../../modules/oauth2-server/app/src/Oauth2Server')
+ return function(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const request = new Oauth2Server.Request(req)
+ const response = new Oauth2Server.Response(res)
+ return Oauth2Server.server.authenticate(request, response, {}, function(
+ err,
+ token
+ ) {
+ if (err != null) {
+ // use a 401 status code for malformed header for git-bridge
+ if (
+ err.code === 400 &&
+ err.message === 'Invalid request: malformed authorization header'
+ ) {
+ err.code = 401
+ }
+ // fall back to v1 on invalid token
+ if (err.code === 401) {
+ return AuthenticationController._requireOauthV1Fallback(
+ req,
+ res,
+ next
+ )
+ }
+ // send all other errors
+ return res
+ .status(err.code)
+ .json({ error: err.name, error_description: err.message })
+ }
+ if (token.user.constructor.modelName === 'UserStub' && !allowUserStub) {
+ return res.sendStatus(401)
+ }
+ req.oauth = { access_token: token.accessToken }
+ req.oauth_token = token
+ req.oauth_user = token.user
+ return next()
+ })
+ }
+ },
+
+ _requireOauthV1Fallback(req, res, next) {
+ if (req.token == null) {
+ return res.sendStatus(401)
+ }
+ const options = {
+ expectedStatusCodes: [401],
+ json: {
+ token: req.token
+ },
+ method: 'POST',
+ uri: '/api/v1/sharelatex/oauth_authorize'
+ }
+ return V1Api.request(options, function(error, response, body) {
+ if (error != null) {
+ return next(error)
+ }
+ if (!__guard__(body != null ? body.user_profile : undefined, x => x.id)) {
+ return res.status(401).json({ error: 'invalid_token' })
+ }
+ return User.findOne({ 'overleaf.id': body.user_profile.id }, function(
+ error,
+ user
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ if (user == null) {
+ return res.status(401).json({ error: 'invalid_token' })
+ }
+ req.oauth = { access_token: body.access_token }
+ req.oauth_user = user
+ return next()
+ })
+ })
+ },
+
+ _globalLoginWhitelist: [],
+ addEndpointToLoginWhitelist(endpoint) {
+ return AuthenticationController._globalLoginWhitelist.push(endpoint)
+ },
+
+ requireGlobalLogin(req, res, next) {
+ if (
+ Array.from(AuthenticationController._globalLoginWhitelist).includes(
+ req._parsedUrl.pathname
+ )
+ ) {
+ return next()
+ }
+
+ if (req.headers['authorization'] != null) {
+ return AuthenticationController.httpAuth(req, res, next)
+ } else if (AuthenticationController.isUserLoggedIn(req)) {
+ return next()
+ } else {
+ logger.log(
+ { url: req.url },
+ 'user trying to access endpoint not in global whitelist'
+ )
+ AuthenticationController.setRedirectInSession(req)
+ return res.redirect('/login')
+ }
+ },
+
+ httpAuth: basicAuth(function(user, pass) {
+ const isValid = Settings.httpAuthUsers[user] === pass
+ if (!isValid) {
+ logger.err({ user, pass }, 'invalid login details')
+ }
+ return isValid
+ }),
+
+ setRedirectInSession(req, value) {
+ if (value == null) {
+ value =
+ Object.keys(req.query).length > 0
+ ? `${req.path}?${querystring.stringify(req.query)}`
+ : `${req.path}`
+ }
+ if (
+ req.session != null &&
+ !/^\/(socket.io|js|stylesheets|img)\/.*$/.test(value) &&
+ !/^.*\.(png|jpeg|svg)$/.test(value)
+ ) {
+ const safePath = AuthenticationController._getSafeRedirectPath(value)
+ return (req.session.postLoginRedirect = safePath)
+ }
+ },
+
+ _redirectToLoginOrRegisterPage(req, res) {
+ if (
+ req.query.zipUrl != null ||
+ req.query.project_name != null ||
+ req.path === '/user/subscription/new'
+ ) {
+ return AuthenticationController._redirectToRegisterPage(req, res)
+ } else {
+ return AuthenticationController._redirectToLoginPage(req, res)
+ }
+ },
+
+ _redirectToLoginPage(req, res) {
+ logger.log(
+ { url: req.url },
+ 'user not logged in so redirecting to login page'
+ )
+ AuthenticationController.setRedirectInSession(req)
+ const url = `/login?${querystring.stringify(req.query)}`
+ res.redirect(url)
+ return Metrics.inc('security.login-redirect')
+ },
+
+ _redirectToReconfirmPage(req, res, user) {
+ logger.log(
+ { url: req.url },
+ 'user needs to reconfirm so redirecting to reconfirm page'
+ )
+ req.session.reconfirm_email = user != null ? user.email : undefined
+ const redir = '/user/reconfirm'
+ if (
+ __guard__(req.headers != null ? req.headers['accept'] : undefined, x =>
+ x.match(/^application\/json.*$/)
+ )
+ ) {
+ return res.json({ redir })
+ } else {
+ return res.redirect(redir)
+ }
+ },
+
+ _redirectToRegisterPage(req, res) {
+ logger.log(
+ { url: req.url },
+ 'user not logged in so redirecting to register page'
+ )
+ AuthenticationController.setRedirectInSession(req)
+ const url = `/register?${querystring.stringify(req.query)}`
+ res.redirect(url)
+ return Metrics.inc('security.login-redirect')
+ },
+
+ _recordSuccessfulLogin(user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return UserUpdater.updateUser(
+ user_id.toString(),
+ {
+ $set: { lastLoggedIn: new Date() },
+ $inc: { loginCount: 1 }
+ },
+ function(error) {
+ if (error != null) {
+ callback(error)
+ }
+ Metrics.inc('user.login.success')
+ return callback()
+ }
+ )
+ },
+
+ _recordFailedLogin(callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ Metrics.inc('user.login.failed')
+ return callback()
+ },
+
+ _getRedirectFromSession(req) {
+ let safePath
+ const value = __guard__(
+ req != null ? req.session : undefined,
+ x => x.postLoginRedirect
+ )
+ if (value) {
+ safePath = AuthenticationController._getSafeRedirectPath(value)
+ }
+ return safePath || null
+ },
+
+ _clearRedirectFromSession(req) {
+ if (req.session != null) {
+ return delete req.session.postLoginRedirect
+ }
+ },
+
+ _getSafeRedirectPath(value) {
+ const baseURL = Settings.siteUrl // base URL is required to construct URL from path
+ const url = new URL(value, baseURL)
+ let safePath = `${url.pathname}${url.search}${url.hash}`
+ if (safePath === '/') {
+ safePath = undefined
+ }
+ return safePath
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Authentication/AuthenticationManager.js b/services/web/app/src/Features/Authentication/AuthenticationManager.js
new file mode 100644
index 0000000000..af742aeba4
--- /dev/null
+++ b/services/web/app/src/Features/Authentication/AuthenticationManager.js
@@ -0,0 +1,320 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS202: Simplify dynamic range loops
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AuthenticationManager
+const Settings = require('settings-sharelatex')
+const { User } = require('../../models/User')
+const { db, ObjectId } = require('../../infrastructure/mongojs')
+const crypto = require('crypto')
+const bcrypt = require('bcrypt')
+const EmailHelper = require('../Helpers/EmailHelper')
+const Errors = require('../Errors/Errors')
+const UserGetter = require('../User/UserGetter')
+const V1Handler = require('../V1/V1Handler')
+
+const BCRYPT_ROUNDS =
+ __guard__(
+ Settings != null ? Settings.security : undefined,
+ x => x.bcryptRounds
+ ) || 12
+
+const _checkWriteResult = function(result, callback) {
+ // for MongoDB
+ if (callback == null) {
+ callback = function(error, updated) {}
+ }
+ if (result && result.nModified === 1) {
+ return callback(null, true)
+ } else {
+ return callback(null, false)
+ }
+}
+
+module.exports = AuthenticationManager = {
+ authenticate(query, password, callback) {
+ // Using Mongoose for legacy reasons here. The returned User instance
+ // gets serialized into the session and there may be subtle differences
+ // between the user returned by Mongoose vs mongojs (such as default values)
+ if (callback == null) {
+ callback = function(error, user) {}
+ }
+ return User.findOne(query, (error, user) => {
+ if (error != null) {
+ return callback(error)
+ }
+ if (user != null) {
+ if (user.hashedPassword != null) {
+ return bcrypt.compare(password, user.hashedPassword, function(
+ error,
+ match
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (match) {
+ return AuthenticationManager.checkRounds(
+ user,
+ user.hashedPassword,
+ password,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback(null, user)
+ }
+ )
+ } else {
+ return callback(null, null)
+ }
+ })
+ } else {
+ return callback(null, null)
+ }
+ } else {
+ return callback(null, null)
+ }
+ })
+ },
+
+ validateEmail(email) {
+ const parsed = EmailHelper.parseEmail(email)
+ if (parsed == null) {
+ return { message: 'email not valid' }
+ }
+ return null
+ },
+
+ // validates a password based on a similar set of rules to `complexPassword.js` on the frontend
+ // note that `passfield.js` enforces more rules than this, but these are the most commonly set.
+ // returns null on success, or an error string.
+ validatePassword(password) {
+ if (password == null) {
+ return { message: 'password not set' }
+ }
+
+ const allowAnyChars =
+ (Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.allowAnyChars
+ : undefined) === true
+ const min =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.length
+ : undefined,
+ x1 => x1.min
+ ) || 6
+ let max =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.length
+ : undefined,
+ x2 => x2.max
+ ) || 72
+
+ // we don't support passwords > 72 characters in length, because bcrypt truncates them
+ if (max > 72) {
+ max = 72
+ }
+
+ if (!(password.length >= min)) {
+ return { message: 'password is too short' }
+ }
+ if (!(password.length <= max)) {
+ return { message: 'password is too long' }
+ }
+ if (
+ !allowAnyChars &&
+ !AuthenticationManager._passwordCharactersAreValid(password)
+ ) {
+ return { message: 'password contains an invalid character' }
+ }
+ return null
+ },
+
+ setUserPassword(user_id, password, callback) {
+ if (callback == null) {
+ callback = function(error, changed) {}
+ }
+ const validation = this.validatePassword(password)
+ if (validation != null) {
+ return callback(validation.message)
+ }
+
+ return UserGetter.getUser(user_id, { email: 1, overleaf: 1 }, function(
+ error,
+ user
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ const v1IdExists =
+ (user.overleaf != null ? user.overleaf.id : undefined) != null
+ if (v1IdExists && Settings.overleaf != null) {
+ // v2 user in v2
+ // v2 user in v2, change password in v1
+ return AuthenticationManager.setUserPasswordInV1(
+ user.overleaf.id,
+ password,
+ callback
+ )
+ } else if (v1IdExists && Settings.overleaf == null) {
+ // v2 user in SL
+ return callback(new Errors.NotInV2Error('Password Reset Attempt'))
+ } else if (!v1IdExists && Settings.overleaf == null) {
+ // SL user in SL, change password in SL
+ return AuthenticationManager.setUserPasswordInV2(
+ user_id,
+ password,
+ callback
+ )
+ } else if (!v1IdExists && Settings.overleaf != null) {
+ // SL user in v2, should not happen
+ return callback(new Errors.SLInV2Error('Password Reset Attempt'))
+ } else {
+ return callback(new Error('Password Reset Attempt Failed'))
+ }
+ })
+ },
+
+ checkRounds(user, hashedPassword, password, callback) {
+ // Temporarily disable this function, TODO: re-enable this
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ if (
+ __guard__(
+ Settings != null ? Settings.security : undefined,
+ x1 => x1.disableBcryptRoundsUpgrades
+ )
+ ) {
+ return callback()
+ }
+ // check current number of rounds and rehash if necessary
+ const currentRounds = bcrypt.getRounds(hashedPassword)
+ if (currentRounds < BCRYPT_ROUNDS) {
+ return AuthenticationManager.setUserPassword(user._id, password, callback)
+ } else {
+ return callback()
+ }
+ },
+
+ setUserPasswordInV2(user_id, password, callback) {
+ const validation = this.validatePassword(password)
+ if (validation != null) {
+ return callback(validation.message)
+ }
+ const minorVersion = 'a'
+ return bcrypt.genSalt(BCRYPT_ROUNDS, minorVersion, function(error, salt) {
+ if (error != null) {
+ return callback(error)
+ }
+ return bcrypt.hash(password, salt, function(error, hash) {
+ if (error != null) {
+ return callback(error)
+ }
+ return db.users.update(
+ {
+ _id: ObjectId(user_id.toString())
+ },
+ {
+ $set: {
+ hashedPassword: hash
+ },
+ $unset: {
+ password: true
+ }
+ },
+ function(updateError, result) {
+ if (updateError != null) {
+ return callback(updateError)
+ }
+ return _checkWriteResult(result, callback)
+ }
+ )
+ })
+ })
+ },
+
+ setUserPasswordInV1(v1_user_id, password, callback) {
+ const validation = this.validatePassword(password)
+ if (validation != null) {
+ return callback(validation.message)
+ }
+
+ return V1Handler.doPasswordReset(v1_user_id, password, function(
+ error,
+ reset
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(error, reset)
+ })
+ },
+
+ _passwordCharactersAreValid(password) {
+ const digits =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.chars
+ : undefined,
+ x1 => x1.digits
+ ) || '1234567890'
+ const letters =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.chars
+ : undefined,
+ x2 => x2.letters
+ ) || 'abcdefghijklmnopqrstuvwxyz'
+ const letters_up =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.chars
+ : undefined,
+ x3 => x3.letters_up
+ ) || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ const symbols =
+ __guard__(
+ Settings.passwordStrengthOptions != null
+ ? Settings.passwordStrengthOptions.chars
+ : undefined,
+ x4 => x4.symbols
+ ) || '@#$%^&*()-_=+[]{};:<>/?!£€.,'
+
+ for (
+ let charIndex = 0, end = password.length - 1, asc = end >= 0;
+ asc ? charIndex <= end : charIndex >= end;
+ asc ? charIndex++ : charIndex--
+ ) {
+ if (
+ !(digits.indexOf(password[charIndex]) > -1) &&
+ !(letters.indexOf(password[charIndex]) > -1) &&
+ !(letters_up.indexOf(password[charIndex]) > -1) &&
+ !(symbols.indexOf(password[charIndex]) > -1)
+ ) {
+ return false
+ }
+ }
+ return true
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Authorization/AuthorizationManager.js b/services/web/app/src/Features/Authorization/AuthorizationManager.js
new file mode 100644
index 0000000000..5c101c8aeb
--- /dev/null
+++ b/services/web/app/src/Features/Authorization/AuthorizationManager.js
@@ -0,0 +1,289 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AuthorizationManager
+const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
+const ProjectGetter = require('../Project/ProjectGetter')
+const { User } = require('../../models/User')
+const PrivilegeLevels = require('./PrivilegeLevels')
+const PublicAccessLevels = require('./PublicAccessLevels')
+const Errors = require('../Errors/Errors')
+const { ObjectId } = require('mongojs')
+const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
+
+module.exports = AuthorizationManager = {
+ getPublicAccessLevel(project_id, callback) {
+ if (callback == null) {
+ callback = function(err, level) {}
+ }
+ if (!ObjectId.isValid(project_id)) {
+ return callback(new Error('invalid project id'))
+ }
+ // Note, the Project property in the DB is `publicAccesLevel`, without the second `s`
+ return ProjectGetter.getProject(
+ project_id,
+ { publicAccesLevel: 1 },
+ function(error, project) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (project == null) {
+ return callback(
+ new Errors.NotFoundError(`no project found with id ${project_id}`)
+ )
+ }
+ return callback(null, project.publicAccesLevel)
+ }
+ )
+ },
+
+ // Get the privilege level that the user has for the project
+ // Returns:
+ // * privilegeLevel: "owner", "readAndWrite", of "readOnly" if the user has
+ // access. false if the user does not have access
+ // * becausePublic: true if the access level is only because the project is public.
+ // * becauseSiteAdmin: true if access level is only because user is admin
+ getPrivilegeLevelForProject(user_id, project_id, token, callback) {
+ if (callback == null) {
+ callback = function(
+ error,
+ privilegeLevel,
+ becausePublic,
+ becauseSiteAdmin
+ ) {}
+ }
+ if (user_id == null) {
+ // User is Anonymous, Try Token-based access
+ return AuthorizationManager.getPublicAccessLevel(project_id, function(
+ err,
+ publicAccessLevel
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
+ // Anonymous users can have read-only access to token-based projects,
+ // while read-write access must be logged in,
+ // unless the `enableAnonymousReadAndWriteSharing` setting is enabled
+ return TokenAccessHandler.isValidToken(project_id, token, function(
+ err,
+ isValidReadAndWrite,
+ isValidReadOnly
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (isValidReadOnly) {
+ // Grant anonymous user read-only access
+ return callback(null, PrivilegeLevels.READ_ONLY, false, false)
+ } else if (
+ isValidReadAndWrite &&
+ TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
+ ) {
+ // Grant anonymous user read-and-write access
+ return callback(
+ null,
+ PrivilegeLevels.READ_AND_WRITE,
+ false,
+ false
+ )
+ } else {
+ // Deny anonymous access
+ return callback(null, PrivilegeLevels.NONE, false, false)
+ }
+ })
+ } else if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
+ // Legacy public read-only access for anonymous user
+ return callback(null, PrivilegeLevels.READ_ONLY, true, false)
+ } else if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
+ // Legacy public read-write access for anonymous user
+ return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
+ } else {
+ // Deny anonymous user access
+ return callback(null, PrivilegeLevels.NONE, false, false)
+ }
+ })
+ } else {
+ // User is present, get their privilege level from database
+ return CollaboratorsHandler.getMemberIdPrivilegeLevel(
+ user_id,
+ project_id,
+ function(error, privilegeLevel) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (
+ privilegeLevel != null &&
+ privilegeLevel !== PrivilegeLevels.NONE
+ ) {
+ // The user has direct access
+ return callback(null, privilegeLevel, false, false)
+ } else {
+ return AuthorizationManager.isUserSiteAdmin(user_id, function(
+ error,
+ isAdmin
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (isAdmin) {
+ return callback(null, PrivilegeLevels.OWNER, false, true)
+ } else {
+ // Legacy public-access system
+ // User is present (not anonymous), but does not have direct access
+ return AuthorizationManager.getPublicAccessLevel(
+ project_id,
+ function(err, publicAccessLevel) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
+ return callback(
+ null,
+ PrivilegeLevels.READ_ONLY,
+ true,
+ false
+ )
+ } else if (
+ publicAccessLevel === PublicAccessLevels.READ_AND_WRITE
+ ) {
+ return callback(
+ null,
+ PrivilegeLevels.READ_AND_WRITE,
+ true,
+ false
+ )
+ } else {
+ return callback(null, PrivilegeLevels.NONE, false, false)
+ }
+ }
+ )
+ }
+ })
+ }
+ }
+ )
+ }
+ },
+
+ canUserReadProject(user_id, project_id, token, callback) {
+ if (callback == null) {
+ callback = function(error, canRead) {}
+ }
+ return AuthorizationManager.getPrivilegeLevelForProject(
+ user_id,
+ project_id,
+ token,
+ function(error, privilegeLevel) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(
+ null,
+ [
+ PrivilegeLevels.OWNER,
+ PrivilegeLevels.READ_AND_WRITE,
+ PrivilegeLevels.READ_ONLY
+ ].includes(privilegeLevel)
+ )
+ }
+ )
+ },
+
+ canUserWriteProjectContent(user_id, project_id, token, callback) {
+ if (callback == null) {
+ callback = function(error, canWriteContent) {}
+ }
+ return AuthorizationManager.getPrivilegeLevelForProject(
+ user_id,
+ project_id,
+ token,
+ function(error, privilegeLevel) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(
+ null,
+ [PrivilegeLevels.OWNER, PrivilegeLevels.READ_AND_WRITE].includes(
+ privilegeLevel
+ )
+ )
+ }
+ )
+ },
+
+ canUserWriteProjectSettings(user_id, project_id, token, callback) {
+ if (callback == null) {
+ callback = function(error, canWriteSettings) {}
+ }
+ return AuthorizationManager.getPrivilegeLevelForProject(
+ user_id,
+ project_id,
+ token,
+ function(error, privilegeLevel, becausePublic) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (privilegeLevel === PrivilegeLevels.OWNER) {
+ return callback(null, true)
+ } else if (
+ privilegeLevel === PrivilegeLevels.READ_AND_WRITE &&
+ !becausePublic
+ ) {
+ return callback(null, true)
+ } else {
+ return callback(null, false)
+ }
+ }
+ )
+ },
+
+ canUserAdminProject(user_id, project_id, token, callback) {
+ if (callback == null) {
+ callback = function(error, canAdmin, becauseSiteAdmin) {}
+ }
+ return AuthorizationManager.getPrivilegeLevelForProject(
+ user_id,
+ project_id,
+ token,
+ function(error, privilegeLevel, becausePublic, becauseSiteAdmin) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(
+ null,
+ privilegeLevel === PrivilegeLevels.OWNER,
+ becauseSiteAdmin
+ )
+ }
+ )
+ },
+
+ isUserSiteAdmin(user_id, callback) {
+ if (callback == null) {
+ callback = function(error, isAdmin) {}
+ }
+ if (user_id == null) {
+ return callback(null, false)
+ }
+ return User.findOne({ _id: user_id }, { isAdmin: 1 }, function(
+ error,
+ user
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, (user != null ? user.isAdmin : undefined) === true)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js b/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js
new file mode 100644
index 0000000000..bae9a9d7b0
--- /dev/null
+++ b/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js
@@ -0,0 +1,298 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let AuthorizationMiddleware
+const AuthorizationManager = require('./AuthorizationManager')
+const async = require('async')
+const logger = require('logger-sharelatex')
+const { ObjectId } = require('mongojs')
+const Errors = require('../Errors/Errors')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
+
+module.exports = AuthorizationMiddleware = {
+ ensureUserCanReadMultipleProjects(req, res, next) {
+ const project_ids = (req.query.project_ids || '').split(',')
+ return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ // Remove the projects we have access to. Note rejectSeries doesn't use
+ // errors in callbacks
+ return async.rejectSeries(
+ project_ids,
+ function(project_id, cb) {
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.canUserReadProject(
+ user_id,
+ project_id,
+ token,
+ function(error, canRead) {
+ if (error != null) {
+ return next(error)
+ }
+ return cb(canRead)
+ }
+ )
+ },
+ function(unauthorized_project_ids) {
+ if (unauthorized_project_ids.length > 0) {
+ return AuthorizationMiddleware.redirectToRestricted(req, res, next)
+ } else {
+ return next()
+ }
+ }
+ )
+ })
+ },
+
+ ensureUserCanReadProject(req, res, next) {
+ return AuthorizationMiddleware._getUserAndProjectId(req, function(
+ error,
+ user_id,
+ project_id
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.canUserReadProject(
+ user_id,
+ project_id,
+ token,
+ function(error, canRead) {
+ if (error != null) {
+ return next(error)
+ }
+ if (canRead) {
+ logger.log(
+ { user_id, project_id },
+ 'allowing user read access to project'
+ )
+ return next()
+ } else {
+ logger.log(
+ { user_id, project_id },
+ 'denying user read access to project'
+ )
+ if (
+ __guard__(
+ req.headers != null ? req.headers['accept'] : undefined,
+ x => x.match(/^application\/json.*$/)
+ )
+ ) {
+ return res.sendStatus(403)
+ } else {
+ return AuthorizationMiddleware.redirectToRestricted(
+ req,
+ res,
+ next
+ )
+ }
+ }
+ }
+ )
+ })
+ },
+
+ ensureUserCanWriteProjectSettings(req, res, next) {
+ return AuthorizationMiddleware._getUserAndProjectId(req, function(
+ error,
+ user_id,
+ project_id
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.canUserWriteProjectSettings(
+ user_id,
+ project_id,
+ token,
+ function(error, canWrite) {
+ if (error != null) {
+ return next(error)
+ }
+ if (canWrite) {
+ logger.log(
+ { user_id, project_id },
+ 'allowing user write access to project settings'
+ )
+ return next()
+ } else {
+ logger.log(
+ { user_id, project_id },
+ 'denying user write access to project settings'
+ )
+ return AuthorizationMiddleware.redirectToRestricted(req, res, next)
+ }
+ }
+ )
+ })
+ },
+
+ ensureUserCanWriteProjectContent(req, res, next) {
+ return AuthorizationMiddleware._getUserAndProjectId(req, function(
+ error,
+ user_id,
+ project_id
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.canUserWriteProjectContent(
+ user_id,
+ project_id,
+ token,
+ function(error, canWrite) {
+ if (error != null) {
+ return next(error)
+ }
+ if (canWrite) {
+ logger.log(
+ { user_id, project_id },
+ 'allowing user write access to project content'
+ )
+ return next()
+ } else {
+ logger.log(
+ { user_id, project_id },
+ 'denying user write access to project settings'
+ )
+ return AuthorizationMiddleware.redirectToRestricted(req, res, next)
+ }
+ }
+ )
+ })
+ },
+
+ ensureUserCanAdminProject(req, res, next) {
+ return AuthorizationMiddleware._getUserAndProjectId(req, function(
+ error,
+ user_id,
+ project_id
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.canUserAdminProject(
+ user_id,
+ project_id,
+ token,
+ function(error, canAdmin) {
+ if (error != null) {
+ return next(error)
+ }
+ if (canAdmin) {
+ logger.log(
+ { user_id, project_id },
+ 'allowing user admin access to project'
+ )
+ return next()
+ } else {
+ logger.log(
+ { user_id, project_id },
+ 'denying user admin access to project'
+ )
+ return AuthorizationMiddleware.redirectToRestricted(req, res, next)
+ }
+ }
+ )
+ })
+ },
+
+ ensureUserIsSiteAdmin(req, res, next) {
+ return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ return AuthorizationManager.isUserSiteAdmin(user_id, function(
+ error,
+ isAdmin
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ if (isAdmin) {
+ logger.log({ user_id }, 'allowing user admin access to site')
+ return next()
+ } else {
+ logger.log({ user_id }, 'denying user admin access to site')
+ return AuthorizationMiddleware.redirectToRestricted(req, res, next)
+ }
+ })
+ })
+ },
+
+ _getUserAndProjectId(req, callback) {
+ if (callback == null) {
+ callback = function(error, user_id, project_id) {}
+ }
+ const project_id =
+ (req.params != null ? req.params.project_id : undefined) ||
+ (req.params != null ? req.params.Project_id : undefined)
+ if (project_id == null) {
+ return callback(new Error('Expected project_id in request parameters'))
+ }
+ if (!ObjectId.isValid(project_id)) {
+ return callback(
+ new Errors.NotFoundError(`invalid project_id: ${project_id}`)
+ )
+ }
+ return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, user_id, project_id)
+ })
+ },
+
+ _getUserId(req, callback) {
+ if (callback == null) {
+ callback = function(error, user_id) {}
+ }
+ const user_id =
+ AuthenticationController.getLoggedInUserId(req) ||
+ __guard__(req != null ? req.oauth_user : undefined, x => x._id) ||
+ null
+ return callback(null, user_id)
+ },
+
+ redirectToRestricted(req, res, next) {
+ // TODO: move this to throwing ForbiddenError
+ return res.redirect(`/restricted?from=${encodeURIComponent(req.url)}`)
+ },
+
+ restricted(req, res, next) {
+ if (AuthenticationController.isUserLoggedIn(req)) {
+ return res.render('user/restricted', { title: 'restricted' })
+ } else {
+ const { from } = req.query
+ logger.log({ from }, 'redirecting to login')
+ const redirect_to = '/login'
+ if (from != null) {
+ AuthenticationController.setRedirectInSession(req, from)
+ }
+ return res.redirect(redirect_to)
+ }
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Authorization/PrivilegeLevels.js b/services/web/app/src/Features/Authorization/PrivilegeLevels.js
new file mode 100644
index 0000000000..6e7c310cec
--- /dev/null
+++ b/services/web/app/src/Features/Authorization/PrivilegeLevels.js
@@ -0,0 +1,8 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+module.exports = {
+ NONE: false,
+ READ_ONLY: 'readOnly',
+ READ_AND_WRITE: 'readAndWrite',
+ OWNER: 'owner'
+}
diff --git a/services/web/app/src/Features/Authorization/PublicAccessLevels.js b/services/web/app/src/Features/Authorization/PublicAccessLevels.js
new file mode 100644
index 0000000000..ed918f4dab
--- /dev/null
+++ b/services/web/app/src/Features/Authorization/PublicAccessLevels.js
@@ -0,0 +1,8 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+module.exports = {
+ READ_ONLY: 'readOnly', // LEGACY
+ READ_AND_WRITE: 'readAndWrite', // LEGACY
+ PRIVATE: 'private',
+ TOKEN_BASED: 'tokenBased'
+}
diff --git a/services/web/app/src/Features/Authorization/Sources.js b/services/web/app/src/Features/Authorization/Sources.js
new file mode 100644
index 0000000000..271e7fca46
--- /dev/null
+++ b/services/web/app/src/Features/Authorization/Sources.js
@@ -0,0 +1,7 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+module.exports = {
+ INVITE: 'invite',
+ TOKEN: 'token',
+ OWNER: 'owner'
+}
diff --git a/services/web/app/src/Features/BetaProgram/BetaProgramController.js b/services/web/app/src/Features/BetaProgram/BetaProgramController.js
new file mode 100644
index 0000000000..b5e82709e1
--- /dev/null
+++ b/services/web/app/src/Features/BetaProgram/BetaProgramController.js
@@ -0,0 +1,64 @@
+/* eslint-disable
+ camelcase,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let BetaProgramController
+const BetaProgramHandler = require('./BetaProgramHandler')
+const UserGetter = require('../User/UserGetter')
+const Settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+
+module.exports = BetaProgramController = {
+ optIn(req, res, next) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ logger.log({ user_id }, 'user opting in to beta program')
+ if (user_id == null) {
+ return next(new Error('no user id in session'))
+ }
+ return BetaProgramHandler.optIn(user_id, function(err) {
+ if (err) {
+ return next(err)
+ }
+ return res.redirect('/beta/participate')
+ })
+ },
+
+ optOut(req, res, next) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ logger.log({ user_id }, 'user opting out of beta program')
+ if (user_id == null) {
+ return next(new Error('no user id in session'))
+ }
+ return BetaProgramHandler.optOut(user_id, function(err) {
+ if (err) {
+ return next(err)
+ }
+ return res.redirect('/beta/participate')
+ })
+ },
+
+ optInPage(req, res, next) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ logger.log({ user_id }, 'showing beta participation page for user')
+ return UserGetter.getUser(user_id, function(err, user) {
+ if (err) {
+ logger.err({ err, user_id }, 'error fetching user')
+ return next(err)
+ }
+ return res.render('beta_program/opt_in', {
+ title: 'sharelatex_beta_program',
+ user,
+ languages: Settings.languages
+ })
+ })
+ }
+}
diff --git a/services/web/app/src/Features/BetaProgram/BetaProgramHandler.js b/services/web/app/src/Features/BetaProgram/BetaProgramHandler.js
new file mode 100644
index 0000000000..adccaaa2d4
--- /dev/null
+++ b/services/web/app/src/Features/BetaProgram/BetaProgramHandler.js
@@ -0,0 +1,62 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let BetaProgramHandler
+const { User } = require('../../models/User')
+const logger = require('logger-sharelatex')
+const metrics = require('metrics-sharelatex')
+
+module.exports = BetaProgramHandler = {
+ optIn(user_id, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return User.findById(user_id, function(err, user) {
+ if (err) {
+ logger.err({ err, user_id }, 'problem adding user to beta')
+ return callback(err)
+ }
+ metrics.inc('beta-program.opt-in')
+ user.betaProgram = true
+ return user.save(function(err) {
+ if (err) {
+ logger.err({ err, user_id }, 'problem adding user to beta')
+ return callback(err)
+ }
+ return callback(null)
+ })
+ })
+ },
+
+ optOut(user_id, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return User.findById(user_id, function(err, user) {
+ if (err) {
+ logger.err({ err, user_id }, 'problem removing user from beta')
+ return callback(err)
+ }
+ metrics.inc('beta-program.opt-out')
+ user.betaProgram = false
+ return user.save(function(err) {
+ if (err) {
+ logger.err({ err, user_id }, 'problem removing user from beta')
+ return callback(err)
+ }
+ return callback(null)
+ })
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Blog/BlogController.js b/services/web/app/src/Features/Blog/BlogController.js
new file mode 100644
index 0000000000..465c9b3179
--- /dev/null
+++ b/services/web/app/src/Features/Blog/BlogController.js
@@ -0,0 +1,105 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let BlogController
+const request = require('request')
+const settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+const _ = require('underscore')
+const ErrorController = require('../Errors/ErrorController')
+
+module.exports = BlogController = {
+ getPage(req, res, next) {
+ const url = req.url != null ? req.url.toLowerCase() : undefined
+ const blogUrl = `${settings.apis.blog.url}${url}`
+
+ const extensionsToProxy = [
+ '.png',
+ '.xml',
+ '.jpeg',
+ '.jpg',
+ '.json',
+ '.zip',
+ '.eps',
+ '.gif'
+ ]
+
+ const shouldProxy = _.find(
+ extensionsToProxy,
+ extension => url.indexOf(extension) !== -1
+ )
+
+ if (shouldProxy) {
+ return BlogController._directProxy(blogUrl, res)
+ }
+
+ logger.log({ url }, 'proxying request to blog api')
+ return request.get(blogUrl, function(err, r, data) {
+ if (
+ (r != null ? r.statusCode : undefined) === 404 ||
+ (r != null ? r.statusCode : undefined) === 403
+ ) {
+ return ErrorController.notFound(req, res, next)
+ }
+ if (err != null) {
+ return res.send(500)
+ }
+ data = data.trim()
+ try {
+ data = JSON.parse(data)
+ if (
+ __guard__(
+ settings.cdn != null ? settings.cdn.web : undefined,
+ x => x.host
+ ) != null
+ ) {
+ if (data != null) {
+ data.content = __guard__(
+ data != null ? data.content : undefined,
+ x1 =>
+ x1.replace(
+ /src="(\/[^"]+)"/g,
+ `src='${__guard__(
+ settings.cdn != null ? settings.cdn.web : undefined,
+ x2 => x2.host
+ )}$1'`
+ )
+ )
+ }
+ }
+ } catch (error) {
+ err = error
+ logger.err({ err, data }, 'error parsing data from data')
+ }
+ return res.render('blog/blog_holder', data)
+ })
+ },
+
+ getIndexPage(req, res) {
+ req.url = '/blog/index.html'
+ return BlogController.getPage(req, res)
+ },
+
+ _directProxy(originUrl, res) {
+ const upstream = request.get(originUrl)
+ upstream.on('error', error =>
+ logger.error({ err: error }, 'blog proxy error')
+ )
+ return upstream.pipe(res)
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Blog/BlogHandler.js b/services/web/app/src/Features/Blog/BlogHandler.js
new file mode 100644
index 0000000000..b0e0d51aff
--- /dev/null
+++ b/services/web/app/src/Features/Blog/BlogHandler.js
@@ -0,0 +1,49 @@
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+ standard/no-callback-literal,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let BlogHandler
+const request = require('request')
+const settings = require('settings-sharelatex')
+const _ = require('underscore')
+const logger = require('logger-sharelatex')
+
+module.exports = BlogHandler = {
+ getLatestAnnouncements(callback) {
+ const blogUrl = `${settings.apis.blog.url}/blog/latestannouncements.json`
+ const opts = {
+ url: blogUrl,
+ json: true,
+ timeout: 1000
+ }
+ return request.get(opts, function(err, res, announcements) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (res.statusCode !== 200) {
+ return callback('blog announcement returned non 200')
+ }
+ logger.log(
+ {
+ announcementsLength:
+ announcements != null ? announcements.length : undefined
+ },
+ 'announcements returned'
+ )
+ announcements = _.map(announcements, function(announcement) {
+ announcement.date = new Date(announcement.date)
+ return announcement
+ })
+ return callback(err, announcements)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/BrandVariations/BrandVariationsHandler.js b/services/web/app/src/Features/BrandVariations/BrandVariationsHandler.js
new file mode 100644
index 0000000000..89e25ad8a7
--- /dev/null
+++ b/services/web/app/src/Features/BrandVariations/BrandVariationsHandler.js
@@ -0,0 +1,98 @@
+/* eslint-disable
+ handle-callback-err,
+ max-len,
+ no-return-assign,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let BrandVariationsHandler
+const url = require('url')
+const settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+const V1Api = require('../V1/V1Api')
+
+module.exports = BrandVariationsHandler = {
+ getBrandVariationById(brandVariationId, callback) {
+ if (callback == null) {
+ callback = function(error, brandVariationDetails) {}
+ }
+ if (brandVariationId == null || brandVariationId === '') {
+ return callback(new Error('Branding variation id not provided'))
+ }
+ logger.log({ brandVariationId }, 'fetching brand variation details from v1')
+ return V1Api.request(
+ {
+ uri: `/api/v2/brand_variations/${brandVariationId}`
+ },
+ function(error, response, brandVariationDetails) {
+ if (error != null) {
+ logger.err(
+ { brandVariationId, error },
+ 'error getting brand variation details'
+ )
+ return callback(error)
+ }
+ _formatBrandVariationDetails(brandVariationDetails)
+ return callback(null, brandVariationDetails)
+ }
+ )
+ }
+}
+
+var _formatBrandVariationDetails = function(details) {
+ if (details.export_url != null) {
+ details.export_url = _setV1AsHostIfRelativeURL(details.export_url)
+ }
+ if (details.home_url != null) {
+ details.home_url = _setV1AsHostIfRelativeURL(details.home_url)
+ }
+ if (details.logo_url != null) {
+ details.logo_url = _setV1AsHostIfRelativeURL(details.logo_url)
+ }
+ if (details.journal_guidelines_url != null) {
+ details.journal_guidelines_url = _setV1AsHostIfRelativeURL(
+ details.journal_guidelines_url
+ )
+ }
+ if (details.journal_cover_url != null) {
+ details.journal_cover_url = _setV1AsHostIfRelativeURL(
+ details.journal_cover_url
+ )
+ }
+ if (details.submission_confirmation_page_logo_url != null) {
+ details.submission_confirmation_page_logo_url = _setV1AsHostIfRelativeURL(
+ details.submission_confirmation_page_logo_url
+ )
+ }
+ if (details.publish_menu_icon != null) {
+ return (details.publish_menu_icon = _setV1AsHostIfRelativeURL(
+ details.publish_menu_icon
+ ))
+ }
+}
+
+var _setV1AsHostIfRelativeURL = urlString =>
+ // The first argument is the base URL to resolve against if the second argument is not absolute.
+ // As it only applies if the second argument is not absolute, we can use it to transform relative URLs into
+ // absolute ones using v1 as the host. If the URL is absolute (e.g. a filepicker one), then the base
+ // argument is just ignored
+ url.resolve(
+ __guard__(
+ __guard__(settings != null ? settings.apis : undefined, x1 => x1.v1),
+ x => x.url
+ ),
+ urlString
+ )
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Captcha/CaptchaMiddleware.js b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js
new file mode 100644
index 0000000000..a0b8805269
--- /dev/null
+++ b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js
@@ -0,0 +1,68 @@
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CaptchaMiddleware
+const request = require('request')
+const logger = require('logger-sharelatex')
+const Settings = require('settings-sharelatex')
+
+module.exports = CaptchaMiddleware = {
+ validateCaptcha(action) {
+ return function(req, res, next) {
+ if (
+ (Settings.recaptcha != null ? Settings.recaptcha.siteKey : undefined) ==
+ null
+ ) {
+ return next()
+ }
+ const inviteAndCaptchaDisabled =
+ action === 'invite' && Settings.recaptcha.disabled.invite
+ const registerAndCaptchaDisabled =
+ action === 'register' && Settings.recaptcha.disabled.register
+ if (inviteAndCaptchaDisabled || registerAndCaptchaDisabled) {
+ return next()
+ }
+ const response = req.body['g-recaptcha-response']
+ const options = {
+ form: {
+ secret: Settings.recaptcha.secretKey,
+ response
+ },
+ json: true
+ }
+ return request.post(
+ 'https://www.google.com/recaptcha/api/siteverify',
+ options,
+ function(error, response, body) {
+ if (error != null) {
+ return next(error)
+ }
+ if (!(body != null ? body.success : undefined)) {
+ logger.warn(
+ { statusCode: response.statusCode, body },
+ 'failed recaptcha siteverify request'
+ )
+ return res.status(400).send({
+ errorReason: 'cannot_verify_user_not_robot',
+ message: {
+ text:
+ 'Sorry, we could not verify that you are not a robot. Please check that Google reCAPTCHA is not being blocked by an ad blocker or firewall.'
+ }
+ })
+ } else {
+ return next()
+ }
+ }
+ )
+ }
+ }
+}
diff --git a/services/web/app/src/Features/Chat/ChatApiHandler.js b/services/web/app/src/Features/Chat/ChatApiHandler.js
new file mode 100644
index 0000000000..2f0a6689ae
--- /dev/null
+++ b/services/web/app/src/Features/Chat/ChatApiHandler.js
@@ -0,0 +1,184 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ChatApiHandler
+const request = require('request')
+const settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+
+module.exports = ChatApiHandler = {
+ _apiRequest(opts, callback) {
+ if (callback == null) {
+ callback = function(error, data) {}
+ }
+ return request(opts, function(error, response, data) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ return callback(null, data)
+ } else {
+ error = new Error(
+ `chat api returned non-success code: ${response.statusCode}`
+ )
+ error.statusCode = response.statusCode
+ logger.error({ err: error, opts }, 'error sending request to chat api')
+ return callback(error)
+ }
+ })
+ },
+
+ sendGlobalMessage(project_id, user_id, content, callback) {
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/messages`,
+ method: 'POST',
+ json: { user_id, content }
+ },
+ callback
+ )
+ },
+
+ getGlobalMessages(project_id, limit, before, callback) {
+ const qs = {}
+ if (limit != null) {
+ qs.limit = limit
+ }
+ if (before != null) {
+ qs.before = before
+ }
+
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/messages`,
+ method: 'GET',
+ qs,
+ json: true
+ },
+ callback
+ )
+ },
+
+ sendComment(project_id, thread_id, user_id, content, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}/messages`,
+ method: 'POST',
+ json: { user_id, content }
+ },
+ callback
+ )
+ },
+
+ getThreads(project_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${settings.apis.chat.internal_url}/project/${project_id}/threads`,
+ method: 'GET',
+ json: true
+ },
+ callback
+ )
+ },
+
+ resolveThread(project_id, thread_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}/resolve`,
+ method: 'POST',
+ json: { user_id }
+ },
+ callback
+ )
+ },
+
+ reopenThread(project_id, thread_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}/reopen`,
+ method: 'POST'
+ },
+ callback
+ )
+ },
+
+ deleteThread(project_id, thread_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}`,
+ method: 'DELETE'
+ },
+ callback
+ )
+ },
+
+ editMessage(project_id, thread_id, message_id, content, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}/messages/${message_id}/edit`,
+ method: 'POST',
+ json: {
+ content
+ }
+ },
+ callback
+ )
+ },
+
+ deleteMessage(project_id, thread_id, message_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ChatApiHandler._apiRequest(
+ {
+ url: `${
+ settings.apis.chat.internal_url
+ }/project/${project_id}/thread/${thread_id}/messages/${message_id}`,
+ method: 'DELETE'
+ },
+ callback
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Chat/ChatController.js b/services/web/app/src/Features/Chat/ChatController.js
new file mode 100644
index 0000000000..b8cc00924b
--- /dev/null
+++ b/services/web/app/src/Features/Chat/ChatController.js
@@ -0,0 +1,143 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-undef,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ChatController
+const ChatApiHandler = require('./ChatApiHandler')
+const EditorRealTimeController = require('../Editor/EditorRealTimeController')
+const logger = require('logger-sharelatex')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const UserInfoManager = require('../User/UserInfoManager')
+const UserInfoController = require('../User/UserInfoController')
+const async = require('async')
+
+module.exports = ChatController = {
+ sendMessage(req, res, next) {
+ const { project_id } = req.params
+ const { content } = req.body
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ if (user_id == null) {
+ const err = new Error('no logged-in user')
+ return next(err)
+ }
+ return ChatApiHandler.sendGlobalMessage(
+ project_id,
+ user_id,
+ content,
+ function(err, message) {
+ if (err != null) {
+ return next(err)
+ }
+ return UserInfoManager.getPersonalInfo(message.user_id, function(
+ err,
+ user
+ ) {
+ if (err != null) {
+ return next(err)
+ }
+ message.user = UserInfoController.formatPersonalInfo(user)
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'new-chat-message',
+ message
+ )
+ return res.send(204)
+ })
+ }
+ )
+ },
+
+ getMessages(req, res, next) {
+ const { project_id } = req.params
+ const { query } = req
+ logger.log({ project_id, query }, 'getting messages')
+ return ChatApiHandler.getGlobalMessages(
+ project_id,
+ query.limit,
+ query.before,
+ function(err, messages) {
+ if (err != null) {
+ return next(err)
+ }
+ return ChatController._injectUserInfoIntoThreads(
+ { global: { messages } },
+ function(err) {
+ if (err != null) {
+ return next(err)
+ }
+ logger.log(
+ { length: messages != null ? messages.length : undefined },
+ 'sending messages to client'
+ )
+ return res.json(messages)
+ }
+ )
+ }
+ )
+ },
+
+ _injectUserInfoIntoThreads(threads, callback) {
+ // There will be a lot of repitition of user_ids, so first build a list
+ // of unique ones to perform db look ups on, then use these to populate the
+ // user fields
+ let message, thread, thread_id, user_id
+ if (callback == null) {
+ callback = function(error, threads) {}
+ }
+ const user_ids = {}
+ for (thread_id in threads) {
+ thread = threads[thread_id]
+ if (thread.resolved) {
+ user_ids[thread.resolved_by_user_id] = true
+ }
+ for (message of Array.from(thread.messages)) {
+ user_ids[message.user_id] = true
+ }
+ }
+
+ const jobs = []
+ const users = {}
+ for (user_id in user_ids) {
+ const _ = user_ids[user_id]
+ ;(user_id =>
+ jobs.push(cb =>
+ UserInfoManager.getPersonalInfo(user_id, function(err, user) {
+ if (typeof error !== 'undefined' && error !== null) {
+ return cb(error)
+ }
+ user = UserInfoController.formatPersonalInfo(user)
+ users[user_id] = user
+ return cb()
+ })
+ ))(user_id)
+ }
+
+ return async.series(jobs, function(error) {
+ if (error != null) {
+ return callback(error)
+ }
+ for (thread_id in threads) {
+ thread = threads[thread_id]
+ if (thread.resolved) {
+ thread.resolved_by_user = users[thread.resolved_by_user_id]
+ }
+ for (message of Array.from(thread.messages)) {
+ message.user = users[message.user_id]
+ }
+ }
+ return callback(null, threads)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsController.js b/services/web/app/src/Features/Collaborators/CollaboratorsController.js
new file mode 100644
index 0000000000..29f018668b
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsController.js
@@ -0,0 +1,109 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CollaboratorsController
+const ProjectGetter = require('../Project/ProjectGetter')
+const CollaboratorsHandler = require('./CollaboratorsHandler')
+const ProjectEditorHandler = require('../Project/ProjectEditorHandler')
+const EditorRealTimeController = require('../Editor/EditorRealTimeController')
+const LimitationsManager = require('../Subscription/LimitationsManager')
+const UserGetter = require('../User/UserGetter')
+const EmailHelper = require('../Helpers/EmailHelper')
+const logger = require('logger-sharelatex')
+
+module.exports = CollaboratorsController = {
+ removeUserFromProject(req, res, next) {
+ const project_id = req.params.Project_id
+ const { user_id } = req.params
+ return CollaboratorsController._removeUserIdFromProject(
+ project_id,
+ user_id,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'project:membership:changed',
+ { members: true }
+ )
+ return res.sendStatus(204)
+ }
+ )
+ },
+
+ removeSelfFromProject(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const user_id = __guard__(
+ req.session != null ? req.session.user : undefined,
+ x => x._id
+ )
+ return CollaboratorsController._removeUserIdFromProject(
+ project_id,
+ user_id,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.sendStatus(204)
+ }
+ )
+ },
+
+ _removeUserIdFromProject(project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return CollaboratorsHandler.removeUserFromProject(
+ project_id,
+ user_id,
+ function(error) {
+ if (error != null) {
+ return callback(error)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'userRemovedFromProject',
+ user_id
+ )
+ return callback()
+ }
+ )
+ },
+
+ getAllMembers(req, res, next) {
+ const projectId = req.params.Project_id
+ logger.log({ projectId }, 'getting all active members for project')
+ return CollaboratorsHandler.getAllInvitedMembers(projectId, function(
+ err,
+ members
+ ) {
+ if (err != null) {
+ logger.err({ projectId }, 'error getting members for project')
+ return next(err)
+ }
+ return res.json({ members })
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsEmailHandler.js b/services/web/app/src/Features/Collaborators/CollaboratorsEmailHandler.js
new file mode 100644
index 0000000000..812c5b3cf4
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsEmailHandler.js
@@ -0,0 +1,49 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CollaboratorsEmailHandler
+const { Project } = require('../../models/Project')
+const EmailHandler = require('../Email/EmailHandler')
+const Settings = require('settings-sharelatex')
+
+module.exports = CollaboratorsEmailHandler = {
+ _buildInviteUrl(project, invite) {
+ return (
+ `${Settings.siteUrl}/project/${project._id}/invite/token/${
+ invite.token
+ }?` +
+ [
+ `project_name=${encodeURIComponent(project.name)}`,
+ `user_first_name=${encodeURIComponent(project.owner_ref.first_name)}`
+ ].join('&')
+ )
+ },
+
+ notifyUserOfProjectInvite(project_id, email, invite, sendingUser, callback) {
+ return Project.findOne({ _id: project_id })
+ .select('name owner_ref')
+ .populate('owner_ref')
+ .exec(function(err, project) {
+ const emailOptions = {
+ to: email,
+ replyTo: project.owner_ref.email,
+ project: {
+ name: project.name
+ },
+ inviteUrl: CollaboratorsEmailHandler._buildInviteUrl(project, invite),
+ owner: project.owner_ref,
+ sendingUser_id: sendingUser._id
+ }
+ return EmailHandler.sendEmail('projectInvite', emailOptions, callback)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsHandler.js b/services/web/app/src/Features/Collaborators/CollaboratorsHandler.js
new file mode 100644
index 0000000000..f9535b4249
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsHandler.js
@@ -0,0 +1,635 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CollaboratorsHandler
+const UserCreator = require('../User/UserCreator')
+const { Project } = require('../../models/Project')
+const ProjectGetter = require('../Project/ProjectGetter')
+const logger = require('logger-sharelatex')
+const UserGetter = require('../User/UserGetter')
+const ContactManager = require('../Contacts/ContactManager')
+const CollaboratorsEmailHandler = require('./CollaboratorsEmailHandler')
+const async = require('async')
+const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
+const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
+const Errors = require('../Errors/Errors')
+const EmailHelper = require('../Helpers/EmailHelper')
+const ProjectEditorHandler = require('../Project/ProjectEditorHandler')
+const Sources = require('../Authorization/Sources')
+const { ObjectId } = require('mongojs')
+
+module.exports = CollaboratorsHandler = {
+ getMemberIdsWithPrivilegeLevels(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, members) {}
+ }
+ const projection = {
+ owner_ref: 1,
+ collaberator_refs: 1,
+ readOnly_refs: 1,
+ tokenAccessReadOnly_refs: 1,
+ tokenAccessReadAndWrite_refs: 1,
+ publicAccesLevel: 1
+ }
+ return ProjectGetter.getProject(project_id, projection, function(
+ error,
+ project
+ ) {
+ let member_id
+ if (error != null) {
+ return callback(error)
+ }
+ if (project == null) {
+ return callback(
+ new Errors.NotFoundError(`no project found with id ${project_id}`)
+ )
+ }
+ const members = []
+ members.push({
+ id: project.owner_ref.toString(),
+ privilegeLevel: PrivilegeLevels.OWNER,
+ source: Sources.OWNER
+ })
+ for (member_id of Array.from(project.collaberator_refs || [])) {
+ members.push({
+ id: member_id.toString(),
+ privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
+ source: Sources.INVITE
+ })
+ }
+ for (member_id of Array.from(project.readOnly_refs || [])) {
+ members.push({
+ id: member_id.toString(),
+ privilegeLevel: PrivilegeLevels.READ_ONLY,
+ source: Sources.INVITE
+ })
+ }
+ if (project.publicAccesLevel === PublicAccessLevels.TOKEN_BASED) {
+ for (member_id of Array.from(
+ project.tokenAccessReadAndWrite_refs || []
+ )) {
+ members.push({
+ id: member_id.toString(),
+ privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
+ source: Sources.TOKEN
+ })
+ }
+ for (member_id of Array.from(project.tokenAccessReadOnly_refs || [])) {
+ members.push({
+ id: member_id.toString(),
+ privilegeLevel: PrivilegeLevels.READ_ONLY,
+ source: Sources.TOKEN
+ })
+ }
+ }
+ return callback(null, members)
+ })
+ },
+
+ getMemberIds(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, member_ids) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, members.map(m => m.id))
+ }
+ )
+ },
+
+ getInvitedMemberIds(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, member_ids) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(
+ null,
+ members.filter(m => m.source !== Sources.TOKEN).map(m => m.id)
+ )
+ }
+ )
+ },
+
+ USER_PROJECTION: {
+ _id: 1,
+ email: 1,
+ features: 1,
+ first_name: 1,
+ last_name: 1,
+ signUpDate: 1
+ },
+ _loadMembers(members, callback) {
+ if (callback == null) {
+ callback = function(error, users) {}
+ }
+ const result = []
+ return async.mapLimit(
+ members,
+ 3,
+ (member, cb) =>
+ UserGetter.getUserOrUserStubById(
+ member.id,
+ CollaboratorsHandler.USER_PROJECTION,
+ function(error, user) {
+ if (error != null) {
+ return cb(error)
+ }
+ if (user != null) {
+ result.push({ user, privilegeLevel: member.privilegeLevel })
+ }
+ return cb()
+ }
+ ),
+ function(error) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, result)
+ }
+ )
+ },
+
+ getMembersWithPrivilegeLevels(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, members) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (members == null) {
+ members = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ return CollaboratorsHandler._loadMembers(members, (error, users) =>
+ callback(error, users)
+ )
+ }
+ )
+ },
+
+ getInvitedMembersWithPrivilegeLevels(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, members) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (members == null) {
+ members = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ members = members.filter(m => m.source !== Sources.TOKEN)
+ return CollaboratorsHandler._loadMembers(members, (error, users) =>
+ callback(error, users)
+ )
+ }
+ )
+ },
+
+ getTokenMembersWithPrivilegeLevels(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, members) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (members == null) {
+ members = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ members = members.filter(m => m.source === Sources.TOKEN)
+ return CollaboratorsHandler._loadMembers(members, (error, users) =>
+ callback(error, users)
+ )
+ }
+ )
+ },
+
+ getMemberIdPrivilegeLevel(user_id, project_id, callback) {
+ // In future if the schema changes and getting all member ids is more expensive (multiple documents)
+ // then optimise this.
+ if (callback == null) {
+ callback = function(error, privilegeLevel) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (members == null) {
+ members = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ for (let member of Array.from(members)) {
+ if (
+ member.id === (user_id != null ? user_id.toString() : undefined)
+ ) {
+ return callback(null, member.privilegeLevel)
+ }
+ }
+ return callback(null, PrivilegeLevels.NONE)
+ }
+ )
+ },
+
+ getInvitedMemberCount(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, count) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(
+ null,
+ (members || []).filter(m => m.source !== Sources.TOKEN).length
+ )
+ }
+ )
+ },
+
+ getInvitedCollaboratorCount(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, count) {}
+ }
+ return CollaboratorsHandler.getInvitedMemberCount(project_id, function(
+ error,
+ count
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, count - 1)
+ })
+ }, // Don't count project owner
+
+ isUserInvitedMemberOfProject(user_id, project_id, callback) {
+ if (callback == null) {
+ callback = function(error, isMember, privilegeLevel) {}
+ }
+ return CollaboratorsHandler.getMemberIdsWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (members == null) {
+ members = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ for (let member of Array.from(members)) {
+ if (
+ member.id.toString() === user_id.toString() &&
+ member.source !== Sources.TOKEN
+ ) {
+ return callback(null, true, member.privilegeLevel)
+ }
+ }
+ return callback(null, false, null)
+ }
+ )
+ },
+
+ getProjectsUserIsMemberOf(user_id, fields, callback) {
+ if (callback == null) {
+ callback = function(error, results) {}
+ }
+ return async.mapLimit(
+ [
+ { collaberator_refs: user_id },
+ { readOnly_refs: user_id },
+ {
+ tokenAccessReadAndWrite_refs: user_id,
+ publicAccesLevel: PublicAccessLevels.TOKEN_BASED
+ },
+ {
+ tokenAccessReadOnly_refs: user_id,
+ publicAccesLevel: PublicAccessLevels.TOKEN_BASED
+ }
+ ],
+ 2,
+ (query, cb) => Project.find(query, fields, cb),
+ function(error, results) {
+ if (error != null) {
+ return callback(error)
+ }
+ const projects = {
+ readAndWrite: results[0],
+ readOnly: results[1],
+ tokenReadAndWrite: results[2],
+ tokenReadOnly: results[3]
+ }
+ return callback(null, projects)
+ }
+ )
+ },
+
+ removeUserFromProject(project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ user_id, project_id }, 'removing user')
+ const conditions = { _id: project_id }
+ const update = { $pull: {} }
+ update['$pull'] = {
+ collaberator_refs: user_id,
+ readOnly_refs: user_id,
+ tokenAccessReadOnly_refs: user_id,
+ tokenAccessReadAndWrite_refs: user_id
+ }
+ return Project.update(conditions, update, function(err) {
+ if (err != null) {
+ logger.error(
+ { err },
+ 'problem removing user from project collaberators'
+ )
+ }
+ return callback(err)
+ })
+ },
+
+ removeUserFromAllProjets(user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return CollaboratorsHandler.getProjectsUserIsMemberOf(
+ user_id,
+ { _id: 1 },
+ function(
+ error,
+ { readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly }
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ const allProjects = readAndWrite
+ .concat(readOnly)
+ .concat(tokenReadAndWrite)
+ .concat(tokenReadOnly)
+ const jobs = []
+ for (let project of Array.from(allProjects)) {
+ ;(project =>
+ jobs.push(function(cb) {
+ if (project == null) {
+ return cb()
+ }
+ return CollaboratorsHandler.removeUserFromProject(
+ project._id,
+ user_id,
+ cb
+ )
+ }))(project)
+ }
+ return async.series(jobs, callback)
+ }
+ )
+ },
+
+ addUserIdToProject(
+ project_id,
+ adding_user_id,
+ user_id,
+ privilegeLevel,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ProjectGetter.getProject(
+ project_id,
+ { collaberator_refs: 1, readOnly_refs: 1 },
+ function(error, project) {
+ let level
+ if (error != null) {
+ return callback(error)
+ }
+ let existing_users = project.collaberator_refs || []
+ existing_users = existing_users.concat(project.readOnly_refs || [])
+ existing_users = existing_users.map(u => u.toString())
+ if (existing_users.indexOf(user_id.toString()) > -1) {
+ return callback(null) // User already in Project
+ }
+
+ if (privilegeLevel === PrivilegeLevels.READ_AND_WRITE) {
+ level = { collaberator_refs: user_id }
+ logger.log(
+ { privileges: 'readAndWrite', user_id, project_id },
+ 'adding user'
+ )
+ } else if (privilegeLevel === PrivilegeLevels.READ_ONLY) {
+ level = { readOnly_refs: user_id }
+ logger.log(
+ { privileges: 'readOnly', user_id, project_id },
+ 'adding user'
+ )
+ } else {
+ return callback(
+ new Error(`unknown privilegeLevel: ${privilegeLevel}`)
+ )
+ }
+
+ if (adding_user_id) {
+ ContactManager.addContact(adding_user_id, user_id)
+ }
+
+ return Project.update(
+ { _id: project_id },
+ { $addToSet: level },
+ function(error) {
+ if (error != null) {
+ return callback(error)
+ }
+ // Flush to TPDS in background to add files to collaborator's Dropbox
+ const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+ ProjectEntityHandler.flushProjectToThirdPartyDataStore(
+ project_id,
+ function(error) {
+ if (error != null) {
+ return logger.error(
+ { err: error, project_id, user_id },
+ 'error flushing to TPDS after adding collaborator'
+ )
+ }
+ }
+ )
+ return callback()
+ }
+ )
+ }
+ )
+ },
+
+ getAllInvitedMembers(projectId, callback) {
+ if (callback == null) {
+ callback = function(err, members) {}
+ }
+ logger.log({ projectId }, 'fetching all members')
+ return CollaboratorsHandler.getInvitedMembersWithPrivilegeLevels(
+ projectId,
+ function(error, rawMembers) {
+ if (error != null) {
+ logger.err({ projectId, error }, 'error getting members for project')
+ return callback(error)
+ }
+ const {
+ owner,
+ members
+ } = ProjectEditorHandler.buildOwnerAndMembersViews(rawMembers)
+ return callback(null, members)
+ }
+ )
+ },
+
+ userIsTokenMember(userId, projectId, callback) {
+ if (callback == null) {
+ callback = function(err, isTokenMember) {}
+ }
+ userId = ObjectId(userId.toString())
+ projectId = ObjectId(projectId.toString())
+ return Project.findOne(
+ {
+ _id: projectId,
+ $or: [
+ { tokenAccessReadOnly_refs: userId },
+ { tokenAccessReadAndWrite_refs: userId }
+ ]
+ },
+ {
+ _id: 1
+ },
+ function(err, project) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback(null, project != null)
+ }
+ )
+ },
+
+ transferProjects(from_user_id, to_user_id, callback) {
+ if (callback == null) {
+ callback = function(err, projects) {}
+ }
+ const MEMBER_KEYS = ['collaberator_refs', 'readOnly_refs']
+
+ // Find all the projects this user is part of so we can flush them to TPDS
+ let query = {
+ $or: [{ owner_ref: from_user_id }].concat(
+ MEMBER_KEYS.map(function(key) {
+ const q = {}
+ q[key] = from_user_id
+ return q
+ })
+ ) // [{ collaberator_refs: from_user_id }, ...]
+ }
+ return Project.find(query, { _id: 1 }, function(error, projects) {
+ if (projects == null) {
+ projects = []
+ }
+ if (error != null) {
+ return callback(error)
+ }
+
+ const project_ids = projects.map(p => p._id)
+ logger.log(
+ { project_ids, from_user_id, to_user_id },
+ 'transferring projects'
+ )
+
+ const update_jobs = []
+ update_jobs.push(cb =>
+ Project.update(
+ { owner_ref: from_user_id },
+ { $set: { owner_ref: to_user_id } },
+ { multi: true },
+ cb
+ )
+ )
+ for (let key of Array.from(MEMBER_KEYS)) {
+ ;(key =>
+ update_jobs.push(function(cb) {
+ query = {}
+ const addNewUserUpdate = { $addToSet: {} }
+ const removeOldUserUpdate = { $pull: {} }
+ query[key] = from_user_id
+ removeOldUserUpdate.$pull[key] = from_user_id
+ addNewUserUpdate.$addToSet[key] = to_user_id
+ // Mongo won't let us pull and addToSet in the same query, so do it in
+ // two. Note we need to add first, since the query is based on the old user.
+ return Project.update(
+ query,
+ addNewUserUpdate,
+ { multi: true },
+ function(error) {
+ if (error != null) {
+ return cb(error)
+ }
+ return Project.update(
+ query,
+ removeOldUserUpdate,
+ { multi: true },
+ cb
+ )
+ }
+ )
+ }))(key)
+ }
+
+ // Flush each project to TPDS to add files to new user's Dropbox
+ const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+ const flush_jobs = []
+ for (let project_id of Array.from(project_ids)) {
+ ;(project_id =>
+ flush_jobs.push(cb =>
+ ProjectEntityHandler.flushProjectToThirdPartyDataStore(
+ project_id,
+ cb
+ )
+ ))(project_id)
+ }
+
+ // Flush in background, no need to block on this
+ async.series(flush_jobs, function(error) {
+ if (error != null) {
+ return logger.err(
+ { err: error, project_ids, from_user_id, to_user_id },
+ 'error flushing tranferred projects to TPDS'
+ )
+ }
+ })
+
+ return async.series(update_jobs, function(err) {
+ logger.log('flushed transferred projects to TPDS')
+ return callback(err)
+ })
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js
new file mode 100644
index 0000000000..64d82b04d6
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js
@@ -0,0 +1,368 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CollaboratorsInviteController
+const ProjectGetter = require('../Project/ProjectGetter')
+const LimitationsManager = require('../Subscription/LimitationsManager')
+const UserGetter = require('../User/UserGetter')
+const CollaboratorsHandler = require('./CollaboratorsHandler')
+const CollaboratorsInviteHandler = require('./CollaboratorsInviteHandler')
+const logger = require('logger-sharelatex')
+const Settings = require('settings-sharelatex')
+const EmailHelper = require('../Helpers/EmailHelper')
+const EditorRealTimeController = require('../Editor/EditorRealTimeController')
+const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
+const AnalyticsManger = require('../Analytics/AnalyticsManager')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const rateLimiter = require('../../infrastructure/RateLimiter')
+const request = require('request')
+
+module.exports = CollaboratorsInviteController = {
+ getAllInvites(req, res, next) {
+ const projectId = req.params.Project_id
+ logger.log({ projectId }, 'getting all active invites for project')
+ return CollaboratorsInviteHandler.getAllInvites(projectId, function(
+ err,
+ invites
+ ) {
+ if (err != null) {
+ logger.err({ projectId }, 'error getting invites for project')
+ return next(err)
+ }
+ return res.json({ invites })
+ })
+ },
+
+ _checkShouldInviteEmail(email, callback) {
+ if (callback == null) {
+ callback = function(err, shouldAllowInvite) {}
+ }
+ if (Settings.restrictInvitesToExistingAccounts === true) {
+ logger.log({ email }, 'checking if user exists with this email')
+ return UserGetter.getUserByAnyEmail(email, { _id: 1 }, function(
+ err,
+ user
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ const userExists =
+ user != null && (user != null ? user._id : undefined) != null
+ return callback(null, userExists)
+ })
+ } else {
+ return callback(null, true)
+ }
+ },
+
+ _checkRateLimit(user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return LimitationsManager.allowedNumberOfCollaboratorsForUser(
+ user_id,
+ function(err, collabLimit) {
+ if (collabLimit == null) {
+ collabLimit = 1
+ }
+ if (err != null) {
+ return callback(err)
+ }
+ if (collabLimit === -1) {
+ collabLimit = 20
+ }
+ collabLimit = collabLimit * 10
+ const opts = {
+ endpointName: 'invite-to-project-by-user-id',
+ timeInterval: 60 * 30,
+ subjectName: user_id,
+ throttle: collabLimit
+ }
+ return rateLimiter.addCount(opts, callback)
+ }
+ )
+ },
+
+ inviteToProject(req, res, next) {
+ const projectId = req.params.Project_id
+ let { email } = req.body
+ const sendingUser = AuthenticationController.getSessionUser(req)
+ const sendingUserId = sendingUser._id
+ if (email === sendingUser.email) {
+ logger.log(
+ { projectId, email, sendingUserId },
+ 'cannot invite yourself to project'
+ )
+ return res.json({ invite: null, error: 'cannot_invite_self' })
+ }
+ logger.log({ projectId, email, sendingUserId }, 'inviting to project')
+ return LimitationsManager.canAddXCollaborators(
+ projectId,
+ 1,
+ (error, allowed) => {
+ let privileges
+ if (error != null) {
+ return next(error)
+ }
+ if (!allowed) {
+ logger.log(
+ { projectId, email, sendingUserId },
+ 'not allowed to invite more users to project'
+ )
+ return res.json({ invite: null })
+ }
+ ;({ email, privileges } = req.body)
+ email = EmailHelper.parseEmail(email)
+ if (email == null || email === '') {
+ logger.log(
+ { projectId, email, sendingUserId },
+ 'invalid email address'
+ )
+ return res.status(400).send({ errorReason: 'invalid_email' })
+ }
+ return CollaboratorsInviteController._checkRateLimit(
+ sendingUserId,
+ function(error, underRateLimit) {
+ if (error != null) {
+ return next(error)
+ }
+ if (!underRateLimit) {
+ return res.sendStatus(429)
+ }
+ return CollaboratorsInviteController._checkShouldInviteEmail(
+ email,
+ function(err, shouldAllowInvite) {
+ if (err != null) {
+ logger.err(
+ { err, email, projectId, sendingUserId },
+ 'error checking if we can invite this email address'
+ )
+ return next(err)
+ }
+ if (!shouldAllowInvite) {
+ logger.log(
+ { email, projectId, sendingUserId },
+ 'not allowed to send an invite to this email address'
+ )
+ return res.json({
+ invite: null,
+ error: 'cannot_invite_non_user'
+ })
+ }
+ return CollaboratorsInviteHandler.inviteToProject(
+ projectId,
+ sendingUser,
+ email,
+ privileges,
+ function(err, invite) {
+ if (err != null) {
+ logger.err(
+ { projectId, email, sendingUserId },
+ 'error creating project invite'
+ )
+ return next(err)
+ }
+ logger.log(
+ { projectId, email, sendingUserId },
+ 'invite created'
+ )
+ EditorRealTimeController.emitToRoom(
+ projectId,
+ 'project:membership:changed',
+ { invites: true }
+ )
+ return res.json({ invite })
+ }
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ },
+
+ revokeInvite(req, res, next) {
+ const projectId = req.params.Project_id
+ const inviteId = req.params.invite_id
+ logger.log({ projectId, inviteId }, 'revoking invite')
+ return CollaboratorsInviteHandler.revokeInvite(
+ projectId,
+ inviteId,
+ function(err) {
+ if (err != null) {
+ logger.err({ projectId, inviteId }, 'error revoking invite')
+ return next(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ projectId,
+ 'project:membership:changed',
+ { invites: true }
+ )
+ return res.sendStatus(201)
+ }
+ )
+ },
+
+ resendInvite(req, res, next) {
+ const projectId = req.params.Project_id
+ const inviteId = req.params.invite_id
+ logger.log({ projectId, inviteId }, 'resending invite')
+ const sendingUser = AuthenticationController.getSessionUser(req)
+ return CollaboratorsInviteController._checkRateLimit(
+ sendingUser._id,
+ function(error, underRateLimit) {
+ if (error != null) {
+ return next(error)
+ }
+ if (!underRateLimit) {
+ return res.sendStatus(429)
+ }
+ return CollaboratorsInviteHandler.resendInvite(
+ projectId,
+ sendingUser,
+ inviteId,
+ function(err) {
+ if (err != null) {
+ logger.err({ projectId, inviteId }, 'error resending invite')
+ return next(err)
+ }
+ return res.sendStatus(201)
+ }
+ )
+ }
+ )
+ },
+
+ viewInvite(req, res, next) {
+ const projectId = req.params.Project_id
+ const { token } = req.params
+ const _renderInvalidPage = function() {
+ logger.log(
+ { projectId, token },
+ 'invite not valid, rendering not-valid page'
+ )
+ return res.render('project/invite/not-valid', { title: 'Invalid Invite' })
+ }
+ // check if the user is already a member of the project
+ const currentUser = AuthenticationController.getSessionUser(req)
+ return CollaboratorsHandler.isUserInvitedMemberOfProject(
+ currentUser._id,
+ projectId,
+ function(err, isMember, _privilegeLevel) {
+ if (err != null) {
+ logger.err(
+ { err, projectId },
+ 'error checking if user is member of project'
+ )
+ return next(err)
+ }
+ if (isMember) {
+ logger.log(
+ { projectId, userId: currentUser._id },
+ 'user is already a member of this project, redirecting'
+ )
+ return res.redirect(`/project/${projectId}`)
+ }
+ // get the invite
+ return CollaboratorsInviteHandler.getInviteByToken(
+ projectId,
+ token,
+ function(err, invite) {
+ if (err != null) {
+ logger.err({ projectId, token }, 'error getting invite by token')
+ return next(err)
+ }
+ // check if invite is gone, or otherwise non-existent
+ if (invite == null) {
+ logger.log({ projectId, token }, 'no invite found for this token')
+ return _renderInvalidPage()
+ }
+ // check the user who sent the invite exists
+ return UserGetter.getUser(
+ { _id: invite.sendingUserId },
+ { email: 1, first_name: 1, last_name: 1 },
+ function(err, owner) {
+ if (err != null) {
+ logger.err({ err, projectId }, 'error getting project owner')
+ return next(err)
+ }
+ if (owner == null) {
+ logger.log({ projectId }, 'no project owner found')
+ return _renderInvalidPage()
+ }
+ // fetch the project name
+ return ProjectGetter.getProject(projectId, {}, function(
+ err,
+ project
+ ) {
+ if (err != null) {
+ logger.err({ err, projectId }, 'error getting project')
+ return next(err)
+ }
+ if (project == null) {
+ logger.log({ projectId }, 'no project found')
+ return _renderInvalidPage()
+ }
+ // finally render the invite
+ return res.render('project/invite/show', {
+ invite,
+ project,
+ owner,
+ title: 'Project Invite'
+ })
+ })
+ }
+ )
+ }
+ )
+ }
+ )
+ },
+
+ acceptInvite(req, res, next) {
+ const projectId = req.params.Project_id
+ const { token } = req.params
+ const currentUser = AuthenticationController.getSessionUser(req)
+ logger.log(
+ { projectId, userId: currentUser._id, token },
+ 'got request to accept invite'
+ )
+ return CollaboratorsInviteHandler.acceptInvite(
+ projectId,
+ token,
+ currentUser,
+ function(err) {
+ if (err != null) {
+ logger.err({ projectId, token }, 'error accepting invite by token')
+ return next(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ projectId,
+ 'project:membership:changed',
+ { invites: true, members: true }
+ )
+ AnalyticsManger.recordEvent(currentUser._id, 'project-invite-accept', {
+ projectId,
+ userId: currentUser._id
+ })
+ if (req.xhr) {
+ return res.sendStatus(204) // Done async via project page notification
+ } else {
+ return res.redirect(`/project/${projectId}`)
+ }
+ }
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteHandler.js b/services/web/app/src/Features/Collaborators/CollaboratorsInviteHandler.js
new file mode 100644
index 0000000000..5e8950f74c
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteHandler.js
@@ -0,0 +1,330 @@
+/* eslint-disable
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CollaboratorsInviteHandler
+const { ProjectInvite } = require('../../models/ProjectInvite')
+const logger = require('logger-sharelatex')
+const CollaboratorsEmailHandler = require('./CollaboratorsEmailHandler')
+const CollaboratorsHandler = require('./CollaboratorsHandler')
+const UserGetter = require('../User/UserGetter')
+const ProjectGetter = require('../Project/ProjectGetter')
+const Async = require('async')
+const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
+const Errors = require('../Errors/Errors')
+const Crypto = require('crypto')
+const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
+
+module.exports = CollaboratorsInviteHandler = {
+ getAllInvites(projectId, callback) {
+ if (callback == null) {
+ callback = function(err, invites) {}
+ }
+ logger.log({ projectId }, 'fetching invites for project')
+ return ProjectInvite.find({ projectId }, function(err, invites) {
+ if (err != null) {
+ logger.err({ err, projectId }, 'error getting invites from mongo')
+ return callback(err)
+ }
+ logger.log(
+ { projectId, count: invites.length },
+ 'found invites for project'
+ )
+ return callback(null, invites)
+ })
+ },
+
+ getInviteCount(projectId, callback) {
+ if (callback == null) {
+ callback = function(err, count) {}
+ }
+ logger.log({ projectId }, 'counting invites for project')
+ return ProjectInvite.count({ projectId }, function(err, count) {
+ if (err != null) {
+ logger.err({ err, projectId }, 'error getting invites from mongo')
+ return callback(err)
+ }
+ return callback(null, count)
+ })
+ },
+
+ _trySendInviteNotification(projectId, sendingUser, invite, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ const { email } = invite
+ return UserGetter.getUserByAnyEmail(email, { _id: 1 }, function(
+ err,
+ existingUser
+ ) {
+ if (err != null) {
+ logger.err({ projectId, email }, 'error checking if user exists')
+ return callback(err)
+ }
+ if (existingUser == null) {
+ logger.log({ projectId, email }, 'no existing user found, returning')
+ return callback(null)
+ }
+ return ProjectGetter.getProject(projectId, { _id: 1, name: 1 }, function(
+ err,
+ project
+ ) {
+ if (err != null) {
+ logger.err({ projectId, email }, 'error getting project')
+ return callback(err)
+ }
+ if (project == null) {
+ logger.log(
+ { projectId },
+ 'no project found while sending notification, returning'
+ )
+ return callback(null)
+ }
+ return NotificationsBuilder.projectInvite(
+ invite,
+ project,
+ sendingUser,
+ existingUser
+ ).create(callback)
+ })
+ })
+ },
+
+ _tryCancelInviteNotification(inviteId, callback) {
+ if (callback == null) {
+ callback = function() {}
+ }
+ return NotificationsBuilder.projectInvite(
+ { _id: inviteId },
+ null,
+ null,
+ null
+ ).read(callback)
+ },
+
+ _sendMessages(projectId, sendingUser, invite, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ logger.log(
+ { projectId, inviteId: invite._id },
+ 'sending notification and email for invite'
+ )
+ return CollaboratorsEmailHandler.notifyUserOfProjectInvite(
+ projectId,
+ invite.email,
+ invite,
+ sendingUser,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ return CollaboratorsInviteHandler._trySendInviteNotification(
+ projectId,
+ sendingUser,
+ invite,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback()
+ }
+ )
+ }
+ )
+ },
+
+ inviteToProject(projectId, sendingUser, email, privileges, callback) {
+ if (callback == null) {
+ callback = function(err, invite) {}
+ }
+ logger.log(
+ { projectId, sendingUserId: sendingUser._id, email, privileges },
+ 'adding invite'
+ )
+ return Crypto.randomBytes(24, function(err, buffer) {
+ if (err != null) {
+ logger.err(
+ { err, projectId, sendingUserId: sendingUser._id, email },
+ 'error generating random token'
+ )
+ return callback(err)
+ }
+ const token = buffer.toString('hex')
+ const invite = new ProjectInvite({
+ email,
+ token,
+ sendingUserId: sendingUser._id,
+ projectId,
+ privileges
+ })
+ return invite.save(function(err, invite) {
+ if (err != null) {
+ logger.err(
+ { err, projectId, sendingUserId: sendingUser._id, email },
+ 'error saving token'
+ )
+ return callback(err)
+ }
+ // Send email and notification in background
+ CollaboratorsInviteHandler._sendMessages(
+ projectId,
+ sendingUser,
+ invite,
+ function(err) {
+ if (err != null) {
+ return logger.err(
+ { err, projectId, email },
+ 'error sending messages for invite'
+ )
+ }
+ }
+ )
+ return callback(null, invite)
+ })
+ })
+ },
+
+ revokeInvite(projectId, inviteId, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ logger.log({ projectId, inviteId }, 'removing invite')
+ return ProjectInvite.remove({ projectId, _id: inviteId }, function(err) {
+ if (err != null) {
+ logger.err({ err, projectId, inviteId }, 'error removing invite')
+ return callback(err)
+ }
+ CollaboratorsInviteHandler._tryCancelInviteNotification(
+ inviteId,
+ function() {}
+ )
+ return callback(null)
+ })
+ },
+
+ resendInvite(projectId, sendingUser, inviteId, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ logger.log({ projectId, inviteId }, 'resending invite email')
+ return ProjectInvite.findOne({ _id: inviteId, projectId }, function(
+ err,
+ invite
+ ) {
+ if (err != null) {
+ logger.err({ err, projectId, inviteId }, 'error finding invite')
+ return callback(err)
+ }
+ if (invite == null) {
+ logger.err(
+ { err, projectId, inviteId },
+ 'no invite found, nothing to resend'
+ )
+ return callback(null)
+ }
+ return CollaboratorsInviteHandler._sendMessages(
+ projectId,
+ sendingUser,
+ invite,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { projectId, inviteId },
+ 'error resending invite messages'
+ )
+ return callback(err)
+ }
+ return callback(null)
+ }
+ )
+ })
+ },
+
+ getInviteByToken(projectId, tokenString, callback) {
+ if (callback == null) {
+ callback = function(err, invite) {}
+ }
+ logger.log({ projectId, tokenString }, 'fetching invite by token')
+ return ProjectInvite.findOne({ projectId, token: tokenString }, function(
+ err,
+ invite
+ ) {
+ if (err != null) {
+ logger.err({ err, projectId }, 'error fetching invite')
+ return callback(err)
+ }
+ if (invite == null) {
+ logger.err({ err, projectId, token: tokenString }, 'no invite found')
+ return callback(null, null)
+ }
+ return callback(null, invite)
+ })
+ },
+
+ acceptInvite(projectId, tokenString, user, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ logger.log({ projectId, userId: user._id, tokenString }, 'accepting invite')
+ return CollaboratorsInviteHandler.getInviteByToken(
+ projectId,
+ tokenString,
+ function(err, invite) {
+ if (err != null) {
+ logger.err({ err, projectId, tokenString }, 'error finding invite')
+ return callback(err)
+ }
+ if (!invite) {
+ err = new Errors.NotFoundError('no matching invite found')
+ logger.log(
+ { err, projectId, tokenString },
+ 'no matching invite found'
+ )
+ return callback(err)
+ }
+ const inviteId = invite._id
+ return CollaboratorsHandler.addUserIdToProject(
+ projectId,
+ invite.sendingUserId,
+ user._id,
+ invite.privileges,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { err, projectId, inviteId, userId: user._id },
+ 'error adding user to project'
+ )
+ return callback(err)
+ }
+ // Remove invite
+ logger.log({ projectId, inviteId }, 'removing invite')
+ return ProjectInvite.remove({ _id: inviteId }, function(err) {
+ if (err != null) {
+ logger.err(
+ { err, projectId, inviteId },
+ 'error removing invite'
+ )
+ return callback(err)
+ }
+ CollaboratorsInviteHandler._tryCancelInviteNotification(
+ inviteId,
+ function() {}
+ )
+ return callback()
+ })
+ }
+ )
+ }
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsRouter.js b/services/web/app/src/Features/Collaborators/CollaboratorsRouter.js
new file mode 100644
index 0000000000..6b9889646d
--- /dev/null
+++ b/services/web/app/src/Features/Collaborators/CollaboratorsRouter.js
@@ -0,0 +1,99 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const CollaboratorsController = require('./CollaboratorsController')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
+const CollaboratorsInviteController = require('./CollaboratorsInviteController')
+const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
+const CaptchaMiddleware = require('../Captcha/CaptchaMiddleware')
+
+module.exports = {
+ apply(webRouter, apiRouter) {
+ webRouter.post(
+ '/project/:Project_id/leave',
+ AuthenticationController.requireLogin(),
+ CollaboratorsController.removeSelfFromProject
+ )
+
+ webRouter.delete(
+ '/project/:Project_id/users/:user_id',
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsController.removeUserFromProject
+ )
+
+ webRouter.get(
+ '/project/:Project_id/members',
+ AuthenticationController.requireLogin(),
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsController.getAllMembers
+ )
+
+ // invites
+ webRouter.post(
+ '/project/:Project_id/invite',
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'invite-to-project-by-project-id',
+ params: ['Project_id'],
+ maxRequests: 100,
+ timeInterval: 60 * 10
+ }),
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'invite-to-project-by-ip',
+ ipOnly: true,
+ maxRequests: 100,
+ timeInterval: 60 * 10
+ }),
+ CaptchaMiddleware.validateCaptcha('invite'),
+ AuthenticationController.requireLogin(),
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsInviteController.inviteToProject
+ )
+
+ webRouter.get(
+ '/project/:Project_id/invites',
+ AuthenticationController.requireLogin(),
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsInviteController.getAllInvites
+ )
+
+ webRouter.delete(
+ '/project/:Project_id/invite/:invite_id',
+ AuthenticationController.requireLogin(),
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsInviteController.revokeInvite
+ )
+
+ webRouter.post(
+ '/project/:Project_id/invite/:invite_id/resend',
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'resend-invite',
+ params: ['Project_id'],
+ maxRequests: 200,
+ timeInterval: 60 * 10
+ }),
+ AuthenticationController.requireLogin(),
+ AuthorizationMiddleware.ensureUserCanAdminProject,
+ CollaboratorsInviteController.resendInvite
+ )
+
+ webRouter.get(
+ '/project/:Project_id/invite/token/:token',
+ AuthenticationController.requireLogin(),
+ CollaboratorsInviteController.viewInvite
+ )
+
+ return webRouter.post(
+ '/project/:Project_id/invite/token/:token/accept',
+ AuthenticationController.requireLogin(),
+ CollaboratorsInviteController.acceptInvite
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Compile/ClsiCookieManager.js b/services/web/app/src/Features/Compile/ClsiCookieManager.js
new file mode 100644
index 0000000000..ad120afcc2
--- /dev/null
+++ b/services/web/app/src/Features/Compile/ClsiCookieManager.js
@@ -0,0 +1,154 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let rclient_secondary
+const Settings = require('settings-sharelatex')
+const request = require('request')
+const RedisWrapper = require('../../infrastructure/RedisWrapper')
+const rclient = RedisWrapper.client('clsi_cookie')
+if (Settings.redis.clsi_cookie_secondary != null) {
+ rclient_secondary = RedisWrapper.client('clsi_cookie_secondary')
+}
+const Cookie = require('cookie')
+const logger = require('logger-sharelatex')
+
+const clsiCookiesEnabled =
+ (Settings.clsiCookie != null ? Settings.clsiCookie.key : undefined) != null &&
+ Settings.clsiCookie.key.length !== 0
+
+module.exports = function(backendGroup) {
+ return {
+ buildKey(project_id) {
+ if (backendGroup != null) {
+ return `clsiserver:${backendGroup}:${project_id}`
+ } else {
+ return `clsiserver:${project_id}`
+ }
+ },
+
+ _getServerId(project_id, callback) {
+ if (callback == null) {
+ callback = function(err, serverId) {}
+ }
+ return rclient.get(this.buildKey(project_id), (err, serverId) => {
+ if (err != null) {
+ return callback(err)
+ }
+ if (serverId == null || serverId === '') {
+ return this._populateServerIdViaRequest(project_id, callback)
+ } else {
+ return callback(null, serverId)
+ }
+ })
+ },
+
+ _populateServerIdViaRequest(project_id, callback) {
+ if (callback == null) {
+ callback = function(err, serverId) {}
+ }
+ const url = `${Settings.apis.clsi.url}/project/${project_id}/status`
+ return request.get(url, (err, res, body) => {
+ if (err != null) {
+ logger.err(
+ { err, project_id },
+ 'error getting initial server id for project'
+ )
+ return callback(err)
+ }
+ return this.setServerId(project_id, res, function(err, serverId) {
+ if (err != null) {
+ logger.err(
+ { err, project_id },
+ 'error setting server id via populate request'
+ )
+ }
+ return callback(err, serverId)
+ })
+ })
+ },
+
+ _parseServerIdFromResponse(response) {
+ const cookies = Cookie.parse(
+ (response.headers['set-cookie'] != null
+ ? response.headers['set-cookie'][0]
+ : undefined) || ''
+ )
+ return cookies != null ? cookies[Settings.clsiCookie.key] : undefined
+ },
+
+ setServerId(project_id, response, callback) {
+ if (callback == null) {
+ callback = function(err, serverId) {}
+ }
+ if (!clsiCookiesEnabled) {
+ return callback()
+ }
+ const serverId = this._parseServerIdFromResponse(response)
+ if (serverId == null) {
+ // We don't get a cookie back if it hasn't changed
+ return rclient.expire(
+ this.buildKey(project_id),
+ Settings.clsiCookie.ttl,
+ callback
+ )
+ }
+ if (rclient_secondary != null) {
+ this._setServerIdInRedis(rclient_secondary, project_id, serverId)
+ }
+ return this._setServerIdInRedis(rclient, project_id, serverId, err =>
+ callback(err, serverId)
+ )
+ },
+
+ _setServerIdInRedis(rclient, project_id, serverId, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ const multi = rclient.multi()
+ multi.set(this.buildKey(project_id), serverId)
+ multi.expire(this.buildKey(project_id), Settings.clsiCookie.ttl)
+ return multi.exec(callback)
+ },
+
+ clearServerId(project_id, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ if (!clsiCookiesEnabled) {
+ return callback()
+ }
+ return rclient.del(this.buildKey(project_id), callback)
+ },
+
+ getCookieJar(project_id, callback) {
+ if (callback == null) {
+ callback = function(err, jar) {}
+ }
+ if (!clsiCookiesEnabled) {
+ return callback(null, request.jar())
+ }
+ return this._getServerId(project_id, (err, serverId) => {
+ if (err != null) {
+ logger.err({ err, project_id }, 'error getting server id')
+ return callback(err)
+ }
+ const serverCookie = request.cookie(
+ `${Settings.clsiCookie.key}=${serverId}`
+ )
+ const jar = request.jar()
+ jar.setCookie(serverCookie, Settings.apis.clsi.url)
+ return callback(null, jar)
+ })
+ }
+ }
+}
diff --git a/services/web/app/src/Features/Compile/ClsiFormatChecker.js b/services/web/app/src/Features/Compile/ClsiFormatChecker.js
new file mode 100644
index 0000000000..dacded23c9
--- /dev/null
+++ b/services/web/app/src/Features/Compile/ClsiFormatChecker.js
@@ -0,0 +1,88 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ClsiFormatChecker
+const _ = require('lodash')
+const async = require('async')
+const settings = require('settings-sharelatex')
+
+module.exports = ClsiFormatChecker = {
+ checkRecoursesForProblems(resources, callback) {
+ const jobs = {
+ conflictedPaths(cb) {
+ return ClsiFormatChecker._checkForConflictingPaths(resources, cb)
+ },
+
+ sizeCheck(cb) {
+ return ClsiFormatChecker._checkDocsAreUnderSizeLimit(resources, cb)
+ }
+ }
+
+ return async.series(jobs, function(err, problems) {
+ if (err != null) {
+ return callback(err)
+ }
+
+ problems = _.omitBy(problems, _.isEmpty)
+
+ if (_.isEmpty(problems)) {
+ return callback()
+ } else {
+ return callback(null, problems)
+ }
+ })
+ },
+
+ _checkForConflictingPaths(resources, callback) {
+ const paths = _.map(resources, 'path')
+
+ const conflicts = _.filter(paths, function(path) {
+ const matchingPaths = _.filter(
+ paths,
+ checkPath => checkPath.indexOf(path + '/') !== -1
+ )
+
+ return matchingPaths.length > 0
+ })
+
+ const conflictObjects = _.map(conflicts, conflict => ({ path: conflict }))
+
+ return callback(null, conflictObjects)
+ },
+
+ _checkDocsAreUnderSizeLimit(resources, callback) {
+ const sizeLimit = 1000 * 1000 * settings.compileBodySizeLimitMb
+
+ let totalSize = 0
+
+ let sizedResources = _.map(resources, function(resource) {
+ const result = { path: resource.path }
+ if (resource.content != null) {
+ result.size = resource.content.replace(/\n/g).length
+ result.kbSize = Math.ceil(result.size / 1000)
+ } else {
+ result.size = 0
+ }
+ totalSize += result.size
+ return result
+ })
+
+ const tooLarge = totalSize > sizeLimit
+ if (!tooLarge) {
+ return callback()
+ } else {
+ sizedResources = _.sortBy(sizedResources, 'size')
+ .reverse()
+ .slice(0, 10)
+ return callback(null, { resources: sizedResources, totalSize })
+ }
+ }
+}
diff --git a/services/web/app/src/Features/Compile/ClsiManager.js b/services/web/app/src/Features/Compile/ClsiManager.js
new file mode 100644
index 0000000000..0aea76bc4e
--- /dev/null
+++ b/services/web/app/src/Features/Compile/ClsiManager.js
@@ -0,0 +1,922 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ClsiManager
+const Path = require('path')
+let async = require('async')
+const Settings = require('settings-sharelatex')
+const request = require('request')
+const { Project } = require('../../models/Project')
+const ProjectGetter = require('../Project/ProjectGetter')
+const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+const logger = require('logger-sharelatex')
+const Url = require('url')
+const ClsiCookieManager = require('./ClsiCookieManager')(
+ Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
+)
+const NewBackendCloudClsiCookieManager = require('./ClsiCookieManager')(
+ Settings.apis.clsi_new != null
+ ? Settings.apis.clsi_new.backendGroupName
+ : undefined
+)
+const ClsiStateManager = require('./ClsiStateManager')
+const _ = require('underscore')
+async = require('async')
+const ClsiFormatChecker = require('./ClsiFormatChecker')
+const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
+const Metrics = require('metrics-sharelatex')
+const Errors = require('../Errors/Errors')
+
+module.exports = ClsiManager = {
+ sendRequest(project_id, user_id, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ return ClsiManager.sendRequestOnce(project_id, user_id, options, function(
+ error,
+ status,
+ ...result
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (status === 'conflict') {
+ options = _.clone(options)
+ options.syncType = 'full' // force full compile
+ return ClsiManager.sendRequestOnce(
+ project_id,
+ user_id,
+ options,
+ callback
+ ) // try again
+ } else {
+ return callback(error, status, ...Array.from(result))
+ }
+ })
+ },
+
+ sendRequestOnce(project_id, user_id, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (callback == null) {
+ callback = function(
+ error,
+ status,
+ outputFiles,
+ clsiServerId,
+ validationProblems
+ ) {}
+ }
+ return ClsiManager._buildRequest(project_id, options, function(error, req) {
+ if (error != null) {
+ if (error.message === 'no main file specified') {
+ return callback(null, 'validation-problems', null, null, {
+ mainFile: error.message
+ })
+ } else {
+ return callback(error)
+ }
+ }
+ logger.log({ project_id }, 'sending compile to CLSI')
+ return ClsiManager._sendBuiltRequest(
+ project_id,
+ user_id,
+ req,
+ options,
+ function(error, status, ...result) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(error, status, ...Array.from(result))
+ }
+ )
+ })
+ },
+
+ // for public API requests where there is no project id
+ sendExternalRequest(submission_id, clsi_request, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (callback == null) {
+ callback = function(
+ error,
+ status,
+ outputFiles,
+ clsiServerId,
+ validationProblems
+ ) {}
+ }
+ logger.log(
+ { submission_id },
+ 'sending external compile to CLSI',
+ clsi_request
+ )
+ return ClsiManager._sendBuiltRequest(
+ submission_id,
+ null,
+ clsi_request,
+ options,
+ function(error, status, ...result) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(error, status, ...Array.from(result))
+ }
+ )
+ },
+
+ stopCompile(project_id, user_id, options, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const compilerUrl = this._getCompilerUrl(
+ options != null ? options.compileGroup : undefined,
+ project_id,
+ user_id,
+ 'compile/stop'
+ )
+ const opts = {
+ url: compilerUrl,
+ method: 'POST'
+ }
+ return ClsiManager._makeRequest(project_id, opts, callback)
+ },
+
+ deleteAuxFiles(project_id, user_id, options, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const compilerUrl = this._getCompilerUrl(
+ options != null ? options.compileGroup : undefined,
+ project_id,
+ user_id
+ )
+ const opts = {
+ url: compilerUrl,
+ method: 'DELETE'
+ }
+ return ClsiManager._makeRequest(project_id, opts, clsiError =>
+ // always clear the project state from the docupdater, even if there
+ // was a problem with the request to the clsi
+ DocumentUpdaterHandler.clearProjectState(project_id, function(
+ docUpdaterError
+ ) {
+ const error = clsiError || docUpdaterError
+ if (error != null) {
+ return callback(error)
+ }
+ return callback()
+ })
+ )
+ },
+
+ _sendBuiltRequest(project_id, user_id, req, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (callback == null) {
+ callback = function(
+ error,
+ status,
+ outputFiles,
+ clsiServerId,
+ validationProblems
+ ) {}
+ }
+ return ClsiFormatChecker.checkRecoursesForProblems(
+ req.compile != null ? req.compile.resources : undefined,
+ function(err, validationProblems) {
+ if (err != null) {
+ logger.err(
+ err,
+ project_id,
+ 'could not check resources for potential problems before sending to clsi'
+ )
+ return callback(err)
+ }
+ if (validationProblems != null) {
+ logger.log(
+ { project_id, validationProblems },
+ 'problems with users latex before compile was attempted'
+ )
+ return callback(
+ null,
+ 'validation-problems',
+ null,
+ null,
+ validationProblems
+ )
+ }
+ return ClsiManager._postToClsi(
+ project_id,
+ user_id,
+ req,
+ options.compileGroup,
+ function(error, response) {
+ if (error != null) {
+ logger.err(
+ { err: error, project_id },
+ 'error sending request to clsi'
+ )
+ return callback(error)
+ }
+ logger.log(
+ {
+ project_id,
+ outputFilesLength: __guard__(
+ response != null ? response.outputFiles : undefined,
+ x => x.length
+ ),
+ status: response != null ? response.status : undefined,
+ compile_status: __guard__(
+ response != null ? response.compile : undefined,
+ x1 => x1.status
+ )
+ },
+ 'received compile response from CLSI'
+ )
+ return ClsiCookieManager._getServerId(project_id, function(
+ err,
+ clsiServerId
+ ) {
+ if (err != null) {
+ logger.err({ err, project_id }, 'error getting server id')
+ return callback(err)
+ }
+ const outputFiles = ClsiManager._parseOutputFiles(
+ project_id,
+ __guard__(
+ response != null ? response.compile : undefined,
+ x2 => x2.outputFiles
+ )
+ )
+ return callback(
+ null,
+ __guard__(
+ response != null ? response.compile : undefined,
+ x3 => x3.status
+ ),
+ outputFiles,
+ clsiServerId
+ )
+ })
+ }
+ )
+ }
+ )
+ },
+
+ _makeRequest(project_id, opts, callback) {
+ return async.series(
+ {
+ currentBackend(cb) {
+ const startTime = new Date()
+ return ClsiCookieManager.getCookieJar(project_id, function(err, jar) {
+ if (err != null) {
+ logger.err({ err }, 'error getting cookie jar for clsi request')
+ return callback(err)
+ }
+ opts.jar = jar
+ const timer = new Metrics.Timer('compile.currentBackend')
+ return request(opts, function(err, response, body) {
+ timer.done()
+ Metrics.inc(
+ `compile.currentBackend.response.${
+ response != null ? response.statusCode : undefined
+ }`
+ )
+ if (err != null) {
+ logger.err(
+ { err, project_id, url: opts != null ? opts.url : undefined },
+ 'error making request to clsi'
+ )
+ return callback(err)
+ }
+ return ClsiCookieManager.setServerId(
+ project_id,
+ response,
+ function(err) {
+ if (err != null) {
+ logger.warn({ err, project_id }, 'error setting server id')
+ }
+ callback(err, response, body) // return as soon as the standard compile has returned
+ return cb(err, {
+ response,
+ body,
+ finishTime: new Date() - startTime
+ })
+ }
+ )
+ })
+ })
+ },
+ newBackend(cb) {
+ const startTime = new Date()
+ return ClsiManager._makeNewBackendRequest(project_id, opts, function(
+ err,
+ response,
+ body
+ ) {
+ Metrics.inc(
+ `compile.newBackend.response.${
+ response != null ? response.statusCode : undefined
+ }`
+ )
+ return cb(err, {
+ response,
+ body,
+ finishTime: new Date() - startTime
+ })
+ })
+ }
+ },
+ function(err, results) {
+ const timeDifference =
+ (results.newBackend != null
+ ? results.newBackend.finishTime
+ : undefined) -
+ (results.currentBackend != null
+ ? results.currentBackend.finishTime
+ : undefined)
+ const statusCodeSame =
+ __guard__(
+ results.newBackend != null
+ ? results.newBackend.response
+ : undefined,
+ x => x.statusCode
+ ) ===
+ __guard__(
+ results.currentBackend != null
+ ? results.currentBackend.response
+ : undefined,
+ x1 => x1.statusCode
+ )
+ const currentCompileTime =
+ results.currentBackend != null
+ ? results.currentBackend.finishTime
+ : undefined
+ const newBackendCompileTime =
+ results.newBackend != null ? results.newBackend.finishTime : undefined
+ return logger.log(
+ {
+ statusCodeSame,
+ timeDifference,
+ currentCompileTime,
+ newBackendCompileTime,
+ project_id
+ },
+ 'both clsi requests returned'
+ )
+ }
+ )
+ },
+
+ _makeNewBackendRequest(project_id, baseOpts, callback) {
+ if (
+ (Settings.apis.clsi_new != null
+ ? Settings.apis.clsi_new.url
+ : undefined) == null
+ ) {
+ return callback()
+ }
+ const opts = _.clone(baseOpts)
+ opts.url = opts.url.replace(
+ Settings.apis.clsi.url,
+ Settings.apis.clsi_new != null ? Settings.apis.clsi_new.url : undefined
+ )
+ return NewBackendCloudClsiCookieManager.getCookieJar(project_id, function(
+ err,
+ jar
+ ) {
+ if (err != null) {
+ logger.err({ err }, 'error getting cookie jar for clsi request')
+ return callback(err)
+ }
+ opts.jar = jar
+ const timer = new Metrics.Timer('compile.newBackend')
+ return request(opts, function(err, response, body) {
+ timer.done()
+ if (err != null) {
+ logger.warn(
+ { err, project_id, url: opts != null ? opts.url : undefined },
+ 'error making request to new clsi'
+ )
+ return callback(err)
+ }
+ return NewBackendCloudClsiCookieManager.setServerId(
+ project_id,
+ response,
+ function(err) {
+ if (err != null) {
+ logger.warn(
+ { err, project_id },
+ 'error setting server id new backend'
+ )
+ }
+ return callback(err, response, body)
+ }
+ )
+ })
+ })
+ },
+
+ _getCompilerUrl(compileGroup, project_id, user_id, action) {
+ const host = Settings.apis.clsi.url
+ let path = `/project/${project_id}`
+ if (user_id != null) {
+ path += `/user/${user_id}`
+ }
+ if (action != null) {
+ path += `/${action}`
+ }
+ return `${host}${path}`
+ },
+
+ _postToClsi(project_id, user_id, req, compileGroup, callback) {
+ if (callback == null) {
+ callback = function(error, response) {}
+ }
+ const compileUrl = this._getCompilerUrl(
+ compileGroup,
+ project_id,
+ user_id,
+ 'compile'
+ )
+ const opts = {
+ url: compileUrl,
+ json: req,
+ method: 'POST'
+ }
+ return ClsiManager._makeRequest(project_id, opts, function(
+ error,
+ response,
+ body
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ return callback(null, body)
+ } else if (response.statusCode === 413) {
+ return callback(null, { compile: { status: 'project-too-large' } })
+ } else if (response.statusCode === 409) {
+ return callback(null, { compile: { status: 'conflict' } })
+ } else if (response.statusCode === 423) {
+ return callback(null, { compile: { status: 'compile-in-progress' } })
+ } else {
+ error = new Error(
+ `CLSI returned non-success code: ${response.statusCode}`
+ )
+ logger.error({ err: error, project_id }, 'CLSI returned failure code')
+ return callback(error, body)
+ }
+ })
+ },
+
+ _parseOutputFiles(project_id, rawOutputFiles) {
+ if (rawOutputFiles == null) {
+ rawOutputFiles = []
+ }
+ const outputFiles = []
+ for (let file of Array.from(rawOutputFiles)) {
+ outputFiles.push({
+ path: file.path, // the clsi is now sending this to web
+ url: Url.parse(file.url).path, // the location of the file on the clsi, excluding the host part
+ type: file.type,
+ build: file.build
+ })
+ }
+ return outputFiles
+ },
+
+ VALID_COMPILERS: ['pdflatex', 'latex', 'xelatex', 'lualatex'],
+
+ _buildRequest(project_id, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (callback == null) {
+ callback = function(error, request) {}
+ }
+ return ProjectGetter.getProject(
+ project_id,
+ { compiler: 1, rootDoc_id: 1, imageName: 1, rootFolder: 1 },
+ function(error, project) {
+ let timer
+ if (error != null) {
+ return callback(error)
+ }
+ if (project == null) {
+ return callback(
+ new Errors.NotFoundError(`project does not exist: ${project_id}`)
+ )
+ }
+ if (
+ !Array.from(ClsiManager.VALID_COMPILERS).includes(project.compiler)
+ ) {
+ project.compiler = 'pdflatex'
+ }
+
+ if (options.incrementalCompilesEnabled || options.syncType != null) {
+ // new way, either incremental or full
+ timer = new Metrics.Timer('editor.compile-getdocs-redis')
+ return ClsiManager.getContentFromDocUpdaterIfMatch(
+ project_id,
+ project,
+ options,
+ function(error, projectStateHash, docUpdaterDocs) {
+ timer.done()
+ if (error != null) {
+ logger.error(
+ { err: error, project_id },
+ 'error checking project state'
+ )
+ // note: we don't bail out when there's an error getting
+ // incremental files from the docupdater, we just fall back
+ // to a normal compile below
+ } else {
+ logger.log(
+ {
+ project_id,
+ projectStateHash,
+ docs: docUpdaterDocs != null
+ },
+ 'checked project state'
+ )
+ }
+ // see if we can send an incremental update to the CLSI
+ if (
+ docUpdaterDocs != null &&
+ options.syncType !== 'full' &&
+ error == null
+ ) {
+ Metrics.inc('compile-from-redis')
+ return ClsiManager._buildRequestFromDocupdater(
+ project_id,
+ options,
+ project,
+ projectStateHash,
+ docUpdaterDocs,
+ callback
+ )
+ } else {
+ Metrics.inc('compile-from-mongo')
+ return ClsiManager._buildRequestFromMongo(
+ project_id,
+ options,
+ project,
+ projectStateHash,
+ callback
+ )
+ }
+ }
+ )
+ } else {
+ // old way, always from mongo
+ timer = new Metrics.Timer('editor.compile-getdocs-mongo')
+ return ClsiManager._getContentFromMongo(project_id, function(
+ error,
+ docs,
+ files
+ ) {
+ timer.done()
+ if (error != null) {
+ return callback(error)
+ }
+ return ClsiManager._finaliseRequest(
+ project_id,
+ options,
+ project,
+ docs,
+ files,
+ callback
+ )
+ })
+ }
+ }
+ )
+ },
+
+ getContentFromDocUpdaterIfMatch(project_id, project, options, callback) {
+ if (callback == null) {
+ callback = function(error, projectStateHash, docs) {}
+ }
+ return ClsiStateManager.computeHash(project, options, function(
+ error,
+ projectStateHash
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return DocumentUpdaterHandler.getProjectDocsIfMatch(
+ project_id,
+ projectStateHash,
+ function(error, docs) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, projectStateHash, docs)
+ }
+ )
+ })
+ },
+
+ getOutputFileStream(
+ project_id,
+ user_id,
+ build_id,
+ output_file_path,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(err, readStream) {}
+ }
+ const url = `${
+ Settings.apis.clsi.url
+ }/project/${project_id}/user/${user_id}/build/${build_id}/output/${output_file_path}`
+ return ClsiCookieManager.getCookieJar(project_id, function(err, jar) {
+ if (err != null) {
+ return callback(err)
+ }
+ const options = { url, method: 'GET', timeout: 60 * 1000, jar }
+ const readStream = request(options)
+ return callback(null, readStream)
+ })
+ },
+
+ _buildRequestFromDocupdater(
+ project_id,
+ options,
+ project,
+ projectStateHash,
+ docUpdaterDocs,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error, request) {}
+ }
+ return ProjectEntityHandler.getAllDocPathsFromProject(project, function(
+ error,
+ docPath
+ ) {
+ let path
+ if (error != null) {
+ return callback(error)
+ }
+ const docs = {}
+ for (let doc of Array.from(docUpdaterDocs || [])) {
+ path = docPath[doc._id]
+ docs[path] = doc
+ }
+ // send new docs but not files as those are already on the clsi
+ options = _.clone(options)
+ options.syncType = 'incremental'
+ options.syncState = projectStateHash
+ // create stub doc entries for any possible root docs, if not
+ // present in the docupdater. This allows finaliseRequest to
+ // identify the root doc.
+ const possibleRootDocIds = [options.rootDoc_id, project.rootDoc_id]
+ for (let rootDoc_id of Array.from(possibleRootDocIds)) {
+ if (rootDoc_id != null && rootDoc_id in docPath) {
+ path = docPath[rootDoc_id]
+ if (docs[path] == null) {
+ docs[path] = { _id: rootDoc_id, path }
+ }
+ }
+ }
+ return ClsiManager._finaliseRequest(
+ project_id,
+ options,
+ project,
+ docs,
+ [],
+ callback
+ )
+ })
+ },
+
+ _buildRequestFromMongo(
+ project_id,
+ options,
+ project,
+ projectStateHash,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error, request) {}
+ }
+ return ClsiManager._getContentFromMongo(project_id, function(
+ error,
+ docs,
+ files
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ options = _.clone(options)
+ options.syncType = 'full'
+ options.syncState = projectStateHash
+ return ClsiManager._finaliseRequest(
+ project_id,
+ options,
+ project,
+ docs,
+ files,
+ callback
+ )
+ })
+ },
+
+ _getContentFromMongo(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, docs, files) {}
+ }
+ return DocumentUpdaterHandler.flushProjectToMongo(project_id, function(
+ error
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return ProjectEntityHandler.getAllDocs(project_id, function(error, docs) {
+ if (docs == null) {
+ docs = {}
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ return ProjectEntityHandler.getAllFiles(project_id, function(
+ error,
+ files
+ ) {
+ if (files == null) {
+ files = {}
+ }
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, docs, files)
+ })
+ })
+ })
+ },
+
+ _finaliseRequest(project_id, options, project, docs, files, callback) {
+ let doc, path
+ if (callback == null) {
+ callback = function(error, params) {}
+ }
+ const resources = []
+ let rootResourcePath = null
+ let rootResourcePathOverride = null
+ let hasMainFile = false
+ let numberOfDocsInProject = 0
+
+ for (path in docs) {
+ doc = docs[path]
+ path = path.replace(/^\//, '') // Remove leading /
+ numberOfDocsInProject++
+ if (doc.lines != null) {
+ // add doc to resources unless it is just a stub entry
+ resources.push({
+ path,
+ content: doc.lines.join('\n')
+ })
+ }
+ if (
+ project.rootDoc_id != null &&
+ doc._id.toString() === project.rootDoc_id.toString()
+ ) {
+ rootResourcePath = path
+ }
+ if (
+ options.rootDoc_id != null &&
+ doc._id.toString() === options.rootDoc_id.toString()
+ ) {
+ rootResourcePathOverride = path
+ }
+ if (path === 'main.tex') {
+ hasMainFile = true
+ }
+ }
+
+ if (rootResourcePathOverride != null) {
+ rootResourcePath = rootResourcePathOverride
+ }
+ if (rootResourcePath == null) {
+ if (hasMainFile) {
+ logger.warn(
+ { project_id },
+ 'no root document found, setting to main.tex'
+ )
+ rootResourcePath = 'main.tex'
+ } else if (numberOfDocsInProject === 1) {
+ // only one file, must be the main document
+ for (path in docs) {
+ doc = docs[path]
+ rootResourcePath = path.replace(/^\//, '')
+ } // Remove leading /
+ logger.warn(
+ { project_id, rootResourcePath },
+ 'no root document found, single document in project'
+ )
+ } else {
+ return callback(new Error('no main file specified'))
+ }
+ }
+
+ for (path in files) {
+ const file = files[path]
+ path = path.replace(/^\//, '') // Remove leading /
+ resources.push({
+ path,
+ url: `${Settings.apis.filestore.url}/project/${project._id}/file/${
+ file._id
+ }`,
+ modified: file.created != null ? file.created.getTime() : undefined
+ })
+ }
+
+ return callback(null, {
+ compile: {
+ options: {
+ compiler: project.compiler,
+ timeout: options.timeout,
+ imageName: project.imageName,
+ draft: !!options.draft,
+ check: options.check,
+ syncType: options.syncType,
+ syncState: options.syncState
+ },
+ rootResourcePath,
+ resources
+ }
+ })
+ },
+
+ wordCount(project_id, user_id, file, options, callback) {
+ if (callback == null) {
+ callback = function(error, response) {}
+ }
+ return ClsiManager._buildRequest(project_id, options, function(error, req) {
+ const filename =
+ file ||
+ __guard__(
+ req != null ? req.compile : undefined,
+ x => x.rootResourcePath
+ )
+ const wordcount_url = ClsiManager._getCompilerUrl(
+ options != null ? options.compileGroup : undefined,
+ project_id,
+ user_id,
+ 'wordcount'
+ )
+ const opts = {
+ url: wordcount_url,
+ qs: {
+ file: filename,
+ image: req.compile.options.imageName
+ },
+ method: 'GET'
+ }
+ return ClsiManager._makeRequest(project_id, opts, function(
+ error,
+ response,
+ body
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ return callback(null, body)
+ } else {
+ error = new Error(
+ `CLSI returned non-success code: ${response.statusCode}`
+ )
+ logger.error({ err: error, project_id }, 'CLSI returned failure code')
+ return callback(error, body)
+ }
+ })
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Compile/ClsiStateManager.js b/services/web/app/src/Features/Compile/ClsiStateManager.js
new file mode 100644
index 0000000000..d65bc9a73e
--- /dev/null
+++ b/services/web/app/src/Features/Compile/ClsiStateManager.js
@@ -0,0 +1,83 @@
+/* eslint-disable
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS205: Consider reworking code to avoid use of IIFEs
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ClsiStateManager
+const Settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+const crypto = require('crypto')
+const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+
+// The "state" of a project is a hash of the relevant attributes in the
+// project object in this case we only need the rootFolder.
+//
+// The idea is that it will change if any doc or file is
+// created/renamed/deleted, and also if the content of any file (not
+// doc) changes.
+//
+// When the hash changes the full set of files on the CLSI will need to
+// be updated. If it doesn't change then we can overwrite changed docs
+// in place on the clsi, getting them from the docupdater.
+//
+// The docupdater is responsible for setting the key in redis, and
+// unsetting it if it removes any documents from the doc updater.
+
+const buildState = s =>
+ crypto
+ .createHash('sha1')
+ .update(s, 'utf8')
+ .digest('hex')
+
+module.exports = ClsiStateManager = {
+ computeHash(project, options, callback) {
+ if (callback == null) {
+ callback = function(err, hash) {}
+ }
+ return ProjectEntityHandler.getAllEntitiesFromProject(project, function(
+ err,
+ docs,
+ files
+ ) {
+ const fileList = Array.from(files || []).map(
+ f => `${f.file._id}:${f.file.rev}:${f.file.created}:${f.path}`
+ )
+ const docList = Array.from(docs || []).map(d => `${d.doc._id}:${d.path}`)
+ const sortedEntityList = [
+ ...Array.from(docList),
+ ...Array.from(fileList)
+ ].sort()
+ // ignore the isAutoCompile options as it doesn't affect the
+ // output, but include all other options e.g. draft
+ const optionsList = (() => {
+ const result = []
+ const object = options || {}
+ for (let key in object) {
+ const value = object[key]
+ if (!['isAutoCompile'].includes(key)) {
+ result.push(`option ${key}:${value}`)
+ }
+ }
+ return result
+ })()
+ const sortedOptionsList = optionsList.sort()
+ const hash = buildState(
+ [
+ ...Array.from(sortedEntityList),
+ ...Array.from(sortedOptionsList)
+ ].join('\n')
+ )
+ return callback(null, hash)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Compile/CompileController.js b/services/web/app/src/Features/Compile/CompileController.js
new file mode 100644
index 0000000000..e81a110078
--- /dev/null
+++ b/services/web/app/src/Features/Compile/CompileController.js
@@ -0,0 +1,556 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-undef,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CompileController
+const Metrics = require('metrics-sharelatex')
+const ProjectGetter = require('../Project/ProjectGetter')
+const CompileManager = require('./CompileManager')
+const ClsiManager = require('./ClsiManager')
+const logger = require('logger-sharelatex')
+const request = require('request')
+const sanitize = require('sanitizer')
+const Settings = require('settings-sharelatex')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const UserGetter = require('../User/UserGetter')
+const RateLimiter = require('../../infrastructure/RateLimiter')
+const ClsiCookieManager = require('./ClsiCookieManager')(
+ Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
+)
+const Path = require('path')
+
+module.exports = CompileController = {
+ compile(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ res.setTimeout(5 * 60 * 1000)
+ const project_id = req.params.Project_id
+ const isAutoCompile = !!(req.query != null
+ ? req.query.auto_compile
+ : undefined)
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ const options = {
+ isAutoCompile
+ }
+ if ((req.body != null ? req.body.rootDoc_id : undefined) != null) {
+ options.rootDoc_id = req.body.rootDoc_id
+ } else if (
+ __guard__(
+ req.body != null ? req.body.settingsOverride : undefined,
+ x => x.rootDoc_id
+ ) != null
+ ) {
+ // Can be removed after deploy
+ options.rootDoc_id = req.body.settingsOverride.rootDoc_id
+ }
+ if (req.body != null ? req.body.compiler : undefined) {
+ options.compiler = req.body.compiler
+ }
+ if (req.body != null ? req.body.draft : undefined) {
+ options.draft = req.body.draft
+ }
+ if (
+ ['validate', 'error', 'silent'].includes(
+ req.body != null ? req.body.check : undefined
+ )
+ ) {
+ options.check = req.body.check
+ }
+ if (req.body != null ? req.body.incrementalCompilesEnabled : undefined) {
+ options.incrementalCompilesEnabled = true
+ }
+ logger.log({ options, project_id, user_id }, 'got compile request')
+ return CompileManager.compile(project_id, user_id, options, function(
+ error,
+ status,
+ outputFiles,
+ clsiServerId,
+ limits,
+ validationProblems
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ res.contentType('application/json')
+ return res.status(200).send(
+ JSON.stringify({
+ status,
+ outputFiles,
+ compileGroup: limits != null ? limits.compileGroup : undefined,
+ clsiServerId,
+ validationProblems,
+ pdfDownloadDomain: Settings.pdfDownloadDomain
+ })
+ )
+ })
+ },
+
+ stopCompile(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ logger.log({ project_id, user_id }, 'stop compile request')
+ return CompileManager.stopCompile(project_id, user_id, function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.status(200).send()
+ })
+ },
+
+ // Used for submissions through the public API
+ compileSubmission(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ res.setTimeout(5 * 60 * 1000)
+ const { submission_id } = req.params
+ const options = {}
+ if ((req.body != null ? req.body.rootResourcePath : undefined) != null) {
+ options.rootResourcePath = req.body.rootResourcePath
+ }
+ if (req.body != null ? req.body.compiler : undefined) {
+ options.compiler = req.body.compiler
+ }
+ if (req.body != null ? req.body.draft : undefined) {
+ options.draft = req.body.draft
+ }
+ if (
+ ['validate', 'error', 'silent'].includes(
+ req.body != null ? req.body.check : undefined
+ )
+ ) {
+ options.check = req.body.check
+ }
+ options.compileGroup =
+ (req.body != null ? req.body.compileGroup : undefined) ||
+ Settings.defaultFeatures.compileGroup
+ options.timeout =
+ (req.body != null ? req.body.timeout : undefined) ||
+ Settings.defaultFeatures.compileTimeout
+ logger.log({ options, submission_id }, 'got compileSubmission request')
+ return ClsiManager.sendExternalRequest(
+ submission_id,
+ req.body,
+ options,
+ function(error, status, outputFiles, clsiServerId, validationProblems) {
+ if (error != null) {
+ return next(error)
+ }
+ logger.log(
+ { submission_id, files: outputFiles },
+ 'compileSubmission output files'
+ )
+ res.contentType('application/json')
+ return res.status(200).send(
+ JSON.stringify({
+ status,
+ outputFiles,
+ clsiServerId,
+ validationProblems
+ })
+ )
+ }
+ )
+ },
+
+ _compileAsUser(req, callback) {
+ // callback with user_id if per-user, undefined otherwise
+ if (!Settings.disablePerUserCompiles) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return callback(null, user_id)
+ } else {
+ return callback()
+ }
+ }, // do a per-project compile, not per-user
+
+ _downloadAsUser(req, callback) {
+ // callback with user_id if per-user, undefined otherwise
+ if (!Settings.disablePerUserCompiles) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return callback(null, user_id)
+ } else {
+ return callback()
+ }
+ }, // do a per-project compile, not per-user
+
+ downloadPdf(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ Metrics.inc('pdf-downloads')
+ const project_id = req.params.Project_id
+ const isPdfjsPartialDownload =
+ req.query != null ? req.query.pdfng : undefined
+ const rateLimit = function(callback) {
+ if (isPdfjsPartialDownload) {
+ return callback(null, true)
+ } else {
+ const rateLimitOpts = {
+ endpointName: 'full-pdf-download',
+ throttle: 1000,
+ subjectName: req.ip,
+ timeInterval: 60 * 60
+ }
+ return RateLimiter.addCount(rateLimitOpts, callback)
+ }
+ }
+
+ return ProjectGetter.getProject(project_id, { name: 1 }, function(
+ err,
+ project
+ ) {
+ res.contentType('application/pdf')
+ const filename = `${CompileController._getSafeProjectName(project)}.pdf`
+
+ if (req.query.popupDownload) {
+ logger.log({ project_id }, 'download pdf as popup download')
+ res.setContentDisposition('attachment', { filename })
+ } else {
+ logger.log({ project_id }, 'download pdf to embed in browser')
+ res.setContentDisposition('', { filename })
+ }
+
+ return rateLimit(function(err, canContinue) {
+ if (err != null) {
+ logger.err({ err }, 'error checking rate limit for pdf download')
+ return res.send(500)
+ } else if (!canContinue) {
+ logger.log(
+ { project_id, ip: req.ip },
+ 'rate limit hit downloading pdf'
+ )
+ return res.send(500)
+ } else {
+ return CompileController._downloadAsUser(req, function(
+ error,
+ user_id
+ ) {
+ const url = CompileController._getFileUrl(
+ project_id,
+ user_id,
+ req.params.build_id,
+ 'output.pdf'
+ )
+ return CompileController.proxyToClsi(
+ project_id,
+ url,
+ req,
+ res,
+ next
+ )
+ })
+ }
+ })
+ })
+ },
+
+ _getSafeProjectName(project) {
+ const safeProjectName = project.name.replace(new RegExp('\\W', 'g'), '_')
+ return sanitize.escape(safeProjectName)
+ },
+
+ deleteAuxFiles(req, res, next) {
+ const project_id = req.params.Project_id
+ return CompileController._compileAsUser(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ return CompileManager.deleteAuxFiles(project_id, user_id, function(
+ error
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.sendStatus(200)
+ })
+ })
+ },
+
+ // this is only used by templates, so is not called with a user_id
+ compileAndDownloadPdf(req, res, next) {
+ const { project_id } = req.params
+ // pass user_id as null, since templates are an "anonymous" compile
+ return CompileManager.compile(project_id, null, {}, function(err) {
+ if (err != null) {
+ logger.err(
+ { err, project_id },
+ 'something went wrong compile and downloading pdf'
+ )
+ res.sendStatus(500)
+ }
+ const url = `/project/${project_id}/output/output.pdf`
+ return CompileController.proxyToClsi(project_id, url, req, res, next)
+ })
+ },
+
+ getFileFromClsi(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ return CompileController._downloadAsUser(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ const url = CompileController._getFileUrl(
+ project_id,
+ user_id,
+ req.params.build_id,
+ req.params.file
+ )
+ return CompileController.proxyToClsi(project_id, url, req, res, next)
+ })
+ },
+
+ getFileFromClsiWithoutUser(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const { submission_id } = req.params
+ const url = CompileController._getFileUrl(
+ submission_id,
+ null,
+ req.params.build_id,
+ req.params.file
+ )
+ const limits = {
+ compileGroup:
+ (req.body != null ? req.body.compileGroup : undefined) ||
+ Settings.defaultFeatures.compileGroup
+ }
+ return CompileController.proxyToClsiWithLimits(
+ submission_id,
+ url,
+ limits,
+ req,
+ res,
+ next
+ )
+ },
+
+ // compute a GET file url for a given project, user (optional), build (optional) and file
+ _getFileUrl(project_id, user_id, build_id, file) {
+ let url
+ if (user_id != null && build_id != null) {
+ url = `/project/${project_id}/user/${user_id}/build/${build_id}/output/${file}`
+ } else if (user_id != null) {
+ url = `/project/${project_id}/user/${user_id}/output/${file}`
+ } else if (build_id != null) {
+ url = `/project/${project_id}/build/${build_id}/output/${file}`
+ } else {
+ url = `/project/${project_id}/output/${file}`
+ }
+ return url
+ },
+
+ // compute a POST url for a project, user (optional) and action
+ _getUrl(project_id, user_id, action) {
+ let path = `/project/${project_id}`
+ if (user_id != null) {
+ path += `/user/${user_id}`
+ }
+ return `${path}/${action}`
+ },
+
+ proxySyncPdf(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const { page, h, v } = req.query
+ if (!(page != null ? page.match(/^\d+$/) : undefined)) {
+ return next(new Error('invalid page parameter'))
+ }
+ if (!(h != null ? h.match(/^-?\d+\.\d+$/) : undefined)) {
+ return next(new Error('invalid h parameter'))
+ }
+ if (!(v != null ? v.match(/^-?\d+\.\d+$/) : undefined)) {
+ return next(new Error('invalid v parameter'))
+ }
+ // whether this request is going to a per-user container
+ return CompileController._compileAsUser(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ const url = CompileController._getUrl(project_id, user_id, 'sync/pdf')
+ const destination = { url, qs: { page, h, v } }
+ return CompileController.proxyToClsi(
+ project_id,
+ destination,
+ req,
+ res,
+ next
+ )
+ })
+ },
+
+ proxySyncCode(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const { file, line, column } = req.query
+ if (file == null) {
+ return next(new Error('missing file parameter'))
+ }
+ // Check that we are dealing with a simple file path (this is not
+ // strictly needed because synctex uses this parameter as a label
+ // to look up in the synctex output, and does not open the file
+ // itself). Since we have valid synctex paths like foo/./bar we
+ // allow those by replacing /./ with /
+ const testPath = file.replace('/./', '/')
+ if (Path.resolve('/', testPath) !== `/${testPath}`) {
+ return next(new Error('invalid file parameter'))
+ }
+ if (!(line != null ? line.match(/^\d+$/) : undefined)) {
+ return next(new Error('invalid line parameter'))
+ }
+ if (!(column != null ? column.match(/^\d+$/) : undefined)) {
+ return next(new Error('invalid column parameter'))
+ }
+ return CompileController._compileAsUser(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ const url = CompileController._getUrl(project_id, user_id, 'sync/code')
+ const destination = { url, qs: { file, line, column } }
+ return CompileController.proxyToClsi(
+ project_id,
+ destination,
+ req,
+ res,
+ next
+ )
+ })
+ },
+
+ proxyToClsi(project_id, url, req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ if (req.query != null ? req.query.compileGroup : undefined) {
+ return CompileController.proxyToClsiWithLimits(
+ project_id,
+ url,
+ { compileGroup: req.query.compileGroup },
+ req,
+ res,
+ next
+ )
+ } else {
+ return CompileManager.getProjectCompileLimits(project_id, function(
+ error,
+ limits
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ return CompileController.proxyToClsiWithLimits(
+ project_id,
+ url,
+ limits,
+ req,
+ res,
+ next
+ )
+ })
+ }
+ },
+
+ proxyToClsiWithLimits(project_id, url, limits, req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ return ClsiCookieManager.getCookieJar(project_id, function(err, jar) {
+ let qs
+ if (err != null) {
+ logger.err({ err }, 'error getting cookie jar for clsi request')
+ return callback(err)
+ }
+ // expand any url parameter passed in as {url:..., qs:...}
+ if (typeof url === 'object') {
+ ;({ url, qs } = url)
+ }
+ const compilerUrl = Settings.apis.clsi.url
+ url = `${compilerUrl}${url}`
+ logger.log({ url }, 'proxying to CLSI')
+ const oneMinute = 60 * 1000
+ // the base request
+ const options = { url, method: req.method, timeout: oneMinute, jar }
+ // add any provided query string
+ if (qs != null) {
+ options.qs = qs
+ }
+ // if we have a build parameter, pass it through to the clsi
+ if (
+ (req.query != null ? req.query.pdfng : undefined) &&
+ (req.query != null ? req.query.build : undefined) != null
+ ) {
+ // only for new pdf viewer
+ if (options.qs == null) {
+ options.qs = {}
+ }
+ options.qs.build = req.query.build
+ }
+ // if we are byte serving pdfs, pass through If-* and Range headers
+ // do not send any others, there's a proxying loop if Host: is passed!
+ if (req.query != null ? req.query.pdfng : undefined) {
+ const newHeaders = {}
+ for (let h in req.headers) {
+ const v = req.headers[h]
+ if (/^(If-|Range)/i.test(h)) {
+ newHeaders[h] = req.headers[h]
+ }
+ }
+ options.headers = newHeaders
+ }
+ const proxy = request(options)
+ proxy.pipe(res)
+ return proxy.on('error', error =>
+ logger.warn({ err: error, url }, 'CLSI proxy error')
+ )
+ })
+ },
+
+ wordCount(req, res, next) {
+ const project_id = req.params.Project_id
+ const file = req.query.file || false
+ return CompileController._compileAsUser(req, function(error, user_id) {
+ if (error != null) {
+ return next(error)
+ }
+ return CompileManager.wordCount(project_id, user_id, file, function(
+ error,
+ body
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ res.contentType('application/json')
+ return res.send(body)
+ })
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Compile/CompileManager.js b/services/web/app/src/Features/Compile/CompileManager.js
new file mode 100644
index 0000000000..ecc21e55f4
--- /dev/null
+++ b/services/web/app/src/Features/Compile/CompileManager.js
@@ -0,0 +1,288 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CompileManager
+const Settings = require('settings-sharelatex')
+const RedisWrapper = require('../../infrastructure/RedisWrapper')
+const rclient = RedisWrapper.client('clsi_recently_compiled')
+const ProjectGetter = require('../Project/ProjectGetter')
+const ProjectRootDocManager = require('../Project/ProjectRootDocManager')
+const UserGetter = require('../User/UserGetter')
+const ClsiManager = require('./ClsiManager')
+const Metrics = require('metrics-sharelatex')
+const logger = require('logger-sharelatex')
+const rateLimiter = require('../../infrastructure/RateLimiter')
+
+module.exports = CompileManager = {
+ compile(project_id, user_id, options, _callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (_callback == null) {
+ _callback = function(error) {}
+ }
+ const timer = new Metrics.Timer('editor.compile')
+ const callback = function(...args) {
+ timer.done()
+ return _callback(...Array.from(args || []))
+ }
+
+ logger.log({ project_id, user_id }, 'compiling project')
+ return CompileManager._checkIfRecentlyCompiled(
+ project_id,
+ user_id,
+ function(error, recentlyCompiled) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (recentlyCompiled) {
+ logger.warn(
+ { project_id, user_id },
+ 'project was recently compiled so not continuing'
+ )
+ return callback(null, 'too-recently-compiled', [])
+ }
+
+ return CompileManager._checkIfAutoCompileLimitHasBeenHit(
+ options.isAutoCompile,
+ 'everyone',
+ function(err, canCompile) {
+ if (!canCompile) {
+ return callback(null, 'autocompile-backoff', [])
+ }
+
+ return ProjectRootDocManager.ensureRootDocumentIsSet(
+ project_id,
+ function(error) {
+ if (error != null) {
+ return callback(error)
+ }
+ return CompileManager.getProjectCompileLimits(
+ project_id,
+ function(error, limits) {
+ if (error != null) {
+ return callback(error)
+ }
+ for (let key in limits) {
+ const value = limits[key]
+ options[key] = value
+ }
+ // Put a lower limit on autocompiles for free users, based on compileGroup
+ return CompileManager._checkCompileGroupAutoCompileLimit(
+ options.isAutoCompile,
+ limits.compileGroup,
+ function(err, canCompile) {
+ if (!canCompile) {
+ return callback(null, 'autocompile-backoff', [])
+ }
+ // only pass user_id down to clsi if this is a per-user compile
+ const compileAsUser = Settings.disablePerUserCompiles
+ ? undefined
+ : user_id
+ return ClsiManager.sendRequest(
+ project_id,
+ compileAsUser,
+ options,
+ function(
+ error,
+ status,
+ outputFiles,
+ clsiServerId,
+ validationProblems
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ logger.log({ files: outputFiles }, 'output files')
+ return callback(
+ null,
+ status,
+ outputFiles,
+ clsiServerId,
+ limits,
+ validationProblems
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ },
+
+ stopCompile(project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return CompileManager.getProjectCompileLimits(project_id, function(
+ error,
+ limits
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return ClsiManager.stopCompile(project_id, user_id, limits, callback)
+ })
+ },
+
+ deleteAuxFiles(project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return CompileManager.getProjectCompileLimits(project_id, function(
+ error,
+ limits
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return ClsiManager.deleteAuxFiles(project_id, user_id, limits, callback)
+ })
+ },
+
+ getProjectCompileLimits(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, limits) {}
+ }
+ return ProjectGetter.getProject(project_id, { owner_ref: 1 }, function(
+ error,
+ project
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return UserGetter.getUser(project.owner_ref, { features: 1 }, function(
+ err,
+ owner
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, {
+ timeout:
+ __guard__(
+ owner != null ? owner.features : undefined,
+ x => x.compileTimeout
+ ) || Settings.defaultFeatures.compileTimeout,
+ compileGroup:
+ __guard__(
+ owner != null ? owner.features : undefined,
+ x1 => x1.compileGroup
+ ) || Settings.defaultFeatures.compileGroup
+ })
+ })
+ })
+ },
+
+ COMPILE_DELAY: 1, // seconds
+ _checkIfRecentlyCompiled(project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error, recentlyCompiled) {}
+ }
+ const key = `compile:${project_id}:${user_id}`
+ return rclient.set(key, true, 'EX', this.COMPILE_DELAY, 'NX', function(
+ error,
+ ok
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (ok === 'OK') {
+ return callback(null, false)
+ } else {
+ return callback(null, true)
+ }
+ })
+ },
+
+ _checkCompileGroupAutoCompileLimit(isAutoCompile, compileGroup, callback) {
+ if (callback == null) {
+ callback = function(err, canCompile) {}
+ }
+ if (!isAutoCompile) {
+ return callback(null, true)
+ }
+ if (compileGroup === 'standard') {
+ // apply extra limits to the standard compile group
+ return CompileManager._checkIfAutoCompileLimitHasBeenHit(
+ isAutoCompile,
+ compileGroup,
+ callback
+ )
+ } else {
+ Metrics.inc(`auto-compile-${compileGroup}`)
+ return callback(null, true)
+ }
+ }, // always allow priority group users to compile
+
+ _checkIfAutoCompileLimitHasBeenHit(isAutoCompile, compileGroup, callback) {
+ if (callback == null) {
+ callback = function(err, canCompile) {}
+ }
+ if (!isAutoCompile) {
+ return callback(null, true)
+ }
+ Metrics.inc(`auto-compile-${compileGroup}`)
+ const opts = {
+ endpointName: 'auto_compile',
+ timeInterval: 20,
+ subjectName: compileGroup,
+ throttle:
+ __guard__(
+ __guard__(
+ Settings != null ? Settings.rateLimit : undefined,
+ x1 => x1.autoCompile
+ ),
+ x => x[compileGroup]
+ ) || 25
+ }
+ return rateLimiter.addCount(opts, function(err, canCompile) {
+ if (err != null) {
+ canCompile = false
+ }
+ if (!canCompile) {
+ Metrics.inc(`auto-compile-${compileGroup}-limited`)
+ }
+ return callback(err, canCompile)
+ })
+ },
+
+ wordCount(project_id, user_id, file, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return CompileManager.getProjectCompileLimits(project_id, function(
+ error,
+ limits
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ return ClsiManager.wordCount(project_id, user_id, file, limits, callback)
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Contacts/ContactController.js b/services/web/app/src/Features/Contacts/ContactController.js
new file mode 100644
index 0000000000..81e17b5ea4
--- /dev/null
+++ b/services/web/app/src/Features/Contacts/ContactController.js
@@ -0,0 +1,88 @@
+/* eslint-disable
+ camelcase,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ContactsController
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const ContactManager = require('./ContactManager')
+const UserGetter = require('../User/UserGetter')
+const logger = require('logger-sharelatex')
+const Modules = require('../../infrastructure/Modules')
+
+module.exports = ContactsController = {
+ getContacts(req, res, next) {
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return ContactManager.getContactIds(user_id, { limit: 50 }, function(
+ error,
+ contact_ids
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ return UserGetter.getUsers(
+ contact_ids,
+ {
+ email: 1,
+ first_name: 1,
+ last_name: 1,
+ holdingAccount: 1
+ },
+ function(error, contacts) {
+ if (error != null) {
+ return next(error)
+ }
+
+ // UserGetter.getUsers may not preserve order so put them back in order
+ const positions = {}
+ for (let i = 0; i < contact_ids.length; i++) {
+ const contact_id = contact_ids[i]
+ positions[contact_id] = i
+ }
+ contacts.sort(
+ (a, b) =>
+ positions[a._id != null ? a._id.toString() : undefined] -
+ positions[b._id != null ? b._id.toString() : undefined]
+ )
+
+ // Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
+ contacts = contacts.filter(c => !c.holdingAccount)
+
+ contacts = contacts.map(ContactsController._formatContact)
+
+ return Modules.hooks.fire('getContacts', user_id, contacts, function(
+ error,
+ additional_contacts
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ contacts = contacts.concat(...Array.from(additional_contacts || []))
+ return res.send({
+ contacts
+ })
+ })
+ }
+ )
+ })
+ },
+
+ _formatContact(contact) {
+ return {
+ id: contact._id != null ? contact._id.toString() : undefined,
+ email: contact.email || '',
+ first_name: contact.first_name || '',
+ last_name: contact.last_name || '',
+ type: 'user'
+ }
+ }
+}
diff --git a/services/web/app/src/Features/Contacts/ContactManager.js b/services/web/app/src/Features/Contacts/ContactManager.js
new file mode 100644
index 0000000000..b97ba05d35
--- /dev/null
+++ b/services/web/app/src/Features/Contacts/ContactManager.js
@@ -0,0 +1,96 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ContactManager
+const request = require('request')
+const settings = require('settings-sharelatex')
+const logger = require('logger-sharelatex')
+
+module.exports = ContactManager = {
+ getContactIds(user_id, options, callback) {
+ if (options == null) {
+ options = { limits: 50 }
+ }
+ if (callback == null) {
+ callback = function(error, contacts) {}
+ }
+ logger.log({ user_id }, 'getting user contacts')
+ const url = `${settings.apis.contacts.url}/user/${user_id}/contacts`
+ return request.get(
+ {
+ url,
+ qs: options,
+ json: true,
+ jar: false
+ },
+ function(error, res, data) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(
+ null,
+ (data != null ? data.contact_ids : undefined) || []
+ )
+ } else {
+ error = new Error(
+ `contacts api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, user_id },
+ 'error getting contacts for user'
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ addContact(user_id, contact_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ user_id, contact_id }, 'add user contact')
+ const url = `${settings.apis.contacts.url}/user/${user_id}/contacts`
+ return request.post(
+ {
+ url,
+ json: {
+ contact_id
+ },
+ jar: false
+ },
+ function(error, res, data) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(
+ null,
+ (data != null ? data.contact_ids : undefined) || []
+ )
+ } else {
+ error = new Error(
+ `contacts api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, user_id, contact_id },
+ 'error adding contact for user'
+ )
+ return callback(error)
+ }
+ }
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Contacts/ContactRouter.js b/services/web/app/src/Features/Contacts/ContactRouter.js
new file mode 100644
index 0000000000..6e9a8ff78f
--- /dev/null
+++ b/services/web/app/src/Features/Contacts/ContactRouter.js
@@ -0,0 +1,19 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const ContactController = require('./ContactController')
+
+module.exports = {
+ apply(webRouter, apiRouter) {
+ return webRouter.get(
+ '/user/contacts',
+ AuthenticationController.requireLogin(),
+ ContactController.getContacts
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Cooldown/CooldownManager.js b/services/web/app/src/Features/Cooldown/CooldownManager.js
new file mode 100644
index 0000000000..1a2a39d4a5
--- /dev/null
+++ b/services/web/app/src/Features/Cooldown/CooldownManager.js
@@ -0,0 +1,56 @@
+/* eslint-disable
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CooldownManager
+const RedisWrapper = require('../../infrastructure/RedisWrapper')
+const rclient = RedisWrapper.client('cooldown')
+const logger = require('logger-sharelatex')
+
+const COOLDOWN_IN_SECONDS = 60 * 10
+
+module.exports = CooldownManager = {
+ _buildKey(projectId) {
+ return `Cooldown:{${projectId}}`
+ },
+
+ putProjectOnCooldown(projectId, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ logger.log(
+ { projectId },
+ `[Cooldown] putting project on cooldown for ${COOLDOWN_IN_SECONDS} seconds`
+ )
+ return rclient.set(
+ CooldownManager._buildKey(projectId),
+ '1',
+ 'EX',
+ COOLDOWN_IN_SECONDS,
+ callback
+ )
+ },
+
+ isProjectOnCooldown(projectId, callback) {
+ if (callback == null) {
+ callback = function(err, isOnCooldown) {}
+ }
+ return rclient.get(CooldownManager._buildKey(projectId), function(
+ err,
+ result
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback(null, result === '1')
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Cooldown/CooldownMiddleware.js b/services/web/app/src/Features/Cooldown/CooldownMiddleware.js
new file mode 100644
index 0000000000..9baf008007
--- /dev/null
+++ b/services/web/app/src/Features/Cooldown/CooldownMiddleware.js
@@ -0,0 +1,40 @@
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let CooldownMiddleware
+const CooldownManager = require('./CooldownManager')
+const logger = require('logger-sharelatex')
+
+module.exports = CooldownMiddleware = {
+ freezeProject(req, res, next) {
+ const projectId = req.params.Project_id
+ if (projectId == null) {
+ return next(new Error('[Cooldown] No projectId parameter on route'))
+ }
+ return CooldownManager.isProjectOnCooldown(projectId, function(
+ err,
+ projectIsOnCooldown
+ ) {
+ if (err != null) {
+ return next(err)
+ }
+ if (projectIsOnCooldown) {
+ logger.log(
+ { projectId },
+ '[Cooldown] project is on cooldown, denying request'
+ )
+ return res.sendStatus(429)
+ }
+ return next()
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Docstore/DocstoreManager.js b/services/web/app/src/Features/Docstore/DocstoreManager.js
new file mode 100644
index 0000000000..e43bcd1071
--- /dev/null
+++ b/services/web/app/src/Features/Docstore/DocstoreManager.js
@@ -0,0 +1,261 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let DocstoreManager
+const request = require('request').defaults({ jar: false })
+const logger = require('logger-sharelatex')
+const settings = require('settings-sharelatex')
+const Errors = require('../Errors/Errors')
+
+module.exports = DocstoreManager = {
+ deleteDoc(project_id, doc_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id, doc_id }, 'deleting doc in docstore api')
+ const url = `${
+ settings.apis.docstore.url
+ }/project/${project_id}/doc/${doc_id}`
+ return request.del(url, function(error, res, body) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(null)
+ } else if (res.statusCode === 404) {
+ error = new Errors.NotFoundError('tried to delete doc not in docstore')
+ logger.error(
+ { err: error, project_id, doc_id },
+ 'tried to delete doc not in docstore'
+ )
+ return callback(error) // maybe suppress the error when delete doc which is not present?
+ } else {
+ error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, project_id, doc_id },
+ 'error deleting doc in docstore'
+ )
+ return callback(error)
+ }
+ })
+ },
+
+ getAllDocs(project_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id }, 'getting all docs for project in docstore api')
+ const url = `${settings.apis.docstore.url}/project/${project_id}/doc`
+ return request.get(
+ {
+ url,
+ json: true
+ },
+ function(error, res, docs) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(null, docs)
+ } else {
+ error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, project_id },
+ 'error getting all docs from docstore'
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ getAllRanges(project_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log(
+ { project_id },
+ 'getting all doc ranges for project in docstore api'
+ )
+ const url = `${settings.apis.docstore.url}/project/${project_id}/ranges`
+ return request.get(
+ {
+ url,
+ json: true
+ },
+ function(error, res, docs) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(null, docs)
+ } else {
+ error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, project_id },
+ 'error getting all doc ranges from docstore'
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ getDoc(project_id, doc_id, options, callback) {
+ if (options == null) {
+ options = {}
+ }
+ if (callback == null) {
+ callback = function(error, lines, rev, version) {}
+ }
+ if (typeof options === 'function') {
+ callback = options
+ options = {}
+ }
+ logger.log({ project_id, doc_id, options }, 'getting doc in docstore api')
+ let url = `${
+ settings.apis.docstore.url
+ }/project/${project_id}/doc/${doc_id}`
+ if (options.include_deleted) {
+ url += '?include_deleted=true'
+ }
+ return request.get(
+ {
+ url,
+ json: true
+ },
+ function(error, res, doc) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ logger.log(
+ { doc_id, project_id, version: doc.version, rev: doc.rev },
+ 'got doc from docstore api'
+ )
+ return callback(null, doc.lines, doc.rev, doc.version, doc.ranges)
+ } else if (res.statusCode === 404) {
+ error = new Errors.NotFoundError('doc not found in docstore')
+ logger.error(
+ { err: error, project_id, doc_id },
+ 'doc not found in docstore'
+ )
+ return callback(error)
+ } else {
+ error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, project_id, doc_id },
+ 'error getting doc from docstore'
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ updateDoc(project_id, doc_id, lines, version, ranges, callback) {
+ if (callback == null) {
+ callback = function(error, modified, rev) {}
+ }
+ logger.log({ project_id, doc_id }, 'updating doc in docstore api')
+ const url = `${
+ settings.apis.docstore.url
+ }/project/${project_id}/doc/${doc_id}`
+ return request.post(
+ {
+ url,
+ json: {
+ lines,
+ version,
+ ranges
+ }
+ },
+ function(error, res, result) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ logger.log(
+ { project_id, doc_id },
+ 'update doc in docstore url finished'
+ )
+ return callback(null, result.modified, result.rev)
+ } else {
+ error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.error(
+ { err: error, project_id, doc_id },
+ 'error updating doc in docstore'
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ archiveProject(project_id, callback) {
+ const url = `${settings.apis.docstore.url}/project/${project_id}/archive`
+ logger.log({ project_id }, 'archiving project in docstore')
+ return request.post(url, function(err, res, docs) {
+ if (err != null) {
+ logger.err({ err, project_id }, 'error archving project in docstore')
+ return callback(err)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback()
+ } else {
+ const error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.err(
+ { err: error, project_id },
+ 'error archiving project in docstore'
+ )
+ return callback(error)
+ }
+ })
+ },
+
+ unarchiveProject(project_id, callback) {
+ const url = `${settings.apis.docstore.url}/project/${project_id}/unarchive`
+ logger.log({ project_id }, 'unarchiving project in docstore')
+ return request.post(url, function(err, res, docs) {
+ if (err != null) {
+ logger.err({ err, project_id }, 'error unarchiving project in docstore')
+ return callback(err)
+ }
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback()
+ } else {
+ const error = new Error(
+ `docstore api responded with non-success code: ${res.statusCode}`
+ )
+ logger.err(
+ { err: error, project_id },
+ 'error unarchiving project in docstore'
+ )
+ return callback(error)
+ }
+ })
+ }
+}
diff --git a/services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.js b/services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.js
new file mode 100644
index 0000000000..18d0720b0a
--- /dev/null
+++ b/services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.js
@@ -0,0 +1,467 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let DocumentUpdaterHandler
+let request = require('request')
+request = request.defaults()
+const settings = require('settings-sharelatex')
+const _ = require('underscore')
+const async = require('async')
+const logger = require('logger-sharelatex')
+const metrics = require('metrics-sharelatex')
+const { Project } = require('../../models/Project')
+
+module.exports = DocumentUpdaterHandler = {
+ flushProjectToMongo(project_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id }, 'flushing project from document updater')
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/flush`,
+ method: 'POST'
+ },
+ project_id,
+ 'flushing.mongo.project',
+ callback
+ )
+ },
+
+ flushMultipleProjectsToMongo(project_ids, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const jobs = []
+ for (let project_id of Array.from(project_ids)) {
+ ;(project_id =>
+ jobs.push(callback =>
+ DocumentUpdaterHandler.flushProjectToMongo(project_id, callback)
+ ))(project_id)
+ }
+ return async.series(jobs, callback)
+ },
+
+ flushProjectToMongoAndDelete(project_id, callback) {
+ if (callback == null) {
+ callback = function() {}
+ }
+ const timer = new metrics.Timer('delete.mongo.project')
+ const url = `${settings.apis.documentupdater.url}`
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}`,
+ method: 'DELETE'
+ },
+ project_id,
+ 'flushing.mongo.project',
+ callback
+ )
+ },
+
+ flushDocToMongo(project_id, doc_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id, doc_id }, 'flushing doc from document updater')
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}/flush`,
+ method: 'POST'
+ },
+ project_id,
+ 'flushing.mongo.doc',
+ callback
+ )
+ },
+
+ deleteDoc(project_id, doc_id, callback) {
+ if (callback == null) {
+ callback = function() {}
+ }
+ logger.log({ project_id, doc_id }, 'deleting doc from document updater')
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}`,
+ method: 'DELETE'
+ },
+ project_id,
+ 'delete.mongo.doc',
+ callback
+ )
+ },
+
+ getDocument(project_id, doc_id, fromVersion, callback) {
+ if (callback == null) {
+ callback = function(error, doclines, version, ranges, ops) {}
+ }
+ logger.log({ project_id, doc_id }, 'getting doc from document updater')
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}?fromVersion=${fromVersion}`,
+ json: true
+ },
+ project_id,
+ 'get-document',
+ function(error, doc) {
+ if (error != null) {
+ return callback(error)
+ }
+ return callback(null, doc.lines, doc.version, doc.ranges, doc.ops)
+ }
+ )
+ },
+
+ setDocument(project_id, doc_id, user_id, docLines, source, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log(
+ { project_id, doc_id, source, user_id },
+ 'setting doc in document updater'
+ )
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}`,
+ method: 'POST',
+ json: {
+ lines: docLines,
+ source,
+ user_id
+ }
+ },
+ project_id,
+ 'set-document',
+ callback
+ )
+ },
+
+ getProjectDocsIfMatch(project_id, projectStateHash, callback) {
+ // If the project state hasn't changed, we can get all the latest
+ // docs from redis via the docupdater. Otherwise we will need to
+ // fall back to getting them from mongo.
+ if (callback == null) {
+ callback = function(error, docs) {}
+ }
+ const timer = new metrics.Timer('get-project-docs')
+ const url = `${
+ settings.apis.documentupdater.url
+ }/project/${project_id}/get_and_flush_if_old?state=${projectStateHash}`
+ logger.log({ project_id }, 'getting project docs from document updater')
+ return request.post(url, function(error, res, body) {
+ timer.done()
+ if (error != null) {
+ logger.error(
+ { err: error, url, project_id },
+ 'error getting project docs from doc updater'
+ )
+ return callback(error)
+ }
+ if (res.statusCode === 409) {
+ // HTTP response code "409 Conflict"
+ // Docupdater has checked the projectStateHash and found that
+ // it has changed. This means that the docs currently in redis
+ // aren't the only change to the project and the full set of
+ // docs/files should be retreived from docstore/filestore
+ // instead.
+ return callback()
+ } else if (res.statusCode >= 200 && res.statusCode < 300) {
+ let docs
+ logger.log(
+ { project_id },
+ 'got project docs from document document updater'
+ )
+ try {
+ docs = JSON.parse(body)
+ } catch (error1) {
+ error = error1
+ return callback(error)
+ }
+ return callback(null, docs)
+ } else {
+ logger.error(
+ { project_id, url },
+ `doc updater returned a non-success status code: ${res.statusCode}`
+ )
+ return callback(
+ new Error(
+ `doc updater returned a non-success status code: ${res.statusCode}`
+ )
+ )
+ }
+ })
+ },
+
+ clearProjectState(project_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id }, 'clearing project state from document updater')
+
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/clearState`,
+ method: 'POST'
+ },
+ project_id,
+ 'clear-project-state',
+ callback
+ )
+ },
+
+ acceptChanges(project_id, doc_id, change_ids, callback) {
+ if (change_ids == null) {
+ change_ids = []
+ }
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log({ project_id, doc_id }, `accepting ${change_ids.length} changes`)
+
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}/change/accept`,
+ json: {
+ change_ids
+ },
+ method: 'POST'
+ },
+ project_id,
+ 'accept-changes',
+ callback
+ )
+ },
+
+ deleteThread(project_id, doc_id, thread_id, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ const timer = new metrics.Timer('delete-thread')
+ logger.log(
+ { project_id, doc_id, thread_id },
+ 'deleting comment range in document updater'
+ )
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/doc/${doc_id}/comment/${thread_id}`,
+ method: 'DELETE'
+ },
+ project_id,
+ 'delete-thread',
+ callback
+ )
+ },
+
+ resyncProjectHistory(project_id, projectHistoryId, docs, files, callback) {
+ logger.info(
+ { project_id, docs, files },
+ 'resyncing project history in doc updater'
+ )
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}/history/resync`,
+ json: { docs, files, projectHistoryId },
+ method: 'POST'
+ },
+ project_id,
+ 'resync-project-history',
+ callback
+ )
+ },
+
+ updateProjectStructure(
+ project_id,
+ projectHistoryId,
+ userId,
+ changes,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ if (
+ !(settings.apis.project_history != null
+ ? settings.apis.project_history.sendProjectStructureOps
+ : undefined)
+ ) {
+ return callback()
+ }
+
+ const docUpdates = DocumentUpdaterHandler._getUpdates(
+ 'doc',
+ changes.oldDocs,
+ changes.newDocs
+ )
+ const fileUpdates = DocumentUpdaterHandler._getUpdates(
+ 'file',
+ changes.oldFiles,
+ changes.newFiles
+ )
+ const projectVersion = __guard__(
+ changes != null ? changes.newProject : undefined,
+ x => x.version
+ )
+
+ if (docUpdates.length + fileUpdates.length < 1) {
+ return callback()
+ }
+
+ if (projectVersion == null) {
+ logger.error(
+ { project_id, changes, projectVersion },
+ 'did not receive project version in changes'
+ )
+ return callback(new Error('did not receive project version in changes'))
+ }
+
+ logger.log({ project_id }, 'updating project structure in doc updater')
+ return DocumentUpdaterHandler._makeRequest(
+ {
+ path: `/project/${project_id}`,
+ json: {
+ docUpdates,
+ fileUpdates,
+ userId,
+ version: projectVersion,
+ projectHistoryId
+ },
+ method: 'POST'
+ },
+ project_id,
+ 'update-project-structure',
+ callback
+ )
+ },
+
+ _makeRequest(options, project_id, metricsKey, callback) {
+ const timer = new metrics.Timer(metricsKey)
+ return request(
+ {
+ url: `${settings.apis.documentupdater.url}${options.path}`,
+ json: options.json,
+ method: options.method || 'GET'
+ },
+ function(error, res, body) {
+ timer.done()
+ if (error != null) {
+ logger.error(
+ { error, project_id },
+ 'error making request to document updater'
+ )
+ return callback(error)
+ } else if (res.statusCode >= 200 && res.statusCode < 300) {
+ return callback(null, body)
+ } else {
+ error = new Error(
+ `document updater returned a failure status code: ${res.statusCode}`
+ )
+ logger.error(
+ { error, project_id },
+ `document updater returned failure status code: ${res.statusCode}`
+ )
+ return callback(error)
+ }
+ }
+ )
+ },
+
+ _getUpdates(entityType, oldEntities, newEntities) {
+ let id, newEntity, oldEntity
+ if (!oldEntities) {
+ oldEntities = []
+ }
+ if (!newEntities) {
+ newEntities = []
+ }
+ const updates = []
+
+ const oldEntitiesHash = _.indexBy(oldEntities, entity =>
+ entity[entityType]._id.toString()
+ )
+ const newEntitiesHash = _.indexBy(newEntities, entity =>
+ entity[entityType]._id.toString()
+ )
+
+ // Send deletes before adds (and renames) to keep a 1:1 mapping between
+ // paths and ids
+ //
+ // When a file is replaced, we first delete the old file and then add the
+ // new file. If the 'add' operation is sent to project history before the
+ // 'delete' then we would have two files with the same path at that point
+ // in time.
+ for (id in oldEntitiesHash) {
+ oldEntity = oldEntitiesHash[id]
+ newEntity = newEntitiesHash[id]
+
+ if (newEntity == null) {
+ // entity deleted
+ updates.push({
+ id,
+ pathname: oldEntity.path,
+ newPathname: ''
+ })
+ }
+ }
+
+ for (id in newEntitiesHash) {
+ newEntity = newEntitiesHash[id]
+ oldEntity = oldEntitiesHash[id]
+
+ if (oldEntity == null) {
+ // entity added
+ updates.push({
+ id,
+ pathname: newEntity.path,
+ docLines: newEntity.docLines,
+ url: newEntity.url,
+ hash: newEntity.file != null ? newEntity.file.hash : undefined
+ })
+ } else if (newEntity.path !== oldEntity.path) {
+ // entity renamed
+ updates.push({
+ id,
+ pathname: oldEntity.path,
+ newPathname: newEntity.path
+ })
+ }
+ }
+
+ return updates
+ }
+}
+
+const PENDINGUPDATESKEY = 'PendingUpdates'
+const DOCLINESKEY = 'doclines'
+const DOCIDSWITHPENDINGUPDATES = 'DocsWithPendingUpdates'
+
+const keys = {
+ pendingUpdates(op) {
+ return `${PENDINGUPDATESKEY}:${op.doc_id}`
+ },
+ docsWithPendingUpdates: DOCIDSWITHPENDINGUPDATES,
+ docLines(op) {
+ return `${DOCLINESKEY}:${op.doc_id}`
+ },
+ combineProjectIdAndDocId(project_id, doc_id) {
+ return `${project_id}:${doc_id}`
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Documents/DocumentController.js b/services/web/app/src/Features/Documents/DocumentController.js
new file mode 100644
index 0000000000..a9b8e05ba3
--- /dev/null
+++ b/services/web/app/src/Features/Documents/DocumentController.js
@@ -0,0 +1,135 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const ProjectGetter = require('../Project/ProjectGetter')
+const ProjectLocator = require('../Project/ProjectLocator')
+const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
+const logger = require('logger-sharelatex')
+
+module.exports = {
+ getDocument(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const { doc_id } = req.params
+ const plain =
+ __guard__(req != null ? req.query : undefined, x => x.plain) === 'true'
+ logger.log(
+ { doc_id, project_id },
+ 'receiving get document request from api (docupdater)'
+ )
+ return ProjectGetter.getProject(
+ project_id,
+ { rootFolder: true, overleaf: true },
+ function(error, project) {
+ if (error != null) {
+ return next(error)
+ }
+ if (project == null) {
+ return res.sendStatus(404)
+ }
+ return ProjectLocator.findElement(
+ { project, element_id: doc_id, type: 'doc' },
+ function(error, doc, path) {
+ if (error != null) {
+ logger.err(
+ { err: error, doc_id, project_id },
+ 'error finding element for getDocument'
+ )
+ return next(error)
+ }
+ return ProjectEntityHandler.getDoc(project_id, doc_id, function(
+ error,
+ lines,
+ rev,
+ version,
+ ranges
+ ) {
+ if (error != null) {
+ logger.err(
+ { err: error, doc_id, project_id },
+ 'error finding doc contents for getDocument'
+ )
+ return next(error)
+ }
+ if (plain) {
+ res.type('text/plain')
+ return res.send(lines.join('\n'))
+ } else {
+ const projectHistoryId = __guard__(
+ __guard__(
+ project != null ? project.overleaf : undefined,
+ x2 => x2.history
+ ),
+ x1 => x1.id
+ )
+ return res.json({
+ lines,
+ version,
+ ranges,
+ pathname: path.fileSystem,
+ projectHistoryId
+ })
+ }
+ })
+ }
+ )
+ }
+ )
+ },
+
+ setDocument(req, res, next) {
+ if (next == null) {
+ next = function(error) {}
+ }
+ const project_id = req.params.Project_id
+ const { doc_id } = req.params
+ const { lines, version, ranges, lastUpdatedAt, lastUpdatedBy } = req.body
+ logger.log(
+ { doc_id, project_id },
+ 'receiving set document request from api (docupdater)'
+ )
+ return ProjectEntityUpdateHandler.updateDocLines(
+ project_id,
+ doc_id,
+ lines,
+ version,
+ ranges,
+ lastUpdatedAt,
+ lastUpdatedBy,
+ function(error) {
+ if (error != null) {
+ logger.err(
+ { err: error, doc_id, project_id },
+ 'error finding element for getDocument'
+ )
+ return next(error)
+ }
+ logger.log(
+ { doc_id, project_id },
+ 'finished receiving set document request from api (docupdater)'
+ )
+ return res.sendStatus(200)
+ }
+ )
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/src/Features/Documents/DocumentHelper.js b/services/web/app/src/Features/Documents/DocumentHelper.js
new file mode 100644
index 0000000000..fd0d67a6f7
--- /dev/null
+++ b/services/web/app/src/Features/Documents/DocumentHelper.js
@@ -0,0 +1,78 @@
+/* eslint-disable
+ max-len,
+ no-cond-assign,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let DocumentHelper
+module.exports = DocumentHelper = {
+ getTitleFromTexContent(content, maxContentToScan) {
+ if (maxContentToScan == null) {
+ maxContentToScan = 30000
+ }
+ const TITLE_WITH_CURLY_BRACES = /\\[tT]itle\*?\s*{([^}]+)}/
+ const TITLE_WITH_SQUARE_BRACES = /\\[tT]itle\s*\[([^\]]+)\]/
+ for (let line of Array.from(
+ DocumentHelper._getLinesFromContent(content, maxContentToScan)
+ )) {
+ var match
+ if (
+ (match =
+ line.match(TITLE_WITH_CURLY_BRACES) ||
+ line.match(TITLE_WITH_SQUARE_BRACES))
+ ) {
+ return DocumentHelper.detex(match[1])
+ }
+ }
+
+ return null
+ },
+
+ contentHasDocumentclass(content, maxContentToScan) {
+ if (maxContentToScan == null) {
+ maxContentToScan = 30000
+ }
+ for (let line of Array.from(
+ DocumentHelper._getLinesFromContent(content, maxContentToScan)
+ )) {
+ // We've had problems with this regex locking up CPU.
+ // Previously /.*\\documentclass/ would totally lock up on lines of 500kb (data text files :()
+ // This regex will only look from the start of the line, including whitespace so will return quickly
+ // regardless of line length.
+ if (line.match(/^\s*\\documentclass/)) {
+ return true
+ }
+ }
+
+ return false
+ },
+
+ detex(string) {
+ return string
+ .replace(/\\LaTeX/g, 'LaTeX')
+ .replace(/\\TeX/g, 'TeX')
+ .replace(/\\TikZ/g, 'TikZ')
+ .replace(/\\BibTeX/g, 'BibTeX')
+ .replace(/\\\[[A-Za-z0-9. ]*\]/g, ' ') // line spacing
+ .replace(/\\(?:[a-zA-Z]+|.|)/g, '')
+ .replace(/{}|~/g, ' ')
+ .replace(/[${}]/g, '')
+ .replace(/ +/g, ' ')
+ .trim()
+ },
+
+ _getLinesFromContent(content, maxContentToScan) {
+ if (typeof content === 'string') {
+ return content.substring(0, maxContentToScan).split('\n')
+ } else {
+ return content
+ }
+ }
+}
diff --git a/services/web/app/src/Features/Downloads/ProjectDownloadsController.js b/services/web/app/src/Features/Downloads/ProjectDownloadsController.js
new file mode 100644
index 0000000000..8c8158a8b8
--- /dev/null
+++ b/services/web/app/src/Features/Downloads/ProjectDownloadsController.js
@@ -0,0 +1,82 @@
+/* eslint-disable
+ camelcase,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ProjectDownloadsController
+const logger = require('logger-sharelatex')
+const Metrics = require('metrics-sharelatex')
+const ProjectGetter = require('../Project/ProjectGetter')
+const ProjectZipStreamManager = require('./ProjectZipStreamManager')
+const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
+
+module.exports = ProjectDownloadsController = {
+ downloadProject(req, res, next) {
+ const project_id = req.params.Project_id
+ Metrics.inc('zip-downloads')
+ logger.log({ project_id }, 'downloading project')
+ return DocumentUpdaterHandler.flushProjectToMongo(project_id, function(
+ error
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ return ProjectGetter.getProject(project_id, { name: true }, function(
+ error,
+ project
+ ) {
+ if (error != null) {
+ return next(error)
+ }
+ return ProjectZipStreamManager.createZipStreamForProject(
+ project_id,
+ function(error, stream) {
+ if (error != null) {
+ return next(error)
+ }
+ res.setContentDisposition('attachment', {
+ filename: `${project.name}.zip`
+ })
+ res.contentType('application/zip')
+ return stream.pipe(res)
+ }
+ )
+ })
+ })
+ },
+
+ downloadMultipleProjects(req, res, next) {
+ const project_ids = req.query.project_ids.split(',')
+ Metrics.inc('zip-downloads-multiple')
+ logger.log({ project_ids }, 'downloading multiple projects')
+ return DocumentUpdaterHandler.flushMultipleProjectsToMongo(
+ project_ids,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return ProjectZipStreamManager.createZipStreamForMultipleProjects(
+ project_ids,
+ function(error, stream) {
+ if (error != null) {
+ return next(error)
+ }
+ res.setContentDisposition('attachment', {
+ filename: `Overleaf Projects (${project_ids.length} items).zip`
+ })
+ res.contentType('application/zip')
+ return stream.pipe(res)
+ }
+ )
+ }
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Downloads/ProjectZipStreamManager.js b/services/web/app/src/Features/Downloads/ProjectZipStreamManager.js
new file mode 100644
index 0000000000..ece438fdf7
--- /dev/null
+++ b/services/web/app/src/Features/Downloads/ProjectZipStreamManager.js
@@ -0,0 +1,179 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-undef,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let ProjectZipStreamManager
+const archiver = require('archiver')
+const async = require('async')
+const logger = require('logger-sharelatex')
+const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
+const ProjectGetter = require('../Project/ProjectGetter')
+const FileStoreHandler = require('../FileStore/FileStoreHandler')
+
+module.exports = ProjectZipStreamManager = {
+ createZipStreamForMultipleProjects(project_ids, callback) {
+ // We'll build up a zip file that contains multiple zip files
+
+ if (callback == null) {
+ callback = function(error, stream) {}
+ }
+ const archive = archiver('zip')
+ archive.on('error', err =>
+ logger.err(
+ { err, project_ids },
+ 'something went wrong building archive of project'
+ )
+ )
+ callback(null, archive)
+
+ logger.log({ project_ids }, 'creating zip stream of multiple projects')
+
+ const jobs = []
+ for (let project_id of Array.from(project_ids || [])) {
+ ;(project_id =>
+ jobs.push(callback =>
+ ProjectGetter.getProject(project_id, { name: true }, function(
+ error,
+ project
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ logger.log(
+ { project_id, name: project.name },
+ 'appending project to zip stream'
+ )
+ return ProjectZipStreamManager.createZipStreamForProject(
+ project_id,
+ function(error, stream) {
+ if (error != null) {
+ return callback(error)
+ }
+ archive.append(stream, { name: `${project.name}.zip` })
+ return stream.on('end', function() {
+ logger.log(
+ { project_id, name: project.name },
+ 'zip stream ended'
+ )
+ return callback()
+ })
+ }
+ )
+ })
+ ))(project_id)
+ }
+
+ return async.series(jobs, function() {
+ logger.log(
+ { project_ids },
+ 'finished creating zip stream of multiple projects'
+ )
+ return archive.finalize()
+ })
+ },
+
+ createZipStreamForProject(project_id, callback) {
+ if (callback == null) {
+ callback = function(error, stream) {}
+ }
+ const archive = archiver('zip')
+ // return stream immediately before we start adding things to it
+ archive.on('error', err =>
+ logger.err(
+ { err, project_id },
+ 'something went wrong building archive of project'
+ )
+ )
+ callback(null, archive)
+ return this.addAllDocsToArchive(project_id, archive, error => {
+ if (error != null) {
+ logger.error(
+ { err: error, project_id },
+ 'error adding docs to zip stream'
+ )
+ }
+ return this.addAllFilesToArchive(project_id, archive, error => {
+ if (error != null) {
+ logger.error(
+ { err: error, project_id },
+ 'error adding files to zip stream'
+ )
+ }
+ return archive.finalize()
+ })
+ })
+ },
+
+ addAllDocsToArchive(project_id, archive, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ProjectEntityHandler.getAllDocs(project_id, function(error, docs) {
+ if (error != null) {
+ return callback(error)
+ }
+ const jobs = []
+ for (let path in docs) {
+ const doc = docs[path]
+ ;(function(path, doc) {
+ if (path[0] === '/') {
+ path = path.slice(1)
+ }
+ return jobs.push(function(callback) {
+ logger.log({ project_id }, 'Adding doc')
+ archive.append(doc.lines.join('\n'), { name: path })
+ return callback()
+ })
+ })(path, doc)
+ }
+ return async.series(jobs, callback)
+ })
+ },
+
+ addAllFilesToArchive(project_id, archive, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return ProjectEntityHandler.getAllFiles(project_id, function(error, files) {
+ if (error != null) {
+ return callback(error)
+ }
+ const jobs = []
+ for (let path in files) {
+ const file = files[path]
+ ;((path, file) =>
+ jobs.push(callback =>
+ FileStoreHandler.getFileStream(project_id, file._id, {}, function(
+ error,
+ stream
+ ) {
+ if (error != null) {
+ logger.err(
+ { err: error, project_id, file_id: file._id },
+ 'something went wrong adding file to zip archive'
+ )
+ return callback(err)
+ }
+ if (path[0] === '/') {
+ path = path.slice(1)
+ }
+ archive.append(stream, { name: path })
+ return stream.on('end', () => callback())
+ })
+ ))(path, file)
+ }
+ return async.parallelLimit(jobs, 5, callback)
+ })
+ }
+}
diff --git a/services/web/app/src/Features/Editor/EditorController.js b/services/web/app/src/Features/Editor/EditorController.js
new file mode 100644
index 0000000000..4a62c4c1e8
--- /dev/null
+++ b/services/web/app/src/Features/Editor/EditorController.js
@@ -0,0 +1,727 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-dupe-keys,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let EditorController
+const logger = require('logger-sharelatex')
+const Metrics = require('metrics-sharelatex')
+const sanitize = require('sanitizer')
+const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
+const ProjectOptionsHandler = require('../Project/ProjectOptionsHandler')
+const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
+const ProjectDeleter = require('../Project/ProjectDeleter')
+const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
+const EditorRealTimeController = require('./EditorRealTimeController')
+const async = require('async')
+const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
+const _ = require('underscore')
+
+module.exports = EditorController = {
+ addDoc(project_id, folder_id, docName, docLines, source, user_id, callback) {
+ if (callback == null) {
+ callback = function(error, doc) {}
+ }
+ return EditorController.addDocWithRanges(
+ project_id,
+ folder_id,
+ docName,
+ docLines,
+ {},
+ source,
+ user_id,
+ callback
+ )
+ },
+
+ addDocWithRanges(
+ project_id,
+ folder_id,
+ docName,
+ docLines,
+ docRanges,
+ source,
+ user_id,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error, doc) {}
+ }
+ docName = docName.trim()
+ logger.log(
+ { project_id, folder_id, docName, source },
+ 'sending new doc to project'
+ )
+ Metrics.inc('editor.add-doc')
+ return ProjectEntityUpdateHandler.addDocWithRanges(
+ project_id,
+ folder_id,
+ docName,
+ docLines,
+ docRanges,
+ user_id,
+ (err, doc, folder_id) => {
+ if (err != null) {
+ logger.err(
+ { err, project_id, docName },
+ 'error adding doc without lock'
+ )
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewDoc',
+ folder_id,
+ doc,
+ source
+ )
+ return callback(err, doc)
+ }
+ )
+ },
+
+ addFile(
+ project_id,
+ folder_id,
+ fileName,
+ fsPath,
+ linkedFileData,
+ source,
+ user_id,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(error, file) {}
+ }
+ fileName = fileName.trim()
+ logger.log(
+ {
+ project_id,
+ folder_id,
+ fileName,
+ fsPath,
+ linkedFileData,
+ source,
+ user_id
+ },
+ 'sending new file to project'
+ )
+ Metrics.inc('editor.add-file')
+ return ProjectEntityUpdateHandler.addFile(
+ project_id,
+ folder_id,
+ fileName,
+ fsPath,
+ linkedFileData,
+ user_id,
+ (err, fileRef, folder_id) => {
+ if (err != null) {
+ logger.err(
+ { err, project_id, folder_id, fileName },
+ 'error adding file without lock'
+ )
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewFile',
+ folder_id,
+ fileRef,
+ source,
+ linkedFileData
+ )
+ return callback(err, fileRef)
+ }
+ )
+ },
+
+ upsertDoc(
+ project_id,
+ folder_id,
+ docName,
+ docLines,
+ source,
+ user_id,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectEntityUpdateHandler.upsertDoc(
+ project_id,
+ folder_id,
+ docName,
+ docLines,
+ source,
+ user_id,
+ function(err, doc, didAddNewDoc) {
+ if (didAddNewDoc) {
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewDoc',
+ folder_id,
+ doc,
+ source
+ )
+ }
+ return callback(err, doc)
+ }
+ )
+ },
+
+ upsertFile(
+ project_id,
+ folder_id,
+ fileName,
+ fsPath,
+ linkedFileData,
+ source,
+ user_id,
+ callback
+ ) {
+ if (callback == null) {
+ callback = function(err, file) {}
+ }
+ return ProjectEntityUpdateHandler.upsertFile(
+ project_id,
+ folder_id,
+ fileName,
+ fsPath,
+ linkedFileData,
+ user_id,
+ function(err, newFile, didAddFile, existingFile) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (!didAddFile) {
+ // replacement, so remove the existing file from the client
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'removeEntity',
+ existingFile._id,
+ source
+ )
+ }
+ // now add the new file on the client
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewFile',
+ folder_id,
+ newFile,
+ source,
+ linkedFileData
+ )
+ return callback(null, newFile)
+ }
+ )
+ },
+
+ upsertDocWithPath(
+ project_id,
+ elementPath,
+ docLines,
+ source,
+ user_id,
+ callback
+ ) {
+ return ProjectEntityUpdateHandler.upsertDocWithPath(
+ project_id,
+ elementPath,
+ docLines,
+ source,
+ user_id,
+ function(err, doc, didAddNewDoc, newFolders, lastFolder) {
+ if (err != null) {
+ return callback(err)
+ }
+ return EditorController._notifyProjectUsersOfNewFolders(
+ project_id,
+ newFolders,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (didAddNewDoc) {
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewDoc',
+ lastFolder._id,
+ doc,
+ source
+ )
+ }
+ return callback()
+ }
+ )
+ }
+ )
+ },
+
+ upsertFileWithPath(
+ project_id,
+ elementPath,
+ fsPath,
+ linkedFileData,
+ source,
+ user_id,
+ callback
+ ) {
+ return ProjectEntityUpdateHandler.upsertFileWithPath(
+ project_id,
+ elementPath,
+ fsPath,
+ linkedFileData,
+ user_id,
+ function(err, newFile, didAddFile, existingFile, newFolders, lastFolder) {
+ if (err != null) {
+ return callback(err)
+ }
+ return EditorController._notifyProjectUsersOfNewFolders(
+ project_id,
+ newFolders,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (!didAddFile) {
+ // replacement, so remove the existing file from the client
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'removeEntity',
+ existingFile._id,
+ source
+ )
+ }
+ // now add the new file on the client
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewFile',
+ lastFolder._id,
+ newFile,
+ source,
+ linkedFileData
+ )
+ return callback()
+ }
+ )
+ }
+ )
+ },
+
+ addFolder(project_id, folder_id, folderName, source, callback) {
+ if (callback == null) {
+ callback = function(error, folder) {}
+ }
+ folderName = folderName.trim()
+ logger.log(
+ { project_id, folder_id, folderName, source },
+ 'sending new folder to project'
+ )
+ Metrics.inc('editor.add-folder')
+ return ProjectEntityUpdateHandler.addFolder(
+ project_id,
+ folder_id,
+ folderName,
+ (err, folder, folder_id) => {
+ if (err != null) {
+ logger.err(
+ { err, project_id, folder_id, folderName, source },
+ 'could not add folder'
+ )
+ return callback(err)
+ }
+ return EditorController._notifyProjectUsersOfNewFolder(
+ project_id,
+ folder_id,
+ folder,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback(null, folder)
+ }
+ )
+ }
+ )
+ },
+
+ mkdirp(project_id, path, callback) {
+ if (callback == null) {
+ callback = function(error, newFolders, lastFolder) {}
+ }
+ logger.log({ project_id, path }, "making directories if they don't exist")
+ return ProjectEntityUpdateHandler.mkdirp(
+ project_id,
+ path,
+ (err, newFolders, lastFolder) => {
+ if (err != null) {
+ logger.err({ err, project_id, path }, 'could not mkdirp')
+ return callback(err)
+ }
+
+ return EditorController._notifyProjectUsersOfNewFolders(
+ project_id,
+ newFolders,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ return callback(null, newFolders, lastFolder)
+ }
+ )
+ }
+ )
+ },
+
+ deleteEntity(project_id, entity_id, entityType, source, userId, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log(
+ { project_id, entity_id, entityType, source },
+ 'start delete process of entity'
+ )
+ Metrics.inc('editor.delete-entity')
+ return ProjectEntityUpdateHandler.deleteEntity(
+ project_id,
+ entity_id,
+ entityType,
+ userId,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { err, project_id, entity_id, entityType },
+ 'could not delete entity'
+ )
+ return callback(err)
+ }
+ logger.log(
+ { project_id, entity_id, entityType },
+ 'telling users entity has been deleted'
+ )
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'removeEntity',
+ entity_id,
+ source
+ )
+ return callback()
+ }
+ )
+ },
+
+ deleteEntityWithPath(project_id, path, source, user_id, callback) {
+ return ProjectEntityUpdateHandler.deleteEntityWithPath(
+ project_id,
+ path,
+ user_id,
+ function(err, entity_id) {
+ if (err != null) {
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'removeEntity',
+ entity_id,
+ source
+ )
+ return callback(null, entity_id)
+ }
+ )
+ },
+
+ notifyUsersProjectHasBeenDeletedOrRenamed(project_id, callback) {
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'projectRenamedOrDeletedByExternalSource'
+ )
+ return callback()
+ },
+
+ updateProjectDescription(project_id, description, callback) {
+ if (callback == null) {
+ callback = function() {}
+ }
+ logger.log({ project_id, description }, 'updating project description')
+ return ProjectDetailsHandler.setProjectDescription(
+ project_id,
+ description,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { err, project_id, description },
+ 'something went wrong setting the project description'
+ )
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'projectDescriptionUpdated',
+ description
+ )
+ return callback()
+ }
+ )
+ },
+
+ deleteProject(project_id, callback) {
+ Metrics.inc('editor.delete-project')
+ logger.log({ project_id }, 'recived message to delete project')
+ return ProjectDeleter.deleteProject(project_id, callback)
+ },
+
+ renameEntity(project_id, entity_id, entityType, newName, userId, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ newName = sanitize.escape(newName)
+ Metrics.inc('editor.rename-entity')
+ logger.log(
+ { entity_id, entity_id, entity_id },
+ 'reciving new name for entity for project'
+ )
+ return ProjectEntityUpdateHandler.renameEntity(
+ project_id,
+ entity_id,
+ entityType,
+ newName,
+ userId,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { err, project_id, entity_id, entityType, newName },
+ 'error renaming entity'
+ )
+ return callback(err)
+ }
+ if (newName.length > 0) {
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveEntityRename',
+ entity_id,
+ newName
+ )
+ }
+ return callback()
+ }
+ )
+ },
+
+ moveEntity(project_id, entity_id, folder_id, entityType, userId, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ Metrics.inc('editor.move-entity')
+ return ProjectEntityUpdateHandler.moveEntity(
+ project_id,
+ entity_id,
+ folder_id,
+ entityType,
+ userId,
+ function(err) {
+ if (err != null) {
+ logger.err(
+ { err, project_id, entity_id, folder_id },
+ 'error moving entity'
+ )
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveEntityMove',
+ entity_id,
+ folder_id
+ )
+ return callback()
+ }
+ )
+ },
+
+ renameProject(project_id, newName, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectDetailsHandler.renameProject(project_id, newName, function(
+ err
+ ) {
+ if (err != null) {
+ logger.err({ err, project_id, newName }, 'error renaming project')
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'projectNameUpdated',
+ newName
+ )
+ return callback()
+ })
+ },
+
+ setCompiler(project_id, compiler, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectOptionsHandler.setCompiler(project_id, compiler, function(
+ err
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ logger.log({ compiler, project_id }, 'setting compiler')
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'compilerUpdated',
+ compiler
+ )
+ return callback()
+ })
+ },
+
+ setImageName(project_id, imageName, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectOptionsHandler.setImageName(project_id, imageName, function(
+ err
+ ) {
+ if (err != null) {
+ return callback(err)
+ }
+ logger.log({ imageName, project_id }, 'setting imageName')
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'imageNameUpdated',
+ imageName
+ )
+ return callback()
+ })
+ },
+
+ setSpellCheckLanguage(project_id, languageCode, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectOptionsHandler.setSpellCheckLanguage(
+ project_id,
+ languageCode,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ logger.log(
+ { languageCode, project_id },
+ 'setting languageCode for spell check'
+ )
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'spellCheckLanguageUpdated',
+ languageCode
+ )
+ return callback()
+ }
+ )
+ },
+
+ setPublicAccessLevel(project_id, newAccessLevel, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectDetailsHandler.setPublicAccessLevel(
+ project_id,
+ newAccessLevel,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'project:publicAccessLevel:changed',
+ { newAccessLevel }
+ )
+ if (newAccessLevel === PublicAccessLevels.TOKEN_BASED) {
+ return ProjectDetailsHandler.ensureTokensArePresent(
+ project_id,
+ function(err, tokens) {
+ if (err != null) {
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'project:tokens:changed',
+ { tokens }
+ )
+ return callback()
+ }
+ )
+ } else {
+ return callback()
+ }
+ }
+ )
+ },
+
+ setRootDoc(project_id, newRootDocID, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ return ProjectEntityUpdateHandler.setRootDoc(
+ project_id,
+ newRootDocID,
+ function(err) {
+ if (err != null) {
+ return callback(err)
+ }
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'rootDocUpdated',
+ newRootDocID
+ )
+ return callback()
+ }
+ )
+ },
+
+ _notifyProjectUsersOfNewFolders(project_id, folders, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ return async.eachSeries(
+ folders,
+ (folder, cb) =>
+ EditorController._notifyProjectUsersOfNewFolder(
+ project_id,
+ folder.parentFolder_id,
+ folder,
+ cb
+ ),
+ callback
+ )
+ },
+
+ _notifyProjectUsersOfNewFolder(project_id, folder_id, folder, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log(
+ { project_id, folder, parentFolder_id: folder_id },
+ 'sending newly created folder out to users'
+ )
+ EditorRealTimeController.emitToRoom(
+ project_id,
+ 'reciveNewFolder',
+ folder_id,
+ folder
+ )
+ return callback()
+ }
+}
diff --git a/services/web/app/src/Features/Editor/EditorHttpController.js b/services/web/app/src/Features/Editor/EditorHttpController.js
new file mode 100644
index 0000000000..75a27449a6
--- /dev/null
+++ b/services/web/app/src/Features/Editor/EditorHttpController.js
@@ -0,0 +1,283 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let EditorHttpController
+const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
+const ProjectDeleter = require('../Project/ProjectDeleter')
+const logger = require('logger-sharelatex')
+const EditorRealTimeController = require('./EditorRealTimeController')
+const EditorController = require('./EditorController')
+const ProjectGetter = require('../Project/ProjectGetter')
+const UserGetter = require('../User/UserGetter')
+const AuthorizationManager = require('../Authorization/AuthorizationManager')
+const ProjectEditorHandler = require('../Project/ProjectEditorHandler')
+const Metrics = require('metrics-sharelatex')
+const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
+const CollaboratorsInviteHandler = require('../Collaborators/CollaboratorsInviteHandler')
+const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
+const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+
+module.exports = EditorHttpController = {
+ joinProject(req, res, next) {
+ const project_id = req.params.Project_id
+ let { user_id } = req.query
+ if (user_id === 'anonymous-user') {
+ user_id = null
+ }
+ logger.log({ user_id, project_id }, 'join project request')
+ Metrics.inc('editor.join-project')
+ return EditorHttpController._buildJoinProjectView(
+ req,
+ project_id,
+ user_id,
+ function(error, project, privilegeLevel) {
+ if (error != null) {
+ return next(error)
+ }
+ // Hide access tokens if this is not the project owner
+ TokenAccessHandler.protectTokens(project, privilegeLevel)
+ res.json({
+ project,
+ privilegeLevel
+ })
+ // Only show the 'renamed or deleted' message once
+ if (project != null ? project.deletedByExternalDataSource : undefined) {
+ return ProjectDeleter.unmarkAsDeletedByExternalSource(project_id)
+ }
+ }
+ )
+ },
+
+ _buildJoinProjectView(req, project_id, user_id, callback) {
+ if (callback == null) {
+ callback = function(error, project, privilegeLevel) {}
+ }
+ logger.log({ project_id, user_id }, 'building the joinProject view')
+ return ProjectGetter.getProjectWithoutDocLines(project_id, function(
+ error,
+ project
+ ) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (project == null) {
+ return callback(new Error('not found'))
+ }
+ return CollaboratorsHandler.getInvitedMembersWithPrivilegeLevels(
+ project_id,
+ function(error, members) {
+ if (error != null) {
+ return callback(error)
+ }
+ const token = TokenAccessHandler.getRequestToken(req, project_id)
+ return AuthorizationManager.getPrivilegeLevelForProject(
+ user_id,
+ project_id,
+ token,
+ function(error, privilegeLevel) {
+ if (error != null) {
+ return callback(error)
+ }
+ if (
+ privilegeLevel == null ||
+ privilegeLevel === PrivilegeLevels.NONE
+ ) {
+ logger.log(
+ { project_id, user_id, privilegeLevel },
+ 'not an acceptable privilege level, returning null'
+ )
+ return callback(null, null, false)
+ }
+ return CollaboratorsInviteHandler.getAllInvites(
+ project_id,
+ function(error, invites) {
+ if (error != null) {
+ return callback(error)
+ }
+ logger.log(
+ {
+ project_id,
+ user_id,
+ memberCount: members.length,
+ inviteCount: invites.length,
+ privilegeLevel
+ },
+ 'returning project model view'
+ )
+ return callback(
+ null,
+ ProjectEditorHandler.buildProjectModelView(
+ project,
+ members,
+ invites
+ ),
+ privilegeLevel
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+ })
+ },
+
+ _nameIsAcceptableLength(name) {
+ return name != null && name.length < 150 && name.length !== 0
+ },
+
+ addDoc(req, res, next) {
+ const project_id = req.params.Project_id
+ const { name } = req.body
+ const { parent_folder_id } = req.body
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ logger.log(
+ { project_id, name, parent_folder_id },
+ 'getting request to add doc to project'
+ )
+ if (!EditorHttpController._nameIsAcceptableLength(name)) {
+ return res.sendStatus(400)
+ }
+ return EditorController.addDoc(
+ project_id,
+ parent_folder_id,
+ name,
+ [],
+ 'editor',
+ user_id,
+ function(error, doc) {
+ if (error === 'project_has_to_many_files') {
+ return res
+ .status(400)
+ .json(req.i18n.translate('project_has_to_many_files'))
+ } else if (error != null) {
+ return next(error)
+ } else {
+ return res.json(doc)
+ }
+ }
+ )
+ },
+
+ addFolder(req, res, next) {
+ const project_id = req.params.Project_id
+ const { name } = req.body
+ const { parent_folder_id } = req.body
+ if (!EditorHttpController._nameIsAcceptableLength(name)) {
+ return res.sendStatus(400)
+ }
+ return EditorController.addFolder(
+ project_id,
+ parent_folder_id,
+ name,
+ 'editor',
+ function(error, doc) {
+ if (error === 'project_has_to_many_files') {
+ return res
+ .status(400)
+ .json(req.i18n.translate('project_has_to_many_files'))
+ } else if (
+ (error != null ? error.message : undefined) === 'invalid element name'
+ ) {
+ return res.status(400).json(req.i18n.translate('invalid_file_name'))
+ } else if (error != null) {
+ return next(error)
+ } else {
+ return res.json(doc)
+ }
+ }
+ )
+ },
+
+ renameEntity(req, res, next) {
+ const project_id = req.params.Project_id
+ const { entity_id } = req.params
+ const { entity_type } = req.params
+ const { name } = req.body
+ if (!EditorHttpController._nameIsAcceptableLength(name)) {
+ return res.sendStatus(400)
+ }
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return EditorController.renameEntity(
+ project_id,
+ entity_id,
+ entity_type,
+ name,
+ user_id,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.sendStatus(204)
+ }
+ )
+ },
+
+ moveEntity(req, res, next) {
+ const project_id = req.params.Project_id
+ const { entity_id } = req.params
+ const { entity_type } = req.params
+ const { folder_id } = req.body
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return EditorController.moveEntity(
+ project_id,
+ entity_id,
+ folder_id,
+ entity_type,
+ user_id,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.sendStatus(204)
+ }
+ )
+ },
+
+ deleteDoc(req, res, next) {
+ req.params.entity_type = 'doc'
+ return EditorHttpController.deleteEntity(req, res, next)
+ },
+
+ deleteFile(req, res, next) {
+ req.params.entity_type = 'file'
+ return EditorHttpController.deleteEntity(req, res, next)
+ },
+
+ deleteFolder(req, res, next) {
+ req.params.entity_type = 'folder'
+ return EditorHttpController.deleteEntity(req, res, next)
+ },
+
+ deleteEntity(req, res, next) {
+ const project_id = req.params.Project_id
+ const { entity_id } = req.params
+ const { entity_type } = req.params
+ const user_id = AuthenticationController.getLoggedInUserId(req)
+ return EditorController.deleteEntity(
+ project_id,
+ entity_id,
+ entity_type,
+ 'editor',
+ user_id,
+ function(error) {
+ if (error != null) {
+ return next(error)
+ }
+ return res.sendStatus(204)
+ }
+ )
+ }
+}
diff --git a/services/web/app/src/Features/Editor/EditorRealTimeController.js b/services/web/app/src/Features/Editor/EditorRealTimeController.js
new file mode 100644
index 0000000000..c5152ae0af
--- /dev/null
+++ b/services/web/app/src/Features/Editor/EditorRealTimeController.js
@@ -0,0 +1,43 @@
+/* eslint-disable
+ camelcase,
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let EditorRealTimeController
+const Settings = require('settings-sharelatex')
+const RedisWrapper = require('../../infrastructure/RedisWrapper')
+const rclient = RedisWrapper.client('realtime')
+const os = require('os')
+const crypto = require('crypto')
+
+const HOST = os.hostname()
+const RND = crypto.randomBytes(4).toString('hex') // generate a random key for this process
+let COUNT = 0
+
+module.exports = EditorRealTimeController = {
+ emitToRoom(room_id, message, ...payload) {
+ // create a unique message id using a counter
+ const message_id = `web:${HOST}:${RND}-${COUNT++}`
+ return rclient.publish(
+ 'editor-events',
+ JSON.stringify({
+ room_id,
+ message,
+ payload,
+ _id: message_id
+ })
+ )
+ },
+
+ emitToAll(message, ...payload) {
+ return this.emitToRoom('all', message, ...Array.from(payload))
+ }
+}
diff --git a/services/web/app/src/Features/Editor/EditorRouter.js b/services/web/app/src/Features/Editor/EditorRouter.js
new file mode 100644
index 0000000000..5b775af392
--- /dev/null
+++ b/services/web/app/src/Features/Editor/EditorRouter.js
@@ -0,0 +1,83 @@
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const EditorHttpController = require('./EditorHttpController')
+const AuthenticationController = require('../Authentication/AuthenticationController')
+const AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
+const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
+
+module.exports = {
+ apply(webRouter, apiRouter) {
+ webRouter.post(
+ '/project/:Project_id/doc',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'add-doc-to-project',
+ params: ['Project_id'],
+ maxRequests: 30,
+ timeInterval: 60
+ }),
+ EditorHttpController.addDoc
+ )
+ webRouter.post(
+ '/project/:Project_id/folder',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'add-folder-to-project',
+ params: ['Project_id'],
+ maxRequests: 60,
+ timeInterval: 60
+ }),
+ EditorHttpController.addFolder
+ )
+
+ webRouter.post(
+ '/project/:Project_id/:entity_type/:entity_id/rename',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ EditorHttpController.renameEntity
+ )
+ webRouter.post(
+ '/project/:Project_id/:entity_type/:entity_id/move',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ EditorHttpController.moveEntity
+ )
+
+ webRouter.delete(
+ '/project/:Project_id/file/:entity_id',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ EditorHttpController.deleteFile
+ )
+ webRouter.delete(
+ '/project/:Project_id/doc/:entity_id',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ EditorHttpController.deleteDoc
+ )
+ webRouter.delete(
+ '/project/:Project_id/folder/:entity_id',
+ AuthorizationMiddleware.ensureUserCanWriteProjectContent,
+ EditorHttpController.deleteFolder
+ )
+
+ // Called by the real-time API to load up the current project state.
+ // This is a post request because it's more than just a getting of data. We take actions
+ // whenever a user joins a project, like updating the deleted status.
+ return apiRouter.post(
+ '/project/:Project_id/join',
+ AuthenticationController.httpAuth,
+ RateLimiterMiddleware.rateLimit({
+ endpointName: 'join-project',
+ params: ['Project_id'],
+ maxRequests: 30,
+ timeInterval: 60
+ }),
+ EditorHttpController.joinProject
+ )
+ }
+}
diff --git a/services/web/app/coffee/Features/Email/Bodies/SingleCTAEmailBody.coffee b/services/web/app/src/Features/Email/Bodies/SingleCTAEmailBody.js
similarity index 96%
rename from services/web/app/coffee/Features/Email/Bodies/SingleCTAEmailBody.coffee
rename to services/web/app/src/Features/Email/Bodies/SingleCTAEmailBody.js
index eb36869a2c..296f21ce09 100644
--- a/services/web/app/coffee/Features/Email/Bodies/SingleCTAEmailBody.coffee
+++ b/services/web/app/src/Features/Email/Bodies/SingleCTAEmailBody.js
@@ -1,7 +1,13 @@
-_ = require("underscore")
-settings = require "settings-sharelatex"
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+const _ = require('underscore')
+const settings = require('settings-sharelatex')
-module.exports = _.template """
+module.exports = _.template(`\
<% if (title) { %>
@@ -56,5 +62,5 @@ module.exports = _.template """
})
%>
-<% } %>
-"""
+<% } %>\
+`)
diff --git a/services/web/app/coffee/Features/Email/Bodies/sl-SingleCTAEmailBody.coffee b/services/web/app/src/Features/Email/Bodies/sl-SingleCTAEmailBody.js
similarity index 96%
rename from services/web/app/coffee/Features/Email/Bodies/sl-SingleCTAEmailBody.coffee
rename to services/web/app/src/Features/Email/Bodies/sl-SingleCTAEmailBody.js
index 192f572beb..2a4e2aaa1e 100644
--- a/services/web/app/coffee/Features/Email/Bodies/sl-SingleCTAEmailBody.coffee
+++ b/services/web/app/src/Features/Email/Bodies/sl-SingleCTAEmailBody.js
@@ -1,7 +1,13 @@
-_ = require("underscore")
-settings = require "settings-sharelatex"
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+const _ = require('underscore')
+const settings = require('settings-sharelatex')
-module.exports = _.template """
+module.exports = _.template(`\
|
<% if (title) { %>
@@ -54,5 +60,5 @@ module.exports = _.template """
"description": "<%= gmailGoToAction.description %>"
}
-<% } %>
-"""
+<% } %>\
+`)
diff --git a/services/web/app/src/Features/Email/EmailBuilder.js b/services/web/app/src/Features/Email/EmailBuilder.js
new file mode 100644
index 0000000000..a438c3ad56
--- /dev/null
+++ b/services/web/app/src/Features/Email/EmailBuilder.js
@@ -0,0 +1,466 @@
+/* eslint-disable
+ max-len,
+ no-unused-vars,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const _ = require('underscore')
+const settings = require('settings-sharelatex')
+const marked = require('marked')
+const StringHelper = require('../Helpers/StringHelper')
+
+const PersonalEmailLayout = require('./Layouts/PersonalEmailLayout')
+const NotificationEmailLayout = require('./Layouts/NotificationEmailLayout')
+const BaseWithHeaderEmailLayout = require(`./Layouts/${
+ settings.brandPrefix
+}BaseWithHeaderEmailLayout`)
+const SpamSafe = require('./SpamSafe')
+
+const SingleCTAEmailBody = require(`./Bodies/${
+ settings.brandPrefix
+}SingleCTAEmailBody`)
+
+const CTAEmailTemplate = function(content) {
+ if (content.greeting == null) {
+ content.greeting = () => 'Hi,'
+ }
+ if (content.secondaryMessage == null) {
+ content.secondaryMessage = () => ''
+ }
+ return {
+ subject(opts) {
+ return content.subject(opts)
+ },
+ layout: BaseWithHeaderEmailLayout,
+ plainTextTemplate(opts) {
+ return `\
+${content.greeting(opts)}
+
+${content.message(opts).trim()}
+
+${content.ctaText(opts)}: ${content.ctaURL(opts)}
+
+${(typeof content.secondaryMessage === 'function'
+ ? content.secondaryMessage(opts).trim()
+ : undefined) || ''}
+
+Regards,
+The ${settings.appName} Team - ${settings.siteUrl}\
+`
+ },
+ compiledTemplate(opts) {
+ return SingleCTAEmailBody({
+ title:
+ typeof content.title === 'function' ? content.title(opts) : undefined,
+ greeting: content.greeting(opts),
+ message: marked(content.message(opts).trim()),
+ secondaryMessage: marked(content.secondaryMessage(opts).trim()),
+ ctaText: content.ctaText(opts),
+ ctaURL: content.ctaURL(opts),
+ gmailGoToAction:
+ typeof content.gmailGoToAction === 'function'
+ ? content.gmailGoToAction(opts)
+ : undefined,
+ StringHelper
+ })
+ }
+ }
+}
+
+const templates = {}
+
+templates.accountMergeToOverleafAddress = CTAEmailTemplate({
+ subject() {
+ return `Confirm Account Merge - ${settings.appName}`
+ },
+ title() {
+ return 'Confirm Account Merge'
+ },
+ message() {
+ return `\
+To merge your ShareLaTeX and Overleaf accounts, click the button below.
+If you think you have received this message in error,
+please contact us at https://www.overleaf.com/contact\
+`
+ },
+ ctaText() {
+ return 'Confirm Account Merge'
+ },
+ ctaURL(opts) {
+ return opts.tokenLinkUrl
+ }
+})
+
+templates.accountMergeToSharelatexAddress =
+ templates.accountMergeToOverleafAddress
+
+templates.registered = CTAEmailTemplate({
+ subject() {
+ return `Activate your ${settings.appName} Account`
+ },
+ message(opts) {
+ return `\
+Congratulations, you've just had an account created for you on ${
+ settings.appName
+ } with the email address '${_.escape(opts.to)}'.
+
+Click here to set your password and log in:\
+`
+ },
+ secondaryMessage() {
+ return `If you have any questions or problems, please contact ${
+ settings.adminEmail
+ }`
+ },
+ ctaText() {
+ return 'Set password'
+ },
+ ctaURL(opts) {
+ return opts.setNewPasswordUrl
+ }
+})
+
+templates.canceledSubscription = CTAEmailTemplate({
+ subject() {
+ return `${settings.appName} thoughts`
+ },
+ message() {
+ return `\
+I'm sorry to see you cancelled your ${
+ settings.appName
+ } premium account. Would you mind giving us some feedback on what the site is lacking at the moment via this quick survey?\
+`
+ },
+ secondaryMessage() {
+ return 'Thank you in advance!'
+ },
+ ctaText() {
+ return 'Leave Feedback'
+ },
+ ctaURL(opts) {
+ return 'https://docs.google.com/forms/d/e/1FAIpQLScqU6Je1r4Afz6ul6oY0RAfN7RabdWv_oL1u7Rj1YBmXS4fiQ/viewform?usp=sf_link'
+ }
+})
+
+templates.reactivatedSubscription = CTAEmailTemplate({
+ subject() {
+ return `Subscription Reactivated - ${settings.appName}`
+ },
+ message(opts) {
+ return `\
+Your subscription was reactivated successfully.\
+`
+ },
+ ctaText() {
+ return 'View Subscription Dashboard'
+ },
+ ctaURL(opts) {
+ return `${settings.siteUrl}/user/subscription`
+ }
+})
+
+templates.passwordResetRequested = CTAEmailTemplate({
+ subject() {
+ return `Password Reset - ${settings.appName}`
+ },
+ title() {
+ return 'Password Reset'
+ },
+ message() {
+ return `We got a request to reset your ${settings.appName} password.`
+ },
+ secondaryMessage() {
+ return `\
+If you ignore this message, your password won't be changed.
+
+If you didn't request a password reset, let us know.\
+`
+ },
+ ctaText() {
+ return 'Reset password'
+ },
+ ctaURL(opts) {
+ return opts.setNewPasswordUrl
+ }
+})
+
+templates.confirmEmail = CTAEmailTemplate({
+ subject() {
+ return `Confirm Email - ${settings.appName}`
+ },
+ title() {
+ return 'Confirm Email'
+ },
+ message() {
+ return `Please confirm your email on ${settings.appName}.`
+ },
+ ctaText() {
+ return 'Confirm Email'
+ },
+ ctaURL(opts) {
+ return opts.confirmEmailUrl
+ }
+})
+
+templates.projectInvite = CTAEmailTemplate({
+ subject(opts) {
+ return `${_.escape(
+ SpamSafe.safeProjectName(opts.project.name, 'New Project')
+ )} - shared by ${_.escape(
+ SpamSafe.safeEmail(opts.owner.email, 'a collaborator')
+ )}`
+ },
+ title(opts) {
+ return `${_.escape(
+ SpamSafe.safeProjectName(opts.project.name, 'New Project')
+ )} - shared by ${_.escape(
+ SpamSafe.safeEmail(opts.owner.email, 'a collaborator')
+ )}`
+ },
+ message(opts) {
+ return `${_.escape(
+ SpamSafe.safeEmail(opts.owner.email, 'a collaborator')
+ )} wants to share ${_.escape(
+ SpamSafe.safeProjectName(opts.project.name, 'a new project')
+ )} with you.`
+ },
+ ctaText() {
+ return 'View project'
+ },
+ ctaURL(opts) {
+ return opts.inviteUrl
+ },
+ gmailGoToAction(opts) {
+ return {
+ target: opts.inviteUrl,
+ name: 'View project',
+ description: `Join ${_.escape(
+ SpamSafe.safeProjectName(opts.project.name, 'project')
+ )} at ${settings.appName}`
+ }
+ }
+})
+
+templates.verifyEmailToJoinTeam = CTAEmailTemplate({
+ subject(opts) {
+ return `${_.escape(
+ SpamSafe.safeUserName(opts.inviterName, 'A collaborator')
+ )} has invited you to join a team on ${settings.appName}`
+ },
+ title(opts) {
+ return `${_.escape(
+ SpamSafe.safeUserName(opts.inviterName, 'A collaborator')
+ )} has invited you to join a team on ${settings.appName}`
+ },
+ message(opts) {
+ return `Please click the button below to join the team and enjoy the benefits of an upgraded ${
+ settings.appName
+ } account.`
+ },
+ ctaText(opts) {
+ return 'Join now'
+ },
+ ctaURL(opts) {
+ return opts.acceptInviteUrl
+ }
+})
+
+templates.dropboxUnlinkedDuplicate = CTAEmailTemplate({
+ subject() {
+ return `Your Dropbox Account has been Unlinked - ${settings.appName}`
+ },
+ message(opts) {
+ return `\
+Our automated systems have detected that your Dropbox account was linked to more than one Overleaf accounts. This should not have been allowed and might be causing issues with the Dropbox sync feature.
+
+We have now unlinked all your Dropbox and Overleaf Accounts. To ensure your project will keep syncing you can link your Dropbox account to the Overleaf account of your choice now.\
+`
+ },
+ ctaText() {
+ return 'Link Dropbox Account'
+ },
+ ctaURL(opts) {
+ return `${settings.siteUrl}/user/settings`
+ }
+})
+
+templates.testEmail = CTAEmailTemplate({
+ subject() {
+ return `A Test Email from ${settings.appName}`
+ },
+ title() {
+ return `A Test Email from ${settings.appName}`
+ },
+ greeting() {
+ return 'Hi,'
+ },
+ message() {
+ return `This is a test Email from ${settings.appName}`
+ },
+ ctaText() {
+ return `Open ${settings.appName}`
+ },
+ ctaURL() {
+ return settings.siteUrl
+ }
+})
+
+templates.projectsTransferredFromSharelatex = CTAEmailTemplate({
+ subject() {
+ return 'ShareLaTeX projects transferred to your Overleaf account'
+ },
+ title() {
+ return 'ShareLaTeX projects transferred to your Overleaf account'
+ },
+ message(opts) {
+ return `\
+We are writing with important information about your Overleaf and ShareLaTeX accounts.
+
+As part of our ongoing work to [integrate Overleaf and ShareLaTeX](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf),
+we found a ShareLaTeX account with the email address ${
+ opts.to
+ } that matches your Overleaf account.
+
+We have now transferred the projects from this ShareLaTeX account into your Overleaf account, so you may notice some new
+projects on your Overleaf projects page.
+
+When you next log in, you may be prompted to reconfirm your email address in order to regain access to your account.
+If you have any questions, please contact our support team by reply.\
+`
+ },
+ ctaText() {
+ return `Log in to ${settings.appName}`
+ },
+ ctaURL() {
+ return settings.siteUrl + '/login'
+ }
+})
+
+templates.emailAddressPoachedEmail = CTAEmailTemplate({
+ subject() {
+ return `One of your email addresses has been moved to another ${
+ settings.appName
+ } account`
+ },
+ title() {
+ return `One of your email addresses has been moved to another ${
+ settings.appName
+ } account`
+ },
+ message(opts) {
+ let message = `\
+We are writing with important information about your Overleaf account.
+
+You added the email address ${opts.poached} to your ${
+ opts.to
+ } Overleaf account as a secondary (or affiliation)
+email address, but we have had to remove it.
+
+This is because your ${
+ opts.poached
+ } email address was also in use as the primary email address for an older Overleaf
+account from before our [integration with ShareLaTeX to create Overleaf v2](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf).
+
+### What do I need to do?
+
+You now have two Overleaf accounts, one under ${opts.poached} and one under ${
+ opts.to
+ }.
+
+You may wish to log in to Overleaf as ${
+ opts.poached
+ } to check whether you have projects there that you would like to
+keep. If you are not sure of the password, you can send yourself a password reset email to ${
+ opts.poached
+ }, via
+https://www.overleaf.com/user/password/reset
+
+Once you have downloaded your projects, you may wish to delete your
+${
+ opts.poached
+ } Overleaf account, which you can do from your account settings. You will then be able to add
+${opts.poached} as a secondary email address on your ${opts.to} account again.
+
+\
+`
+ if (opts.proFeatures) {
+ message += `\
+Because your ${
+ opts.poached
+ } email address was an institutional affiliation through which you had Pro features. Your Pro
+features have been transferred to your ${
+ opts.poached
+ } account. If you would like to transfer them back to your
+${opts.to} account, you will need to delete the ${
+ opts.poached
+ } account and re-add it as a secondary email address,
+as described above.
+
+\
+`
+ }
+
+ message += `\
+If you have any questions, you can contact our support team by reply.\
+`
+ return message
+ },
+ ctaText() {
+ return `Log in to ${settings.appName}`
+ },
+ ctaURL() {
+ return settings.siteUrl + '/login'
+ }
+})
+
+module.exports = {
+ templates,
+ CTAEmailTemplate,
+ buildEmail(templateName, opts) {
+ const template = templates[templateName]
+ opts.siteUrl = settings.siteUrl
+ opts.body = template.compiledTemplate(opts)
+ if (
+ __guard__(
+ settings.email != null ? settings.email.templates : undefined,
+ x => x.customFooter
+ ) != null
+ ) {
+ opts.body += __guard__(
+ settings.email != null ? settings.email.templates : undefined,
+ x1 => x1.customFooter
+ )
+ }
+ return {
+ subject: template.subject(opts),
+ html: template.layout(opts),
+ text: __guardMethod__(template, 'plainTextTemplate', o =>
+ o.plainTextTemplate(opts)
+ )
+ }
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
+function __guardMethod__(obj, methodName, transform) {
+ if (
+ typeof obj !== 'undefined' &&
+ obj !== null &&
+ typeof obj[methodName] === 'function'
+ ) {
+ return transform(obj, methodName)
+ } else {
+ return undefined
+ }
+}
diff --git a/services/web/app/src/Features/Email/EmailHandler.js b/services/web/app/src/Features/Email/EmailHandler.js
new file mode 100644
index 0000000000..938cd62a96
--- /dev/null
+++ b/services/web/app/src/Features/Email/EmailHandler.js
@@ -0,0 +1,34 @@
+/* eslint-disable
+ handle-callback-err,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const settings = require('settings-sharelatex')
+const EmailBuilder = require('./EmailBuilder')
+const EmailSender = require('./EmailSender')
+
+if (settings.email == null) {
+ settings.email = { lifecycleEnabled: false }
+}
+
+module.exports = {
+ sendEmail(emailType, opts, callback) {
+ if (callback == null) {
+ callback = function(err) {}
+ }
+ const email = EmailBuilder.buildEmail(emailType, opts)
+ if (email.type === 'lifecycle' && !settings.email.lifecycle) {
+ return callback()
+ }
+ opts.html = email.html
+ opts.text = email.text
+ opts.subject = email.subject
+ return EmailSender.sendEmail(opts, err => callback(err))
+ }
+}
diff --git a/services/web/app/src/Features/Email/EmailSender.js b/services/web/app/src/Features/Email/EmailSender.js
new file mode 100644
index 0000000000..8166fc618d
--- /dev/null
+++ b/services/web/app/src/Features/Email/EmailSender.js
@@ -0,0 +1,208 @@
+/* eslint-disable
+ camelcase,
+ handle-callback-err,
+ max-len,
+ no-undef,
+ standard/no-callback-literal,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+let defaultFromAddress, nm_client
+const logger = require('logger-sharelatex')
+const metrics = require('metrics-sharelatex')
+const Settings = require('settings-sharelatex')
+const nodemailer = require('nodemailer')
+const sesTransport = require('nodemailer-ses-transport')
+const sgTransport = require('nodemailer-sendgrid-transport')
+const mandrillTransport = require('nodemailer-mandrill-transport')
+const rateLimiter = require('../../infrastructure/RateLimiter')
+const _ = require('underscore')
+
+if (Settings.email != null && Settings.email.fromAddress != null) {
+ defaultFromAddress = Settings.email.fromAddress
+} else {
+ defaultFromAddress = ''
+}
+
+// provide dummy mailer unless we have a better one configured.
+let client = {
+ sendMail(options, callback) {
+ if (callback == null) {
+ callback = function(err, status) {}
+ }
+ logger.log({ options }, 'Would send email if enabled.')
+ return callback()
+ }
+}
+if (
+ __guard__(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x1 => x1.parameters
+ ),
+ x => x.AWSAccessKeyID
+ ) != null ||
+ __guard__(Settings != null ? Settings.email : undefined, x2 => x2.driver) ===
+ 'ses'
+) {
+ logger.log('using aws ses for email')
+ nm_client = nodemailer.createTransport(
+ sesTransport(Settings.email.parameters)
+ )
+} else if (
+ __guard__(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x4 => x4.parameters
+ ),
+ x3 => x3.sendgridApiKey
+ ) != null
+) {
+ logger.log('using sendgrid for email')
+ nm_client = nodemailer.createTransport(
+ sgTransport({
+ auth: {
+ api_key: __guard__(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x6 => x6.parameters
+ ),
+ x5 => x5.sendgridApiKey
+ )
+ }
+ })
+ )
+} else if (
+ __guard__(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x8 => x8.parameters
+ ),
+ x7 => x7.MandrillApiKey
+ ) != null
+) {
+ logger.log('using mandril for email')
+ nm_client = nodemailer.createTransport(
+ mandrillTransport({
+ auth: {
+ apiKey: __guard__(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x10 => x10.parameters
+ ),
+ x9 => x9.MandrillApiKey
+ )
+ }
+ })
+ )
+} else if (
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x11 => x11.parameters
+ ) != null
+) {
+ logger.log('using smtp for email')
+ const smtp = _.pick(
+ __guard__(
+ Settings != null ? Settings.email : undefined,
+ x12 => x12.parameters
+ ),
+ 'host',
+ 'port',
+ 'secure',
+ 'auth',
+ 'ignoreTLS'
+ )
+ nm_client = nodemailer.createTransport(smtp)
+} else {
+ logger.warn(
+ 'Email transport and/or parameters not defined. No emails will be sent.'
+ )
+ nm_client = client
+}
+
+if (nm_client != null) {
+ client = nm_client
+} else {
+ logger.warn(
+ 'Failed to create email transport. Please check your settings. No email will be sent.'
+ )
+}
+
+const checkCanSendEmail = function(options, callback) {
+ if (options.sendingUser_id == null) {
+ // email not sent from user, not rate limited
+ return callback(null, true)
+ }
+ const opts = {
+ endpointName: 'send_email',
+ timeInterval: 60 * 60 * 3,
+ subjectName: options.sendingUser_id,
+ throttle: 100
+ }
+ return rateLimiter.addCount(opts, callback)
+}
+
+module.exports = {
+ sendEmail(options, callback) {
+ if (callback == null) {
+ callback = function(error) {}
+ }
+ logger.log(
+ { receiver: options.to, subject: options.subject },
+ 'sending email'
+ )
+ return checkCanSendEmail(options, function(err, canContinue) {
+ if (err != null) {
+ return callback(err)
+ }
+ if (!canContinue) {
+ logger.log(
+ {
+ sendingUser_id: options.sendingUser_id,
+ to: options.to,
+ subject: options.subject,
+ canContinue
+ },
+ 'rate limit hit for sending email, not sending'
+ )
+ return callback('rate limit hit sending email')
+ }
+ metrics.inc('email')
+ options = {
+ to: options.to,
+ from: defaultFromAddress,
+ subject: options.subject,
+ html: options.html,
+ text: options.text,
+ replyTo: options.replyTo || Settings.email.replyToAddress,
+ socketTimeout: 30 * 1000
+ }
+ if (Settings.email.textEncoding != null) {
+ opts.textEncoding = textEncoding
+ }
+ return client.sendMail(options, function(err, res) {
+ if (err != null) {
+ logger.err({ err }, 'error sending message')
+ err = new Error('Cannot send email')
+ } else {
+ logger.log(`Message sent to ${options.to}`)
+ }
+ return callback(err)
+ })
+ })
+ }
+}
+
+function __guard__(value, transform) {
+ return typeof value !== 'undefined' && value !== null
+ ? transform(value)
+ : undefined
+}
diff --git a/services/web/app/coffee/Features/Email/Layouts/BaseWithHeaderEmailLayout.coffee b/services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.js
similarity index 96%
rename from services/web/app/coffee/Features/Email/Layouts/BaseWithHeaderEmailLayout.coffee
rename to services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.js
index 280eb2da16..615ef06893 100644
--- a/services/web/app/coffee/Features/Email/Layouts/BaseWithHeaderEmailLayout.coffee
+++ b/services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.js
@@ -1,7 +1,12 @@
-_ = require("underscore")
-settings = require "settings-sharelatex"
+/* eslint-disable
+ max-len,
+*/
+// TODO: This file was created by bulk-decaffeinate.
+// Fix any style issues and re-enable lint.
+const _ = require('underscore')
+const settings = require('settings-sharelatex')
-module.exports = _.template """
+module.exports = _.template(`\
@@ -364,7 +369,11 @@ module.exports = _.template """
|
|---|
@@ -376,5 +385,5 @@ module.exports = _.template """
|
|
|---|
|