Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81164 views
1
(function(global, undefined) {
2
// Defining the `install` function more than once leads to mayhem, so
3
// return immedately if a property called `install` is already defined on
4
// the global object.
5
if (global.install)
6
return;
7
8
// The `installed` object maps absolute module identifiers to module
9
// definitions available for requirement.
10
var installed = {};
11
12
// I make frequent use of `hasOwn.call` to test for the presence of object
13
// properties without traversing the prototype chain.
14
var hasOwn = installed.hasOwnProperty;
15
16
// Anonymous modules are pushed onto a queue so that (when ready) they can
17
// be executed in order of installation.
18
var qhead = {};
19
var qtail = qhead;
20
21
// Define the `install` function globally.
22
global.install = function(id, module) {
23
// To install a named module, pass an absolute module identifier
24
// string followed by a module definition. Note that named modules are
25
// not evaluated until they are required for the first time.
26
if (typeof id === "string" && module) {
27
if (!hasOwn.call(installed, id)) {
28
installed[module.id = id] = module;
29
flushQueue();
30
}
31
// To install an anonymous module, pass a module definition without an
32
// identifier. Anonymous modules are executed in order of
33
// installation, as soon as their requirements have been installed.
34
} else if (id && typeof id.call === "function") {
35
qtail = qtail.next = { module: id };
36
if (qhead.next === qtail)
37
flushQueue();
38
}
39
};
40
41
// The `require` function takes an absolute module identifier and returns
42
// the `exports` object defined by that module. An error is thrown if no
43
// module with the given identifier is installed.
44
function require(moduleId) {
45
if (hasOwn.call(installed, moduleId)) {
46
var module = installed[moduleId];
47
if (!hasOwn.call(module, "exports")) {
48
// Each module receives a version of `require` that knows how
49
// to `absolutize` relative module identifiers with respect to
50
// `moduleId`.
51
module.call(global, function(id) {
52
return require(absolutize(id, moduleId));
53
}, module.exports = {}, module);
54
}
55
// Note that `module.exports` may be redefined during evaluation
56
// of the module.
57
return module.exports;
58
}
59
// Since modules are evaluated only after all their requirements have
60
// been installed, this error generally means that `require` was
61
// called with an identifier that was not seen (or was not understood)
62
// by the dependency scanner.
63
throw new Error('module "' + moduleId + '" not installed');
64
}
65
66
// Given two module identifiers `id` and `baseId`, the `absolutize`
67
// function returns the absolute form of `id`, as if `id` were required
68
// from a module with the identifier `baseId`. For more information about
69
// relative identifiers, refer to the
70
// [spec](http://wiki.commonjs.org/wiki/Modules/1.1#Module_Identifiers).
71
var pathNormExp = /\/(\.?|[^\/]+\/\.\.)\//;
72
function absolutize(id, baseId) {
73
if (id.charAt(0) === ".") {
74
// Note: if `baseId` is omitted, then `"/undefined/../" + id` will
75
// be the starting point for normalization, which works just fine!
76
id = "/" + baseId + "/../" + id;
77
while (id != (baseId = id.replace(pathNormExp, "/")))
78
id = baseId;
79
id = id.replace(/^\//, "");
80
}
81
return id;
82
}
83
84
// The `flushQueue` function attempts to evaluate the oldest module in the
85
// queue, provided all of its dependencies have been installed. This
86
// provision is important because it ensures that the module can call
87
// `require` without fear of missing dependencies.
88
function flushQueue() {
89
var next = qhead.next, module;
90
if (next && !flushing && ready(module = next.module)) {
91
flushing = qhead = next;
92
// Module evaluation might throw an exception, so we need to
93
// schedule the next call to `flushQueue` before invoking
94
// `module.call`. The `setTimeout` function allows the stack to
95
// unwind before flushing resumes, so that the browser has a chance
96
// to report exceptions and/or handle other events.
97
global.setTimeout(resume, 0);
98
module.call(global, require);
99
flushing = undefined;
100
}
101
}
102
103
// If `install` is called during the evaluation of a queued module,
104
// `flushQueue` could be invoked recursively. To prevent double evaluation,
105
// `flushQueue` sets `flushing` to a truthy value before it evaluates a
106
// module and refuses to evaluate any modules if `flushing` is truthy
107
// already.
108
var flushing;
109
110
// Since `resume` is only ever invoked from `setTimeout`, there is no risk
111
// that `flushQueue` is already executing, so it is safe to clear the
112
// `flushing` flag unconditionally.
113
function resume() {
114
flushing = undefined;
115
flushQueue();
116
}
117
118
// To be recognized as dependencies, calls to `require` must use string
119
// literal identifiers.
120
var requireExp = /\brequire\(['"]([^'"]+)['"]\)/g;
121
122
// A module is `ready` to be evaluated if
123
//
124
// 1. it has an `.exports` property (indicating that it has already begun to be evaluated) or
125
// 1. all of its direct dependencies are installed and `ready` to be evaluated.
126
//
127
// Note that the above definition is recursive.
128
function ready(module) {
129
var deps, code, match, id, result = true;
130
131
if (!module.seen &&
132
!hasOwn.call(module, "exports"))
133
{
134
// Here's a little secret: module definitions don't have to be
135
// functions, as long as they have a suitable `.toString` and
136
// `.call` methods. If you have a really long module that you
137
// don't want to waste time scanning, just override its
138
// `.toString` function to return something equivalent (with
139
// regard to dependencies) but shorter.
140
deps = module.deps;
141
if (!deps) {
142
code = module + "";
143
deps = module.deps = {};
144
requireExp.lastIndex = 0;
145
while ((match = requireExp.exec(code)))
146
deps[absolutize(match[1], module.id)] = true;
147
}
148
149
// There may be cycles in the dependency graph, so we must be
150
// careful that the recursion always terminates. Each module we
151
// check is temporarily marked as `.seen` before its dependencies
152
// are traversed, so that if we encounter the same module again we
153
// can immediately return `true`.
154
module.seen = true;
155
156
for (id in deps) {
157
if (hasOwn.call(deps, id)) {
158
// Once a dependency is determined to be satisfied, we
159
// remove its identifier from `module.deps`, so that we
160
// can avoid considering it again if `ready` is called
161
// multiple times.
162
if (hasOwn.call(installed, id) && ready(installed[id])) {
163
delete deps[id];
164
// If any dependency is missing or not `ready`, then the
165
// current module is not yet `ready`. The `break` is not
166
// strictly necessary here, but immediately terminating
167
// the loop postpones work that can be done later.
168
} else {
169
result = false;
170
break;
171
}
172
}
173
}
174
175
// Ordinarily I would be more paranoid about always resetting
176
// `module.seen` to `false`, but if you thoroughly examine the code
177
// above, you'll find that the only real threat of exceptions comes
178
// from evaluating `code = module + ""` in a recursive call to
179
// `ready`. So if you decide to override the `.toString` method of a
180
// module for performance reasons, get it right.
181
module.seen = false;
182
}
183
184
return result;
185
}
186
187
// The most reliable way to get the global object:
188
// [http://stackoverflow.com/a/3277192/128454](http://stackoverflow.com/a/3277192/128454)
189
}(Function("return this")()));
190
191