parent
f24bc366e5
commit
3d0ce78306
@ 0,0 +1,211 @@


+++


date = "20181207T21:08:3908:00"


title = "Privacy is Consent (alt: On Optimal Privacy vs. System Efficiency)"


+++




This fieldnote documents my notes with regards to a characterization of systems I've been calling "optimal privacy" but which intersects and overlaps with many other concepts in the literature e.g "privacy and computational complexity" or "approximate privacy".




Starting with an observation, it is clear that privacypreserving protocols are less efficient than nonprivacy preserving protocols  that is to say that it seems that one must always communicate more to say less. (As far as I can tell, this observation was first made by Beaver[[1]](#1))




This raises two interesting questions, what do we mean when we say we can compute a function privately and how does optimalprivacy relate to overall system efficiency?




Beaver[[1]](#1), Chor[[2]](#2), Kushilevitz[[2]](#2)[[3]](#3) and others published much on this in the last 80s to early 90s and what follows below is a summary and rephrasing of their work.




### What functions can be computed privately?




Let's consider two parties Alice & Bob, who wish to compute a function $f(x,y)$ where $x$ is an input provided by Alice, and $y$ is an input provided by Bob.




We note that Alice could simply send $x$ to Bob (or Bob could send $y$ to Alice) and the recipient would be able to computer the function keeping their input private. We however would like to explore ways such that both can compute the function while revealing as little as possible about their input.




In the ideal case, what is generally referred to as *perfectprivacy* we would like to reveal only information that can be derived from either parties private input and the value of the function.




While generally left unspecified in earlier papers on this subject, I want to explicitly add one additional constraint to the definition of a perfectly private protocol:




* The information about the private inputs that is communicated, or that can be derived, as a result of the protocol should be symmetric for both parties




Any function $f(x,y)$ can be reduced and written as a matrix $M$ where the the matrix coordinate $M(x,y) = f(x,y)$. As an example the following is a representation of an AND function, and an OR function:




$$AND(x,y) = \begin{pmatrix}0 & 0\\\ 0 & 1\end{pmatrix}\,\, OR(x,y) = \begin{pmatrix}0 & 1\\\ 1 & 1\end{pmatrix}$$




Given this representation we can start to construct rules and intuition about which functions can be made to be privacy preserving and which cannot.




Trivially, any matrix which is insensitive to both $x$ and $y$ can be made privacypreserving, e.g. $\forall x,y;$ $f(x,y) = 0$:




$$f(x,y) = \begin{pmatrix}0 & 0 & \dots \\\ 0 & 0 & \dots \\\ \vdots & \vdots & \ddots \end{pmatrix}$$




Given such a matrix, either party can communicate the value of the function without input from each other (because the value is constant).




#### Partionable Functions




It is perhaps clear at this point that in order to privately compute a nontrivial function we require each party to reveal some information about their input.




Such information is necessary to *partition* the function into a smaller value space. Given enough information our goal is to partition the value space to produce a trivial matrix.




As an example let's consider the function $f(x,y) = x + y\, mod \,2$, it has a function matrix as below:




$$f(x,y) = \begin{pmatrix}0 & 1 & 0 & 1 & 0 & 1 & \dots \\\ 1 & 0 & 1 & 0 & 1 & 0 & \dots\\\ 0 & 1 & 0 & 1 & 0 & 1 & \dots\\\ 1 & 0 & 1 & 0 & 1 & 0 & \dots \\\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots \end{pmatrix}$$




Such a function can be partitioned based on a single bit of information e.g. whether $y$ is divisible by 2:




$$f(x,y) = \begin{pmatrix}1 & 1 & 1 & \dots\\\ 0 & 0 & 0 & \dots\\\ 1 & 1 & 1 & \dots \\\ 0 & 0 & 0 & \dots \\\ \vdots & \vdots & \vdots & \vdots \ddots \end{pmatrix}$$




or not:




$$f(x,y) = \begin{pmatrix}0 & 0 & 0 & \dots \\\ 1 & 1 & 1 & \dots\\\ 0 & 0 & 0 & \dots\\\ 1 & 1 & 1 & \dots \\\ \vdots & \vdots & \vdots & \vdots \ddots \end{pmatrix}$$




We can partition each matrix again, based on whether $x$ is divisible by 2 or not. Regardless of which of the above partitioned matrices we start with, the resulting matrices are the same:




$$f(x,y) = \begin{pmatrix}0 & 0 & 0 & \dots\\\ 0 & 0 & 0 & \dots\\\ \vdots & \vdots & \vdots & \ddots \end{pmatrix}$$




$$f(x,y) = \begin{pmatrix}1 & 1 & 1 & \dots\\\ 1 & 1 & 1 & \dots \\\ \vdots & \vdots & \vdots & \ddots \end{pmatrix}$$




Both resulting matrices are constant and insensitive to any other information about $x$ or $y$. We have revealed the minimal amount of information necessary to compute the (admittedly rather simple) function.




#### Nonpartionable Functions




Before we dive deeper into the above, it is worth pointing out that not all (in fact, the majority of) functions are partionable.




Kushilevitz [[3]](#3) provides us with a definition of *forbidden matrices*, function matrices which cannot be partitioned. For the sake of clarity, I am going to use the term *nonpartionable*.




Intuitively, we cannot partition functions if there is no way to partition the input variable space in a way that cleanly partitions the output value space.




In our above example, we could partition both input variables by the "divisible by 2" check. (Note that in this case we could have started with either $x$ or $y$  that is we could partition by rows *or* by columns.)




To understand why some functions are nonpartitionable, let us start with looking at a concrete example of a function that is impossible to compute in a private manner, the AND function, defined over the input domain $[0,3)$:




$$AND(x,y) = \begin{pmatrix}


0 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 1 \\\ 0 & 0 & 1 & 1 \\\ 0 & 1 & 1 & 1


\end{pmatrix}$$




Observe how every row and column is unique  there is no bit of information that can be given that subdivides the matrix into (logical) discrete partitions.




More formally, every potential input $x$ and $y$ is transitively related to every other input $x$ and $y$ respectively.




That is to say that every $x$ ($x\_1$) shares a relation $ \sim$ with at least one other $x$ ($x\_2$) such that there exists a $y$ where $M\_{{x\_1}y} = M\_{{x\_2}y}$




The equivalence relation $\equiv$ on the rows of the Matrix is defined as the transitive closure over $~$. That is, $x\_1 \equiv x\_2$ if there exist a set of $x\_i$ such that $ x\_1 \sim x\_{i\_1} \sim x\_{i\_2} \sim x\_{i\_3} \sim \dots \sim x\_2$




A similar relation is defined over $y$ for the columns of the matrix.




We can now see that if all the rows and all the columns of a submatrix are equivalent, there can be no way to partition the submatrix i.e. for any possible partition there will always be at least one output value that is shared by the input values of multiple partitions.




(Recursively, a matrix cannot be partitioned if it contains a submatrix that cannot be partitioned.)




Going back to our AND function, we can see that this is the case, even if we just consider submatrix for the input domain [0,1]




For $y$:




$$


f(0,0) \equiv f(0,1) = 0


$$




And for $x$:




$$


f(0,0) \equiv f(1,0) = 0


$$




This means that there are no ways of partitioning the submatrix of the AND function without revealing all of $x$ and $y$  thus it is impossible to compute AND between two parties in an informationtheoretic private way (we will leave aside computing similar functions in the computational model of privacy until later)




From the above we can also observe that functions with a unique output for every set of inputs can never be computed without revealing both sets of inputs i.e. in order to maintain privacy over the input variables of Alice & Bob the function output domain must be of lower order than the input domain.




#### A Note on the Optimal Partitioning of Function Matrices




This fieldnote will not dive into strategies for determining the optimal partition of a given function, but by now it may have occurred to you that "partitioning matrices" isn't exactly a trivial step. There are often multiple equivalent ways of partitioning certain functions, and both parties must agree on a given optimal partition and have a way of efficiently communicating which partition they are selecting during each round.




### Additional Information & Privacy




As we noted further up, we can achieve perfect privacy for any party by sacrificing the privacy of another.




We can therefore think of optimalprivacy as the goal of minimizing the amount of information either party must reveal about their inputs.




(Optimal) Privacy can be seen as a metafunction which takes in a function matrix and outputs the minimum amount of additional information necessary to resolve the function to an arbitrary value. BarYehuda, Chor and Kushilevitz [[4]](#4) proved tight bounds on the minimum amount of information that must be revealed for twoparty functions.




As an example, consider the following function:




$$f(x,y) = \begin{cases} 1 & x = y \\\ min(x,y) & x \neq y \end{cases}$$




We can represent the function over the input domain [0,3] as follows:




$$f(x,y) = \begin{pmatrix}


1 & 0 & 0 & 0 \\\ 0 & 1 & 1 & 1 \\\ 0 & 1 & 1 & 2 \\\ 0 & 1 & 2 & 1


\end{pmatrix}$$




We note that in the above function that at least one party always learns the others input (the minimum), and both parties reveal their input in the case that the number is the same. Because of this it can be tempting to think of such a function as notperfectly private, however, per our definition above, it is.




The matrix of the function above is partionable by revealing the most signficant bit of each input. Both Alice and Bob would take it in turns to reveal significant bits, each one would cut the value space in half.




In some of the leaf nodes (e.g. if Alice chooses 2 or 3 and Bob chooses 0 or 1 as in the bottom left of the matrix, or vice versa in the top right) we see that the matrix decomposes into two monochrome submatrices allows the party with the maximum value to retain some privacy of their input.




In others (as seen in the top left & bottom right), the matrices decompose in such a way that revealing the value, also reveals both inputs (either the values are equal, or through the process of eliminations there are no other values that either party could possess).




Sadly, in the informationtheoretic model, the number of functions that are defined in the input space for our metafunction is frustratingly limited. There are simply not that many interesting functions we can compute with perfect informationtheoretic privacy.




For more interesting metafunctions we are forced to make tradeoffs either by either limiting the computational power of parties (i.e. achieving privacy through the properties of certain cryptographical problems) or by accepting that we can only achieve *approximate* privacy.




### The Millionaires Problem




Alice and Bob wish to know which one of them is richer, without revealing their wealth. They construct the following function:




$$f(x,y) = \begin{cases} 0 & x \geq y \\\ 1 & x \lt y \\\ \end{cases}$$




Note that the above breaks ties in favor of Alice. This forms the following function matrix:




$$f(x,y) = \begin{pmatrix}


0 & 1 & 1 & 1 & \dots \\\ 0 & 0 & 1 & 1 & \dots\\\ 0 & 0 & 0 & 1 & \dots \\\ \vdots & \vdots & \vdots & \vdots & \ddots \\\


\end{pmatrix}$$




Such a function matrix is nonpartitionable, as every submatrix along the diagonal is nonpartionable, as such perfect privacy is impossible.




The Bisection Protocol (as defined by Feigenbaum et al [[5]](#5)) provides good privacy in the average case. Much like the strategy for the $min(x,y)$ based function above we can bitbybit compare the most significant bit of each of the parties inputs, and stop once the outputs from the parties differ.




The bisection protocol applied to the millionaires problem is optimallyprivate in respect to the party with the least amount of money: in addition to learning the most significant bit at which their wealth differs from the richer party, they also (by way of their private input) learn the lower and upper bounds on the difference of their wealth and the richer party, i.e. they learn the input of the wealthier party is the interval $\[2^{nk}, 2^n\)$ where $k$ is the index of the most significant bit where both inputs differ. In contrast, the wealthier party only learns that the other has an input in the interval in the interval $\[0, 2^{nk}\)$




More clearly stated, the information revealed to each party by the protocol is asymmetric.




Further, the greater the difference of two inputs, the greater the asymmetry. Consider the, worst case, example where Alice has $2^n$ wealth (the maximum possible), and Bob has $0$.




In the first comparison of the Bisection Protocol, Alice will learn that they have the most wealth (thus they have computed the function), and will additionally learn that Bob's wealth is in the interval $\[0, 2^{n1}\)$. Bob will also learn that Alice has more wealth, but will also learn that Alice's wealth is the interval $\[2^{n1}, 2^n\)$.




In comparison to the case where Alice and Bob have the same wealth (or near the same wealth), the protocol runs for longer and the information asymmetry approaches 0 (however this trend runs inverse to the total amount of system information both parties gain).




At this point, it is worth explicitly noting that we can greatly improve the privacy of a protocol to compute the millionaires problem if we can limit the computational power of both parties (See Yao [[6]](#6)). (This also relies on the assumption that oneway functions exist)




In the case of the millionaires problem, we can use Oblivious Transfer to evaluate the inputs of a Garbled Circuit, in addition to numerous other protocols. Such protocols will ensure that each party learns only the value of the function (under the limited computational power & oneway functions assumptions).




### Communication Efficiency, Privacy & Consent




We have finally reached the point in this fieldnote where we can start considering the second question: how does achieving optimalprivacy relate to the overall communication efficiency of the system?




Regardless of whether a function can be computed with perfectprivacy (or the assumptions made about computational power) the communication complexity of the number of rounds associated with the optimally private computation is dramatically more that a nonprivate computation.




As an example, a nonprivate computation of the millionaires problem can be computed with a **single** round of communication (where each party transmits once). The bisection protocol requires *atleast* one round of communication, and at worst $n$ rounds of communication ($n = \log_{2}N$ where $N$ is the maximum value of the input domain). The simplest oblivious transfer protocol [[7]](#7) on the other hand requires $1.5$ rounds to transmit a single bit (thus requires $1.5 \cdot n$ rounds of communication, not including the communication required to setup the garbled circuit).




We have to engage in much more conversation, to transmit less information.




More formally, we know that if a function can be computed perfectly private it can be computed in at worst $2 \cdot 2^n$ rounds (See [[1]](#1)), we also know that we can trade additional information for improvements on communication complexity ([[4]](#4)  that is, we can sacrifice privacy to gain efficiency. We can choose to give up more information about our (private) inputs to improve the efficiency of the system.




Thus we hit upon a philosophical notion of the nature of privacy & consent. Consent is the degree to which you are willing to reveal additional information to improve the efficiency of a system. Privacy is the degree to which you are unwilling to reveal additional information. Privacy and Consent are poles on the same spectrum. Privacy is negative consent, Consent is negative privacy.




**Privacy is Consent**










# References




<div id="1"/>


1. Beaver, Donald. Perfect privacy for twoparty protocols. Harvard University, Center for Research in Computing Technology, Aiken Computation Laboratory, 1989.


<div id="2"/>


2. Chor, Benny, and Eyal Kushilevitz. "A zeroone law for boolean privacy." SIAM Journal on Discrete Mathematics 4.1 (1991): 3647.


<div id="3"/>


3. Kushelvitz, Eyal. "Privacy and communication complexity." SIAM Journal on Discrete Mathematics 5.2 (1992): 273284.


<div id="4"/>


4. R. BarYehuda, B. Chor, E. Kushilevitz and A. Orlitsky, "Privacy, additional information and communication," in IEEE Transactions on Information Theory, vol. 39, no. 6, pp. 19301943, Nov. 1993. doi: 10.1109/18.265501


<div id="5"/>


5. Feigenbaum, Joan, Aaron D. Jaggard, and Michael Schapira. "Approximate privacy: foundations and quantification." Proceedings of the 11th ACM conference on Electronic commerce. ACM, 2010.


<div id="6"/>


6. A. C. Yao, "Protocols for secure computations," 23rd Annual Symposium on Foundations of Computer Science (sfcs 1982)(FOCS), vol. 00, no. , pp. 160164, 1982.


doi:10.1109/SFCS.1982.88


<div id="7"/>


7. Chou, Tung, and Claudio Orlandi. "The simplest protocol for oblivious transfer." International Conference on Cryptology and Information Security in Latin America. Springer, Cham, 2015.

@ 0,0 +1,6 @@


.DS_Store


docs/build/htmlmathjaxsite


config/local/*.js


!config/local/local.js


unpacked/config/local/*.js


!unpacked/config/local/local.js

@ 0,0 +1,7 @@


.DS_Store


docs/build/htmlmathjaxsite


config/local/*.js


!config/local/local.js


unpacked/config/local/*.js


!unpacked/config/local/local.js


fonts/HTMLCSS/TeX/png

@ 0,0 +1,17 @@


language: node_js


node_js:


 stable


sudo: false


script:


 npm install


 npm test


branches:


only:


 "/^\\d+\\.\\d+/"


deploy:


provider: npm


email: manager@mathjax.org


api_key:


secure: cTkds6AqvCrkE9lAbBBjyDy7swjQEsGTCvLcjEyJemWH7ciNmtbwQ+Mzpk5bsL1i734CS29fTUBY05bPdwhBXB19yC0LzDfuNd2OKd1GhKa5OUig3d3+iNZEb/bhlEL/N2pM3pNBLT3+HDWBWVPPzDOCgSHYf355WmNlFIxrUtWbQQ7w5cX1d6ZKHVDkO0s9cl9eIQkX5aIKpsQM/N/tfkqPlF3OZuseTg7TU1wL+g6zqtsa0a1uhjXiCSRfDzgi4e2FUg9OBJHInbRho7MoZ9c8NrgCDTqwh1xJVAgi50HZpFAlhw3bBvWMzWLESLKUgmDOQc1/jzq6EhdUY1HMmryHPtvFIlyj0mWH88lZjUOqsCntG+t874ONYGkHF7I5q9VsX5LJNiZzASeXMymA1BP3fC33s/vGXen1H90JpdlGQXQvIXn6ZIQ9UiI1/bONuxVEUghnVRZHLTe2Nhy7s2s0OHTN23PmDVPHSzuM1FjEXXFaza/dGgOfi0ACRBPcqopQ2wxuCVDlmrrL+3r2o4Tp5F3f49KIrqNwO/GSnWX5H7GgxHKSh7CK1rUwqcpTumwYfY1Do/xdlu2D3I/IjZXO9TzDtZYJG1ye0BVTh44cECfBgBIZVmRH56Yjo5MvKEQwSSFfETKW4PKWoahbZIC4V99YWhoRqYqtb+OT0ow=


on:


tags: true

@ 0,0 +1,259 @@


# Contributing to MathJax




You are interested in giving us a hand? That's awesome! We've put together some brief guidelines that should help you get started quickly and easily.




There are lots and lots of ways to get involved, this document covers:




* [reporting an issue](#reportinganissue)


* [bug reports](#bugreports)


* [feature requests](#featurerequests)


* [change requests](#changerequests)


* [working on MathJax core](#workingonmathjaxcore)


* [key branches and tags](#keybranchestags)


* [submitting pull requests](#submittingpullrequests)


* [testing and quality assurance](#testingandqualityassurance)


* [writing documentation](#writingdocumentation)


* [translation](#translation)


* [Conduct](#conduct)






## Reporting An Issue




If you're about to raise an issue because you think you've found a


problem with MathJax, or you'd like to make a request for a new


feature in the codebase, or any other reasonโฆ please read this first.




The GitHub issue tracker is the preferred channel for [bug reports](#bugreports),


[feature requests](#featurerequests), [change requests](#changerequests) and [submitting pull


requests](#submittingpullrequests), but please respect the following restrictions:




* Please **search for existing issues**. Help us keep duplicate issues


to a minimum by checking to see if someone has already reported your


problem or requested your idea.




* Please **do not** use the issue tracker for personal support


requests (use [the MathJax User Group](https://groups.google.com/forum/#!forum/mathjaxusers)).




* Please **be civil**. Keep the discussion on topic and respect the


opinions of others. See also our [Conduct Guidelines](#conduct)




### Bug Reports




A bug is a _demonstrable problem_ that is caused by the code in the repository.


Good bug reports are extremely helpful  thank you!




Guidelines for bug reports:




1. **Use the GitHub issue search** — check if the issue has already been


reported.




2. **Check if the issue has been fixed** — look for [closed issues in the


current milestone](https://github.com/MathJax/MathJax/issues?&page=1&state=closed) or try to reproduce it


using the latest `develop` branch. Please note that we only pack MathJax for releases, so on the `develop` branch you have to use `/unpacked/MathJax.js` etc. to test.




3. **Share a live sample of the problem** — without a live page it is usually impossible to debug problems; see also the Bug Report Template below.




4. **Isolate the problem** — a live sample is a starting point but if you want to speed things up create a [reduced test


case](http://csstricks.com/6263reducedtestcases/). Be specific about your setup (browser, OS versions etc). Use services like [jsbin](http://jsbin.com), [CodePen](http://codepen.io), [JSfiddle](http://jsfiddle.com) to make collaboration on minimal test cases easier for everyone. Use the unpacked copy of MathJax (`[...]/unpacked/MathJax.js` etc.) for better debugging.




5. **Include a screenshot/cast as a last resort** — Is your issue about a layout


or design feature / bug but hard to reproduce or isolate? Then please provide a screenshot or screencast. Tools like [LICEcap](http://www.cockos.com/licecap/) or [SauceLabs](http://www.saucelabs.com) allow you to quickly and easily record a screencasts. Make it an animated gif, embed it directly into your GitHub issue  kapow!




6. Use the Bug Report template below or [click this


link](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)


to start creating a bug report with the template automatically.




A good bug report shouldn't leave others needing to chase you up for


more information. Be sure to include the details of your environment.




Here is a [real example](https://github.com/mathjax/MathJax/issues/820)




Template Example ([click to use](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)):


```


Short and descriptive example bug report title




### Issue Summary




A summary of the issue and the browser/OS environment in which it occurs. If


suitable, include the steps required to reproduce the bug.




### Steps to Reproduce




1. This is the first step


2. This is the second step


3. Further steps, etc.




Any other information you want to share that is relevant to the issue


being reported. Especially, why do you consider this to be a bug? What


do you expect to happen instead?




### Technical details:




* MathJax Version: 2.3 (latest commit: f3aaf3a2a3e964df2770dc4aaaa9c87ce5f47e2c)


* Client OS: Mac OS X 10.8.4


* Browser: Chrome 29.0.1547.57


```






### Feature Requests




Feature requests are welcome. Before you submit one be sure to have:




1. Read the


[Roadmaps](https://github.com/mathjax/MathJax/wiki/Mathjaxroadmap),


**use the GitHub search** and check the feature hasn't already been


requested.


2. Take a moment to think about whether your idea fits with the scope


and aims of the project, or if it might better fit being a [custom


extension](https://github.com/mathjax/MathJaxthirdpartyextensions).


3. Remember, it's up to *you* to make a strong case to convince the


project's leaders of the merits of this feature. Please provide as


much detail and context as possible, this means explaining the use


case and why it is likely to be common.


4. Clearly indicate whether this is a feature request for MathJax


core, input & output jax, or extensions.






### Change Requests




Change requests cover both architectural and functional changes to how


MathJax works. If you have an idea for a new or different dependency,


a refactor, or an improvement to a feature, etc  please be sure to:




1. **Use the GitHub search** and check someone else didn't get there first


2. Take a moment to think about the best way to make a case for, and


explain what you're thinking. Are you sure this shouldn't really be


a [bug report](#bugreports) or a [feature


request](#featurerequests)? Is it really one idea or is it many?


What's the context? What problem are you solving? Why is what you


are suggesting better than what's already there? Does it fit with


the Roadmap?




## Working on MathJax core




You want to contribute code? Fantastic! Let's get you started.




### Key Branches & Tags




To get it out of the way:




 **[develop](https://github.com/MathJax/MathJax/tree/develop)** is


the development branch. All work on the next release happens here so


you should generally branch off `develop`. Do **NOT** use this branch


for a production site.


 **[master](https://github.com/MathJax/MathJax)** contains the latest


release of MathJax. This branch may be used in production. Do


**NOT** use this branch to work on MathJax's source.




### Submitting Pull Requests




Pull requests are awesome. If you're looking to raise a PR for


something which doesn't have an open issue, please think carefully


about [raising an issue](#reportinganissue) which your PR can close,


especially if you're fixing a bug. This makes it more likely that


there will be enough information available for your PR to be properly


tested and merged.




##### Need Help?




If you're not completely clear on how to submit / update / *do* Pull


Requests, please check out our [source control


policies](https://github.com/mathjax/MathJax/wiki/Sourcecontrolpolicies). For


more insights, chech the excellent in depth [Git Workflow


guide](https://github.com/TryGhost/Ghost/wiki/GitWorkflow) from


Ghost, in particular




* [Ghost Workflow guide: commit messages](https://github.com/TryGhost/Ghost/wiki/Gitworkflow#commitmessages)




### Testing and Quality Assurance




Never underestimate just how useful quality assurance is. If you're


looking to get involved with the code base and don't know where to


start, checking out and testing a pull request is one of the most


useful things you could do.




If you want to get involved with testing MathJax, there is a set of QA


Documentation [in our testing


framework](https://github.com/MathJax/MathJaxtest).




Essentially though, [check out the latest develop


branch](#workingonmathJaxcore), take it for a spin, and if you find


anything odd, please follow the [bug report guidelines](#bugreports)


and let us know!




#### Checking out a Pull Request




These are some [excellent


instructions](https://gist.github.com/piscisaureus/3342247) on


configuring your GitHub repository to allow you to checkout pull


requests in the same way as branches:


<https://gist.github.com/piscisaureus/3342247>.






### Writing documentation




MathJax's main documentation can be found at [docs.mathjax.org](http://docs.mathjax.org).


The source of the docs is hosted in the


[mathjax/mathjaxdocs](http://github.com/mathjax/mathjaxdocs) repo here on GitHub.




The documentation is generated using [Sphinxdoc](http://sphinxdoc.org/) and hosted on


[Read the docs](http://readthedocs.org).


You can clone the repo and submit pull requests following the


[pullrequest](#submittingpullrequests) guidelines.






### Translation




If you wish to add or update translations of MathJax, please do it on


[TranslateWiki.net](https://translatewiki.net/w/i.php?title=Special:Translate&group=outmathjax0all)


(and while you're there you can help other open source projects,


too, because you're awesome!).




For bug reports and other questions that don't fit on


TranslateWiki.net, head over to the


[mathjax/mathjaxi18n](https://github.com/mathjax/MathJaxi18n)


repository.




## Conduct




We are committed to providing a friendly, safe and welcoming environment for


all, regardless of gender, sexual orientation, disability, ethnicity, religion,


or similar personal characteristic.




Please be kind and courteous. There's no need to be mean or rude.


Respect that people have differences of opinion and that every design or


implementation choice carries a tradeoff and numerous costs. There is seldom


a right answer, merely an optimal answer given a set of values and


circumstances.




Please keep unstructured critique to a minimum. If you have solid ideas you


want to experiment with, make a fork and see how it works.




We will exclude you from interaction if you insult, demean or harass anyone.


That is not welcome behaviour. We interpret the term "harassment" as


including the definition in the


[Citizen Code of Conduct](http://citizencodeofconduct.org/);


if you have any lack of clarity about what might be included in that concept,


please read their definition. In particular, we don't tolerate behavior that


excludes people in socially marginalized groups.




Private harassment is also unacceptable. No matter who you are, if you feel


you have been or are being harassed or made uncomfortable by a community


member, please contact one of the channel ops or any of the


[MathJax](https://github.com/MathJax/MathJax) core team


immediately. Whether you're a regular contributor or a newcomer, we care about


making this community a safe place for you and we've got your back.




Likewise any spamming, trolling, flaming, baiting or other attentionstealing


behaviour is not welcome.




We also suggest to read [discourse's


rules](http://blog.discourse.org/2013/03/theuniversalrulesofcivilizeddiscourse/)




## References




* We heavily borrowed from Mozilla and Ghost  thank you!


* https://github.com/TryGhost/Ghost/blob/master/CONTRIBUTING.md


* https://github.com/mozilla/rust/wiki/Notedevelopmentpolicy


* https://github.com/jden/CONTRIBUTING.md/blob/master/CONTRIBUTING.md


* http://blog.discourse.org/2013/03/theuniversalrulesofcivilizeddiscourse/

@ 0,0 +1,202 @@




Apache License


Version 2.0, January 2004


http://www.apache.org/licenses/




TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION




1. Definitions.




"License" shall mean the terms and conditions for use, reproduction,


and distribution as defined by Sections 1 through 9 of this document.




"Licensor" shall mean the copyright owner or entity authorized by


the copyright owner that is granting the License.




"Legal Entity" shall mean the union of the acting entity and all


other entities that control, are controlled by, or are under common


control with that entity. For the purposes of this definition,


"control" means (i) the power, direct or indirect, to cause the


direction or management of such entity, whether by contract or


otherwise, or (ii) ownership of fifty percent (50%) or more of the


outstanding shares, or (iii) beneficial ownership of such entity.




"You" (or "Your") shall mean an individual or Legal Entity


exercising permissions granted by this License.




"Source" form shall mean the preferred form for making modifications,


including but not limited to software source code, documentation


source, and configuration files.




"Object" form shall mean any form resulting from mechanical


transformation or translation of a Source form, including but


not limited to compiled object code, generated documentation,


and conversions to other media types.




"Work" shall mean the work of authorship, whether in Source or


Object form, made available under the License, as indicated by a


copyright notice that is included in or attached to the work


(an example is provided in the Appendix below).




"Derivative Works" shall mean any work, whether in Source or Object


form, that is based on (or derived from) the Work and for which the


editorial revisions, annotations, elaborations, or other modifications


represent, as a whole, an original work of authorship. For the purposes


of this License, Derivative Works shall not include works that remain


separable from, or merely link (or bind by name) to the interfaces of,


the Work and Derivative Works thereof.




"Contribution" shall mean any work of authorship, including


the original version of the Work and any modifications or additions


to that Work or Derivative Works thereof, that is intentionally


submitted to Licensor for inclusion in the Work by the copyright owner


or by an individual or Legal Entity authorized to submit on behalf of


the copyright owner. For the purposes of this definition, "submitted"


means any form of electronic, verbal, or written communication sent


to the Licensor or its representatives, including but not limited to


communication on electronic mailing lists, source code control systems,


and issue tracking systems that are managed by, or on behalf of, the


Licensor for the purpose of discussing and improving the Work, but


excluding communication that is conspicuously marked or otherwise


designated in writing by the copyright owner as "Not a Contribution."




"Contributor" shall mean Licensor and any individual or Legal Entity


on behalf of whom a Contribution has been received by Licensor and


subsequently incorporated within the Work.




2. Grant of Copyright License. Subject to the terms and conditions of


this License, each Contributor hereby grants to You a perpetual,


worldwide, nonexclusive, nocharge, royaltyfree, irrevocable


copyright license to reproduce, prepare Derivative Works of,


publicly display, publicly perform, sublicense, and distribute the


Work and such Derivative Works in Source or Object form.




3. Grant of Patent License. Subject to the terms and conditions of


this License, each Contributor hereby grants to You a perpetual,


worldwide, nonexclusive, nocharge, royaltyfree, irrevocable


(except as stated in this section) patent license to make, have made,


use, offer to sell, sell, import, and otherwise transfer the Work,


where such license applies only to those patent claims licensable


by such Contributor that are necessarily infringed by their


Contribution(s) alone or by combination of their Contribution(s)


with the Work to which such Contribution(s) was submitted. If You


institute patent litigation against any entity (including a


crossclaim or counterclaim in a lawsuit) alleging that the Work


or a Contribution incorporated within the Work constitutes direct


or contributory patent infringement, then any patent licenses


granted to You under this License for that Work shall terminate


as of the date such litigation is filed.




4. Redistribution. You may reproduce and distribute copies of the


Work or Derivative Works thereof in any medium, with or without


modifications, and in Source or Object form, provided that You


meet the following conditions:




(a) You must give any other recipients of the Work or


Derivative Works a copy of this License; and




(b) You must cause any modified files to carry prominent notices


stating that You changed the files; and




(c) You must retain, in the Source form of any Derivative Works


that You distribute, all copyright, patent, trademark, and


attribution notices from the Source form of the Work,


excluding those notices that do not pertain to any part of


the Derivative Works; and




(d) If the Work includes a "NOTICE" text file as part of its


distribution, then any Derivative Works that You distribute must


include a readable copy of the attribution notices contained


within such NOTICE file, excluding those notices that do not


pertain to any part of the Derivative Works, in at least one


of the following places: within a NOTICE text file distributed


as part of the Derivative Works; within the Source form or


documentation, if provided along with the Derivative Works; or,


within a display generated by the Derivative Works, if and


wherever such thirdparty notices normally appear. The contents


of the NOTICE file are for informational purposes only and


do not modify the License. You may add Your own attribution


notices within Derivative Works that You distribute, alongside


or as an addendum to the NOTICE text from the Work, provided


that such additional attribution notices cannot be construed


as modifying the License.




You may add Your own copyright statement to Your modifications and


may provide additional or different license terms and conditions


for use, reproduction, or distribution of Your modifications, or


for any such Derivative Works as a whole, provided Your use,


reproduction, and distribution of the Work otherwise complies with


the conditions stated in this License.




5. Submission of Contributions. Unless You explicitly state otherwise,


any Contribution intentionally submitted for inclusion in the Work


by You to the Licensor shall be under the terms and conditions of


this License, without any additional terms or conditions.


Notwithstanding the above, nothing herein shall supersede or modify


the terms of any separate license agreement you may have executed


with Licensor regarding such Contributions.




6. Trademarks. This License does not grant permission to use the trade


names, trademarks, service marks, or product names of the Licensor,


except as required for reasonable and customary use in describing the


origin of the Work and reproducing the content of the NOTICE file.




7. Disclaimer of Warranty. Unless required by applicable law or


agreed to in writing, Licensor provides the Work (and each


Contributor provides its Contributions) on an "AS IS" BASIS,


WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or


implied, including, without limitation, any warranties or conditions


of TITLE, NONINFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A


PARTICULAR PURPOSE. You are solely responsible for determining the


appropriateness of using or redistributing the Work and assume any


risks associated with Your exercise of permissions under this License.




8. Limitation of Liability. In no event and under no legal theory,


whether in tort (including negligence), contract, or otherwise,


unless required by applicable law (such as deliberate and grossly


negligent acts) or agreed to in writing, shall any Contributor be


liable to You for damages, including any direct, indirect, special,


incidental, or consequential damages of any character arising as a


result of this License or out of the use or inability to use the


Work (including but not limited to damages for loss of goodwill,


work stoppage, computer failure or malfunction, or any and all


other commercial damages or losses), even if such Contributor


has been advised of the possibility of such damages.




9. Accepting Warranty or Additional Liability. While redistributing


the Work or Derivative Works thereof, You may choose to offer,


and charge a fee for, acceptance of support, warranty, indemnity,


or other liability obligations and/or rights consistent with this


License. However, in accepting such obligations, You may act only


on Your own behalf and on Your sole responsibility, not on behalf


of any other Contributor, and only if You agree to indemnify,


defend, and hold each Contributor harmless for any liability


incurred by, or claims asserted against, such Contributor by reason


of your accepting any such warranty or additional liability.




END OF TERMS AND CONDITIONS




APPENDIX: How to apply the Apache License to your work.




To apply the Apache License to your work, attach the following


boilerplate notice, with the fields enclosed by brackets "[]"


replaced with your own identifying information. (Don't include


the brackets!) The text should be enclosed in the appropriate


comment syntax for the file format. We also recommend that a


file or class name and description of purpose be included on the


same "printed page" as the copyright notice for easier


identification within thirdparty archives.




Copyright [yyyy] [name of copyright owner]




Licensed under the Apache License, Version 2.0 (the "License");


you may not use this file except in compliance with the License.


You may obtain a copy of the License at




http://www.apache.org/licenses/LICENSE2.0




Unless required by applicable law or agreed to in writing, software


distributed under the License is distributed on an "AS IS" BASIS,


WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


See the License for the specific language governing permissions and


limitations under the License.

File diff suppressed because one or more lines are too long
@ 0,0 +1,53 @@


# MathJax




## Beautiful math in all browsers




MathJax is an opensource JavaScript display engine for LaTeX, MathML, and


AsciiMath notation that works in all modern browsers. It was designed with


the goal of consolidating the recent advances in web technologies into a


single, definitive, mathontheweb platform supporting the major browsers


and operating systems. It requires no setup on the part of the user (no


plugins to download or software to install), so the page author can write


web documents that include mathematics and be confident that users will be


able to view it naturally and easily. Simply include MathJax and some


mathematics in a web page, and MathJax does the rest.




Some of the main features of MathJax include:




 Highquality display of LaTeX, MathML, and AsciiMath notation in HTML pages




 Supported in most browsers with no plugins, extra fonts, or special


setup for the reader




 Easy for authors, flexible for publishers, extensible for developers




 Supports math accessibility, cutandpaste interoperability, and other


advanced functionality




 Powerful API for integration with other web applications




See <http://www.mathjax.org/> for additional details.






## Installation and Usage




The MathJax installation and usage documentation is available in a


separate GitHub repository at <https://github.com/mathjax/mathjaxdocs>.


The HTML versions can now be viewed at <http://docs.mathjax.org/>,


where it is possible for you to submit corrections and modifications


directly to the documentation on line.






## Community




The main MathJax website is <http://www.mathjax.org>, and it includes


announcements and other important information. MathJax is maintained and


distributed on GitHub at <http://github.com/mathjax/MathJax>. A user forum


for asking questions and getting assistance is hosted at Google, and the


bug tracker is hosted at GitHub:




Bug tracker: <https://github.com/mathjax/MathJax/issues>


MathJaxUsers Group: <http://groups.google.com/group/mathjaxusers>




Before reporting a bug, please check that it has not already been reported.


Also, please use the bug tracker for reporting bugs rather than the help forum.

@ 0,0 +1,11 @@


{


"name": "MathJax",


"main": "./MathJax.js",


"homepage": "http://www.mathjax.org/",


"ignore": [


"**/.*",


"node_modules",


"components"


],


"keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"]


}

@ 0,0 +1,14 @@


{


"name": "mathjax/mathjax",


"type": "library",


"description": "MathJax is an opensource JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.",


"keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"],


"homepage": "http://www.mathjax.org/",


"license": "Apache2.0",


"authors": [


{


"name": "MathJax Consortium",


"homepage": "https://github.com/mathjax"


}


]


}

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/config/MMLorHTML.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




(function(c,g){var f="2.7.0";var a=MathJax.Hub.CombineConfig("MMLorHTML",{prefer:{MSIE:"MML",Firefox:"HTML",Opera:"HTML",Chrome:"HTML",Safari:"HTML",other:"HTML"}});var e={Firefox:3,Opera:9.52,MSIE:6,Chrome:0.3,Safari:2,Konqueror:4};var b=(g.version==="0.0"g.versionAtLeast(e[g]0));var d=(g.isFirefox&&g.versionAtLeast("1.5"))(g.isMSIE&&g.hasMathPlayer)(g.isSafari&&g.versionAtLeast("5.0"))(g.isOpera&&g.versionAtLeast("9.52"));c.Register.StartupHook("End Config",function(){var h=(a.prefer&&typeof(a.prefer)==="object"?a.prefer[MathJax.Hub.Browser]a.prefer.other"HTML":a.prefer);if(bd){if(d&&(h==="MML"!b)){if(MathJax.OutputJax.NativeMML){MathJax.OutputJax.NativeMML.Register("jax/mml")}else{c.config.jax.unshift("output/NativeMML")}c.Startup.signal.Post("NativeMML output selected")}else{if(MathJax.OutputJax["HTMLCSS"]){MathJax.OutputJax["HTMLCSS"].Register("jax/mml")}else{c.config.jax.unshift("output/HTMLCSS")}c.Startup.signal.Post("HTMLCSS output selected")}}else{c.PreProcess.disabled=true;c.prepareScripts.disabled=true;MathJax.Message.Set(["MathJaxNotSupported","Your browser does not support MathJax"],null,4000);c.Startup.signal.Post("MathJax not supported")}})})(MathJax.Hub,MathJax.Hub.Browser);MathJax.Ajax.loadComplete("[MathJax]/config/MMLorHTML.js");

@ 0,0 +1,19 @@


/*


* /MathJax/config/Safe.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Hub.Register.StartupHook("End Config",function(){if(!MathJax.Hub.config.extensions){MathJax.Hub.config.extensions=[]}MathJax.Hub.config.extensions.push("Safe.js")});MathJax.Ajax.loadComplete("[MathJax]/config/Safe.js");

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ 0,0 +1,40 @@


/* * Mode: Javascript; indenttabsmode:nil; jsindentlevel: 2 * */


/* vim: set ts=2 et sw=2 tw=80: */




/*************************************************************


*


* MathJax/config/local/local.js


*


* Include changes and configuration local to your installation


* in this file. For example, common macros can be defined here


* (see below). To use this file, add "local/local.js" to the


* config array in MathJax.js or your MathJax.Hub.Config() call.


*


* 


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/






MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {


var TEX = MathJax.InputJax.TeX;




// place macros here. E.g.:


// TEX.Macro("R","{\\bf R}");


// TEX.Macro("op","\\mathop{\\rm #1}",1); // a macro with 1 parameter




});




MathJax.Ajax.loadComplete("[MathJax]/config/local/local.js");

@ 0,0 +1,11 @@


The source files for the documentation are now kept in a separate


GitHub repository at




https://github.com/mathjax/mathjaxdocs




The HTML versions are now available at




http://docs.mathjax.org/




where it is possible for you to submit corrections and modifications


directly to the documentation on line.

@ 0,0 +1,27 @@


<!DOCTYPE html>


<html>


<head>


<title>MathJax Documentation</title>


</head>


<body>




<p>


The source files for the documentation are now kept in a separate


GitHub repository at


</p>


<p style="textindent:3em">


<a href="https://github.com/mathjax/mathjaxdocs">https://github.com/mathjax/mathjaxdocs</a>


</p>




<p>


The HTML versions are now available at


</p>


<p style="textindent:3em">


<a href="http://docs.mathjax.org/">http://docs.mathjax.org/</a>


</p>


<p>


where it is possible for you to submit corrections and modifications


directly to the documentation on line.


</p>


</body>


</html>

@ 0,0 +1,11 @@


The source files for the documentation are now kept in a separate


GitHub repository at




https://github.com/mathjax/mathjaxdocs




The HTML versions are now available at




http://docs.mathjax.org/




where it is possible for you to submit corrections and modifications


directly to the documentation on line.

File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/extensions/CHTMLpreview.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Callback.Queue(["Require",MathJax.Ajax,"[MathJax]/extensions/fastpreview.js"],["loadComplete",MathJax.Ajax,"[MathJax]/extensions/CHTMLpreview.js"]);

File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/extensions/HTMLCSS/handlefloats.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["HTMLCSS/handlefloats"]={version:"2.7.5"};MathJax.Hub.Startup.signal.Post("HTMLCSS handlefloats Ready");MathJax.Ajax.loadComplete("[MathJax]/extensions/HTMLCSS/handlefloats.js");

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/HTML.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/HTML"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var b=MathJax.InputJax.TeX;var a=b.Definitions;a.Add({macros:{href:"HREF_attribute","class":"CLASS_attribute",style:"STYLE_attribute",cssId:"ID_attribute"}},null,true);b.Parse.Augment({HREF_attribute:function(e){var d=this.GetArgument(e),c=this.GetArgumentMML(e);this.Push(c.With({href:d}))},CLASS_attribute:function(d){var e=this.GetArgument(d),c=this.GetArgumentMML(d);if(c["class"]!=null){e=c["class"]+" "+e}this.Push(c.With({"class":e}))},STYLE_attribute:function(d){var e=this.GetArgument(d),c=this.GetArgumentMML(d);if(c.style!=null){if(e.charAt(e.length1)!==";"){e+=";"}e=c.style+" "+e}this.Push(c.With({style:e}))},ID_attribute:function(e){var d=this.GetArgument(e),c=this.GetArgumentMML(e);this.Push(c.With({id:d}))},GetArgumentMML:function(d){var c=this.ParseArg(d);if(c.inferred&&c.data.length==1){c=c.data[0]}else{delete c.inferred}return c}});MathJax.Hub.Startup.signal.Post("TeX HTML Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/HTML.js");

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/action.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/action"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var b=MathJax.InputJax.TeX,a=MathJax.ElementJax.mml;b.Definitions.Add({macros:{toggle:"Toggle",mathtip:"Mathtip",texttip:["Macro","\\mathtip{#1}{\\text{#2}}",2]}},null,true);b.Parse.Augment({Toggle:function(d){var e=[],c;while((c=this.GetArgument(d))!=="\\endtoggle"){e.push(b.Parse(c,this.stack.env).mml())}this.Push(a.maction.apply(a,e).With({actiontype:a.ACTIONTYPE.TOGGLE}))},Mathtip:function(d){var c=this.ParseArg(d),e=this.ParseArg(d);this.Push(a.maction(c,e).With({actiontype:a.ACTIONTYPE.TOOLTIP}))}});MathJax.Hub.Startup.signal.Post("TeX action Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/action.js");

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/autobold.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/autobold"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var a=MathJax.InputJax.TeX;a.prefilterHooks.Add(function(d){var c=d.script.parentNode.insertBefore(document.createElement("span"),d.script);c.visibility="hidden";c.style.fontFamily="Times, serif";c.appendChild(document.createTextNode("ABCXYZabcxyz"));var b=c.offsetWidth;c.style.fontWeight="bold";if(b&&c.offsetWidth===b){d.math="\\boldsymbol{"+d.math+"}"}c.parentNode.removeChild(c)});MathJax.Hub.Startup.signal.Post("TeX autobold Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/autobold.js");

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/autoloadall.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/autoloadall"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var h={action:["mathtip","texttip","toggle"],AMSmath:["mathring","nobreakspace","negmedspace","negthickspace","intI","iiiint","idotsint","dddot","ddddot","sideset","boxed","substack","injlim","projlim","varliminf","varlimsup","varinjlim","varprojlim","DeclareMathOperator","operatorname","genfrac","tfrac","dfrac","binom","tbinom","dbinom","cfrac","shoveleft","shoveright","xrightarrow","xleftarrow"],begingroup:["begingroup","endgroup","gdef","global"],cancel:["cancel","bcancel","xcancel","cancelto"],color:["color","textcolor","colorbox","fcolorbox","definecolor"],enclose:["enclose"],extpfeil:["Newextarrow","xlongequal","xmapsto","xtofrom","xtwoheadleftarrow","xtwoheadrightarrow"],mhchem:["ce","cee","cf"]};var c={AMSmath:["subarray","smallmatrix","equation","equation*"],AMScd:["CD"]};var d,g,b,a={macros:{},environment:{}};for(d in h){if(h.hasOwnProperty(d)){if(!MathJax.Extension["TeX/"+d]){var f=h[d];for(g=0,b=f.length;g<b;g++){a.macros[f[g]]=["Extension",d]}}}}for(d in c){if(c.hasOwnProperty(d)){if(!MathJax.Extension["TeX/"+d]){var e=c[d];for(g=0,b=e.length;g<b;g++){a.environment[e[g]]=["ExtensionEnv",null,d]}}}}MathJax.InputJax.TeX.Definitions.Add(a);MathJax.Hub.Startup.signal.Post("TeX autoloadall Ready")});MathJax.Callback.Queue(["Require",MathJax.Ajax,"[MathJax]/extensions/TeX/AMSsymbols.js"],["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/autoloadall.js"]);

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/bbox.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/bbox"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var b=MathJax.InputJax.TeX,a=MathJax.ElementJax.mml;b.Definitions.Add({macros:{bbox:"BBox"}},null,true);b.Parse.Augment({BBox:function(e){var p=this.GetBrackets(e,""),o=this.ParseArg(e);var k=p.split(/,/),g,d,c;for(var l=0,j=k.length;l<j;l++){var f=k[l].replace(/^\s+/,"").replace(/\s+$/,"");var n=f.match(/^(\.\d+\d+(\.\d*)?)(ptemexmupxincmmm)$/);if(n){if(g){b.Error(["MultipleBBoxProperty","%1 specified twice in %2","Padding",e])}var h=this.BBoxPadding(n[1]+n[3]);if(h){g={height:"+"+h,depth:"+"+h,lspace:h,width:"+"+(2*n[1])+n[3]}}}else{if(f.match(/^([az09]+\#[09af]{6}\#[09af]{3})$/i)){if(d){b.Error(["MultipleBBoxProperty","%1 specified twice in %2","Background",e])}d=f}else{if(f.match(/^[az]+:/i)){if(c){b.Error(["MultipleBBoxProperty","%1 specified twice in %2","Style",e])}c=this.BBoxStyle(f)}else{if(f!==""){b.Error(["InvalidBBoxProperty","'%1' doesn't look like a color, a padding dimension, or a style",f])}}}}}if(g){o=a.mpadded(o).With(g)}if(dc){o=a.mstyle(o).With({mathbackground:d,style:c})}this.Push(o)},BBoxStyle:function(c){return c},BBoxPadding:function(c){return c}});MathJax.Hub.Startup.signal.Post("TeX bbox Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/bbox.js");

File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/boldsymbol.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/boldsymbol"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var a=MathJax.ElementJax.mml;var d=MathJax.InputJax.TeX;var b=d.Definitions;var c={};c[a.VARIANT.NORMAL]=a.VARIANT.BOLD;c[a.VARIANT.ITALIC]=a.VARIANT.BOLDITALIC;c[a.VARIANT.FRAKTUR]=a.VARIANT.BOLDFRAKTUR;c[a.VARIANT.SCRIPT]=a.VARIANT.BOLDSCRIPT;c[a.VARIANT.SANSSERIF]=a.VARIANT.BOLDSANSSERIF;c["texcaligraphic"]="texcaligraphicbold";c["texoldstyle"]="texoldstylebold";b.Add({macros:{boldsymbol:"Boldsymbol"}},null,true);d.Parse.Augment({mmlToken:function(f){if(this.stack.env.boldsymbol){var e=f.Get("mathvariant");if(e==null){f.mathvariant=a.VARIANT.BOLD}else{f.mathvariant=(c[e]e)}}return f},Boldsymbol:function(h){var e=this.stack.env.boldsymbol,f=this.stack.env.font;this.stack.env.boldsymbol=true;this.stack.env.font=null;var g=this.ParseArg(h);this.stack.env.font=f;this.stack.env.boldsymbol=e;this.Push(g)}});MathJax.Hub.Startup.signal.Post("TeX boldsymbol Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/boldsymbol.js");

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/cancel.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/cancel"]={version:"2.7.5",ALLOWED:{color:1,mathcolor:1,background:1,mathbackground:1,padding:1,thickness:1}};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var c=MathJax.InputJax.TeX,a=MathJax.ElementJax.mml,b=MathJax.Extension["TeX/cancel"];b.setAttributes=function(h,e){if(e!==""){e=e.replace(/ /g,"").split(/,/);for(var g=0,d=e.length;g<d;g++){var f=e[g].split(/[:=]/);if(b.ALLOWED[f[0]]){if(f[1]==="true"){f[1]=true}if(f[1]==="false"){f[1]=false}h[f[0]]=f[1]}}}return h};c.Definitions.Add({macros:{cancel:["Cancel",a.NOTATION.UPDIAGONALSTRIKE],bcancel:["Cancel",a.NOTATION.DOWNDIAGONALSTRIKE],xcancel:["Cancel",a.NOTATION.UPDIAGONALSTRIKE+" "+a.NOTATION.DOWNDIAGONALSTRIKE],cancelto:"CancelTo"}},null,true);c.Parse.Augment({Cancel:function(e,g){var d=this.GetBrackets(e,""),f=this.ParseArg(e);var h=b.setAttributes({notation:g},d);this.Push(a.menclose(f).With(h))},CancelTo:function(e,g){var i=this.ParseArg(e),d=this.GetBrackets(e,""),f=this.ParseArg(e);var h=b.setAttributes({notation:a.NOTATION.UPDIAGONALSTRIKE+" "+a.NOTATION.UPDIAGONALARROW},d);i=a.mpadded(i).With({depth:".1em",height:"+.1em",voffset:".1em"});this.Push(a.msup(a.menclose(f).With(h),i))}});MathJax.Hub.Startup.signal.Post("TeX cancel Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/cancel.js");

File diff suppressed because one or more lines are too long
@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/enclose.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/enclose"]={version:"2.7.5",ALLOWED:{arrow:1,color:1,mathcolor:1,background:1,mathbackground:1,padding:1,thickness:1}};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var c=MathJax.InputJax.TeX,a=MathJax.ElementJax.mml,b=MathJax.Extension["TeX/enclose"].ALLOWED;c.Definitions.Add({macros:{enclose:"Enclose"}},null,true);c.Parse.Augment({Enclose:function(g){var k=this.GetArgument(g),e=this.GetBrackets(g),j=this.ParseArg(g);var l={notation:k.replace(/,/g," ")};if(e){e=e.replace(/ /g,"").split(/,/);for(var h=0,d=e.length;h<d;h++){var f=e[h].split(/[:=]/);if(b[f[0]]){f[1]=f[1].replace(/^"(.*)"$/,"$1");if(f[1]==="true"){f[1]=true}if(f[1]==="false"){f[1]=false}if(f[0]==="arrow"&&f[1]){l.notation=l.notation+" updiagonalarrow"}else{l[f[0]]=f[1]}}}}this.Push(a.menclose(j).With(l))}});MathJax.Hub.Startup.signal.Post("TeX enclose Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/enclose.js");

@ 0,0 +1,19 @@


/*


* /MathJax/extensions/TeX/extpfeil.js


*


* Copyright (c) 20092018 The MathJax Consortium


*


* Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.


* You may obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE2.0


*


* Unless required by applicable law or agreed to in writing, software


* distributed under the License is distributed on an "AS IS" BASIS,


* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


* See the License for the specific language governing permissions and


* limitations under the License.


*/




MathJax.Extension["TeX/extpfeil"]={version:"2.7.5"};MathJax.Hub.Register.StartupHook("TeX Jax Ready",function(){var b=MathJax.InputJax.TeX,a=b.Definitions;a.Add({macros:{xtwoheadrightarrow:["Extension","AMSmath"],xtwoheadleftarrow:["Extension","AMSmath"],xmapsto:["Extension","AMSmath"],xlongequal:["Extension","AMSmath"],xtofrom:["Extension","AMSmath"],Newextarrow:["Extension","AMSmath"]}},null,true);MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function(){MathJax.Hub.Insert(a,{macros:{xtwoheadrightarrow:["xArrow",8608,12,16],xtwoheadleftarrow:["xArrow",8606,17,13],xmapsto:["xArrow",8614,6,7],xlongequal:["xArrow",61,7,7],xtofrom:["xArrow",8644,12,12],Newextarrow:"NewExtArrow"}})});b.Parse.Augment({NewExtArrow:function(c){var e=this.GetArgument(c),f=this.GetArgument(c),d=this.GetArgument(c);if(!e.match(/^\\([az]+.)$/i)){b.Error(["NewextarrowArg1","First argument to %1 must be a control sequence name",c])}if(!f.match(/^(\d+),(\d+)$/)){b.Error(["NewextarrowArg2","Second argument to %1 must be two integers separated by a comma",c])}if(!d.match(/^(\d+0x[09AF]+)$/i)){b.Error(["NewextarrowArg3","Third argument to %1 must be a unicode character number",c])}e=e.substr(1);f=f.split(",");d=parseInt(d);this.setDef(e,["xArrow",d,parseInt(f[0]),parseInt(f[1])])}});MathJax.Hub.Startup.signal.Post("TeX extpfeil Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/extpfeil.js");
