OSDN Git Service

Py 3 handles exception propagation a little differently?
[joypy/Thun.git] / docs / Types.html
1 <!DOCTYPE html>
2 <html>
3 <head><meta charset="utf-8" />
4
5 <title>Types</title>
6
7 <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
8 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
9
10
11
12 <style type="text/css">
13     /*!
14 *
15 * Twitter Bootstrap
16 *
17 */
18 /*!
19  * Bootstrap v3.3.7 (http://getbootstrap.com)
20  * Copyright 2011-2016 Twitter, Inc.
21  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
22  */
23 /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
24 html {
25   font-family: sans-serif;
26   -ms-text-size-adjust: 100%;
27   -webkit-text-size-adjust: 100%;
28 }
29 body {
30   margin: 0;
31 }
32 article,
33 aside,
34 details,
35 figcaption,
36 figure,
37 footer,
38 header,
39 hgroup,
40 main,
41 menu,
42 nav,
43 section,
44 summary {
45   display: block;
46 }
47 audio,
48 canvas,
49 progress,
50 video {
51   display: inline-block;
52   vertical-align: baseline;
53 }
54 audio:not([controls]) {
55   display: none;
56   height: 0;
57 }
58 [hidden],
59 template {
60   display: none;
61 }
62 a {
63   background-color: transparent;
64 }
65 a:active,
66 a:hover {
67   outline: 0;
68 }
69 abbr[title] {
70   border-bottom: 1px dotted;
71 }
72 b,
73 strong {
74   font-weight: bold;
75 }
76 dfn {
77   font-style: italic;
78 }
79 h1 {
80   font-size: 2em;
81   margin: 0.67em 0;
82 }
83 mark {
84   background: #ff0;
85   color: #000;
86 }
87 small {
88   font-size: 80%;
89 }
90 sub,
91 sup {
92   font-size: 75%;
93   line-height: 0;
94   position: relative;
95   vertical-align: baseline;
96 }
97 sup {
98   top: -0.5em;
99 }
100 sub {
101   bottom: -0.25em;
102 }
103 img {
104   border: 0;
105 }
106 svg:not(:root) {
107   overflow: hidden;
108 }
109 figure {
110   margin: 1em 40px;
111 }
112 hr {
113   box-sizing: content-box;
114   height: 0;
115 }
116 pre {
117   overflow: auto;
118 }
119 code,
120 kbd,
121 pre,
122 samp {
123   font-family: monospace, monospace;
124   font-size: 1em;
125 }
126 button,
127 input,
128 optgroup,
129 select,
130 textarea {
131   color: inherit;
132   font: inherit;
133   margin: 0;
134 }
135 button {
136   overflow: visible;
137 }
138 button,
139 select {
140   text-transform: none;
141 }
142 button,
143 html input[type="button"],
144 input[type="reset"],
145 input[type="submit"] {
146   -webkit-appearance: button;
147   cursor: pointer;
148 }
149 button[disabled],
150 html input[disabled] {
151   cursor: default;
152 }
153 button::-moz-focus-inner,
154 input::-moz-focus-inner {
155   border: 0;
156   padding: 0;
157 }
158 input {
159   line-height: normal;
160 }
161 input[type="checkbox"],
162 input[type="radio"] {
163   box-sizing: border-box;
164   padding: 0;
165 }
166 input[type="number"]::-webkit-inner-spin-button,
167 input[type="number"]::-webkit-outer-spin-button {
168   height: auto;
169 }
170 input[type="search"] {
171   -webkit-appearance: textfield;
172   box-sizing: content-box;
173 }
174 input[type="search"]::-webkit-search-cancel-button,
175 input[type="search"]::-webkit-search-decoration {
176   -webkit-appearance: none;
177 }
178 fieldset {
179   border: 1px solid #c0c0c0;
180   margin: 0 2px;
181   padding: 0.35em 0.625em 0.75em;
182 }
183 legend {
184   border: 0;
185   padding: 0;
186 }
187 textarea {
188   overflow: auto;
189 }
190 optgroup {
191   font-weight: bold;
192 }
193 table {
194   border-collapse: collapse;
195   border-spacing: 0;
196 }
197 td,
198 th {
199   padding: 0;
200 }
201 /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
202 @media print {
203   *,
204   *:before,
205   *:after {
206     background: transparent !important;
207     box-shadow: none !important;
208     text-shadow: none !important;
209   }
210   a,
211   a:visited {
212     text-decoration: underline;
213   }
214   a[href]:after {
215     content: " (" attr(href) ")";
216   }
217   abbr[title]:after {
218     content: " (" attr(title) ")";
219   }
220   a[href^="#"]:after,
221   a[href^="javascript:"]:after {
222     content: "";
223   }
224   pre,
225   blockquote {
226     border: 1px solid #999;
227     page-break-inside: avoid;
228   }
229   thead {
230     display: table-header-group;
231   }
232   tr,
233   img {
234     page-break-inside: avoid;
235   }
236   img {
237     max-width: 100% !important;
238   }
239   p,
240   h2,
241   h3 {
242     orphans: 3;
243     widows: 3;
244   }
245   h2,
246   h3 {
247     page-break-after: avoid;
248   }
249   .navbar {
250     display: none;
251   }
252   .btn > .caret,
253   .dropup > .btn > .caret {
254     border-top-color: #000 !important;
255   }
256   .label {
257     border: 1px solid #000;
258   }
259   .table {
260     border-collapse: collapse !important;
261   }
262   .table td,
263   .table th {
264     background-color: #fff !important;
265   }
266   .table-bordered th,
267   .table-bordered td {
268     border: 1px solid #ddd !important;
269   }
270 }
271 @font-face {
272   font-family: 'Glyphicons Halflings';
273   src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
274   src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
275 }
276 .glyphicon {
277   position: relative;
278   top: 1px;
279   display: inline-block;
280   font-family: 'Glyphicons Halflings';
281   font-style: normal;
282   font-weight: normal;
283   line-height: 1;
284   -webkit-font-smoothing: antialiased;
285   -moz-osx-font-smoothing: grayscale;
286 }
287 .glyphicon-asterisk:before {
288   content: "\002a";
289 }
290 .glyphicon-plus:before {
291   content: "\002b";
292 }
293 .glyphicon-euro:before,
294 .glyphicon-eur:before {
295   content: "\20ac";
296 }
297 .glyphicon-minus:before {
298   content: "\2212";
299 }
300 .glyphicon-cloud:before {
301   content: "\2601";
302 }
303 .glyphicon-envelope:before {
304   content: "\2709";
305 }
306 .glyphicon-pencil:before {
307   content: "\270f";
308 }
309 .glyphicon-glass:before {
310   content: "\e001";
311 }
312 .glyphicon-music:before {
313   content: "\e002";
314 }
315 .glyphicon-search:before {
316   content: "\e003";
317 }
318 .glyphicon-heart:before {
319   content: "\e005";
320 }
321 .glyphicon-star:before {
322   content: "\e006";
323 }
324 .glyphicon-star-empty:before {
325   content: "\e007";
326 }
327 .glyphicon-user:before {
328   content: "\e008";
329 }
330 .glyphicon-film:before {
331   content: "\e009";
332 }
333 .glyphicon-th-large:before {
334   content: "\e010";
335 }
336 .glyphicon-th:before {
337   content: "\e011";
338 }
339 .glyphicon-th-list:before {
340   content: "\e012";
341 }
342 .glyphicon-ok:before {
343   content: "\e013";
344 }
345 .glyphicon-remove:before {
346   content: "\e014";
347 }
348 .glyphicon-zoom-in:before {
349   content: "\e015";
350 }
351 .glyphicon-zoom-out:before {
352   content: "\e016";
353 }
354 .glyphicon-off:before {
355   content: "\e017";
356 }
357 .glyphicon-signal:before {
358   content: "\e018";
359 }
360 .glyphicon-cog:before {
361   content: "\e019";
362 }
363 .glyphicon-trash:before {
364   content: "\e020";
365 }
366 .glyphicon-home:before {
367   content: "\e021";
368 }
369 .glyphicon-file:before {
370   content: "\e022";
371 }
372 .glyphicon-time:before {
373   content: "\e023";
374 }
375 .glyphicon-road:before {
376   content: "\e024";
377 }
378 .glyphicon-download-alt:before {
379   content: "\e025";
380 }
381 .glyphicon-download:before {
382   content: "\e026";
383 }
384 .glyphicon-upload:before {
385   content: "\e027";
386 }
387 .glyphicon-inbox:before {
388   content: "\e028";
389 }
390 .glyphicon-play-circle:before {
391   content: "\e029";
392 }
393 .glyphicon-repeat:before {
394   content: "\e030";
395 }
396 .glyphicon-refresh:before {
397   content: "\e031";
398 }
399 .glyphicon-list-alt:before {
400   content: "\e032";
401 }
402 .glyphicon-lock:before {
403   content: "\e033";
404 }
405 .glyphicon-flag:before {
406   content: "\e034";
407 }
408 .glyphicon-headphones:before {
409   content: "\e035";
410 }
411 .glyphicon-volume-off:before {
412   content: "\e036";
413 }
414 .glyphicon-volume-down:before {
415   content: "\e037";
416 }
417 .glyphicon-volume-up:before {
418   content: "\e038";
419 }
420 .glyphicon-qrcode:before {
421   content: "\e039";
422 }
423 .glyphicon-barcode:before {
424   content: "\e040";
425 }
426 .glyphicon-tag:before {
427   content: "\e041";
428 }
429 .glyphicon-tags:before {
430   content: "\e042";
431 }
432 .glyphicon-book:before {
433   content: "\e043";
434 }
435 .glyphicon-bookmark:before {
436   content: "\e044";
437 }
438 .glyphicon-print:before {
439   content: "\e045";
440 }
441 .glyphicon-camera:before {
442   content: "\e046";
443 }
444 .glyphicon-font:before {
445   content: "\e047";
446 }
447 .glyphicon-bold:before {
448   content: "\e048";
449 }
450 .glyphicon-italic:before {
451   content: "\e049";
452 }
453 .glyphicon-text-height:before {
454   content: "\e050";
455 }
456 .glyphicon-text-width:before {
457   content: "\e051";
458 }
459 .glyphicon-align-left:before {
460   content: "\e052";
461 }
462 .glyphicon-align-center:before {
463   content: "\e053";
464 }
465 .glyphicon-align-right:before {
466   content: "\e054";
467 }
468 .glyphicon-align-justify:before {
469   content: "\e055";
470 }
471 .glyphicon-list:before {
472   content: "\e056";
473 }
474 .glyphicon-indent-left:before {
475   content: "\e057";
476 }
477 .glyphicon-indent-right:before {
478   content: "\e058";
479 }
480 .glyphicon-facetime-video:before {
481   content: "\e059";
482 }
483 .glyphicon-picture:before {
484   content: "\e060";
485 }
486 .glyphicon-map-marker:before {
487   content: "\e062";
488 }
489 .glyphicon-adjust:before {
490   content: "\e063";
491 }
492 .glyphicon-tint:before {
493   content: "\e064";
494 }
495 .glyphicon-edit:before {
496   content: "\e065";
497 }
498 .glyphicon-share:before {
499   content: "\e066";
500 }
501 .glyphicon-check:before {
502   content: "\e067";
503 }
504 .glyphicon-move:before {
505   content: "\e068";
506 }
507 .glyphicon-step-backward:before {
508   content: "\e069";
509 }
510 .glyphicon-fast-backward:before {
511   content: "\e070";
512 }
513 .glyphicon-backward:before {
514   content: "\e071";
515 }
516 .glyphicon-play:before {
517   content: "\e072";
518 }
519 .glyphicon-pause:before {
520   content: "\e073";
521 }
522 .glyphicon-stop:before {
523   content: "\e074";
524 }
525 .glyphicon-forward:before {
526   content: "\e075";
527 }
528 .glyphicon-fast-forward:before {
529   content: "\e076";
530 }
531 .glyphicon-step-forward:before {
532   content: "\e077";
533 }
534 .glyphicon-eject:before {
535   content: "\e078";
536 }
537 .glyphicon-chevron-left:before {
538   content: "\e079";
539 }
540 .glyphicon-chevron-right:before {
541   content: "\e080";
542 }
543 .glyphicon-plus-sign:before {
544   content: "\e081";
545 }
546 .glyphicon-minus-sign:before {
547   content: "\e082";
548 }
549 .glyphicon-remove-sign:before {
550   content: "\e083";
551 }
552 .glyphicon-ok-sign:before {
553   content: "\e084";
554 }
555 .glyphicon-question-sign:before {
556   content: "\e085";
557 }
558 .glyphicon-info-sign:before {
559   content: "\e086";
560 }
561 .glyphicon-screenshot:before {
562   content: "\e087";
563 }
564 .glyphicon-remove-circle:before {
565   content: "\e088";
566 }
567 .glyphicon-ok-circle:before {
568   content: "\e089";
569 }
570 .glyphicon-ban-circle:before {
571   content: "\e090";
572 }
573 .glyphicon-arrow-left:before {
574   content: "\e091";
575 }
576 .glyphicon-arrow-right:before {
577   content: "\e092";
578 }
579 .glyphicon-arrow-up:before {
580   content: "\e093";
581 }
582 .glyphicon-arrow-down:before {
583   content: "\e094";
584 }
585 .glyphicon-share-alt:before {
586   content: "\e095";
587 }
588 .glyphicon-resize-full:before {
589   content: "\e096";
590 }
591 .glyphicon-resize-small:before {
592   content: "\e097";
593 }
594 .glyphicon-exclamation-sign:before {
595   content: "\e101";
596 }
597 .glyphicon-gift:before {
598   content: "\e102";
599 }
600 .glyphicon-leaf:before {
601   content: "\e103";
602 }
603 .glyphicon-fire:before {
604   content: "\e104";
605 }
606 .glyphicon-eye-open:before {
607   content: "\e105";
608 }
609 .glyphicon-eye-close:before {
610   content: "\e106";
611 }
612 .glyphicon-warning-sign:before {
613   content: "\e107";
614 }
615 .glyphicon-plane:before {
616   content: "\e108";
617 }
618 .glyphicon-calendar:before {
619   content: "\e109";
620 }
621 .glyphicon-random:before {
622   content: "\e110";
623 }
624 .glyphicon-comment:before {
625   content: "\e111";
626 }
627 .glyphicon-magnet:before {
628   content: "\e112";
629 }
630 .glyphicon-chevron-up:before {
631   content: "\e113";
632 }
633 .glyphicon-chevron-down:before {
634   content: "\e114";
635 }
636 .glyphicon-retweet:before {
637   content: "\e115";
638 }
639 .glyphicon-shopping-cart:before {
640   content: "\e116";
641 }
642 .glyphicon-folder-close:before {
643   content: "\e117";
644 }
645 .glyphicon-folder-open:before {
646   content: "\e118";
647 }
648 .glyphicon-resize-vertical:before {
649   content: "\e119";
650 }
651 .glyphicon-resize-horizontal:before {
652   content: "\e120";
653 }
654 .glyphicon-hdd:before {
655   content: "\e121";
656 }
657 .glyphicon-bullhorn:before {
658   content: "\e122";
659 }
660 .glyphicon-bell:before {
661   content: "\e123";
662 }
663 .glyphicon-certificate:before {
664   content: "\e124";
665 }
666 .glyphicon-thumbs-up:before {
667   content: "\e125";
668 }
669 .glyphicon-thumbs-down:before {
670   content: "\e126";
671 }
672 .glyphicon-hand-right:before {
673   content: "\e127";
674 }
675 .glyphicon-hand-left:before {
676   content: "\e128";
677 }
678 .glyphicon-hand-up:before {
679   content: "\e129";
680 }
681 .glyphicon-hand-down:before {
682   content: "\e130";
683 }
684 .glyphicon-circle-arrow-right:before {
685   content: "\e131";
686 }
687 .glyphicon-circle-arrow-left:before {
688   content: "\e132";
689 }
690 .glyphicon-circle-arrow-up:before {
691   content: "\e133";
692 }
693 .glyphicon-circle-arrow-down:before {
694   content: "\e134";
695 }
696 .glyphicon-globe:before {
697   content: "\e135";
698 }
699 .glyphicon-wrench:before {
700   content: "\e136";
701 }
702 .glyphicon-tasks:before {
703   content: "\e137";
704 }
705 .glyphicon-filter:before {
706   content: "\e138";
707 }
708 .glyphicon-briefcase:before {
709   content: "\e139";
710 }
711 .glyphicon-fullscreen:before {
712   content: "\e140";
713 }
714 .glyphicon-dashboard:before {
715   content: "\e141";
716 }
717 .glyphicon-paperclip:before {
718   content: "\e142";
719 }
720 .glyphicon-heart-empty:before {
721   content: "\e143";
722 }
723 .glyphicon-link:before {
724   content: "\e144";
725 }
726 .glyphicon-phone:before {
727   content: "\e145";
728 }
729 .glyphicon-pushpin:before {
730   content: "\e146";
731 }
732 .glyphicon-usd:before {
733   content: "\e148";
734 }
735 .glyphicon-gbp:before {
736   content: "\e149";
737 }
738 .glyphicon-sort:before {
739   content: "\e150";
740 }
741 .glyphicon-sort-by-alphabet:before {
742   content: "\e151";
743 }
744 .glyphicon-sort-by-alphabet-alt:before {
745   content: "\e152";
746 }
747 .glyphicon-sort-by-order:before {
748   content: "\e153";
749 }
750 .glyphicon-sort-by-order-alt:before {
751   content: "\e154";
752 }
753 .glyphicon-sort-by-attributes:before {
754   content: "\e155";
755 }
756 .glyphicon-sort-by-attributes-alt:before {
757   content: "\e156";
758 }
759 .glyphicon-unchecked:before {
760   content: "\e157";
761 }
762 .glyphicon-expand:before {
763   content: "\e158";
764 }
765 .glyphicon-collapse-down:before {
766   content: "\e159";
767 }
768 .glyphicon-collapse-up:before {
769   content: "\e160";
770 }
771 .glyphicon-log-in:before {
772   content: "\e161";
773 }
774 .glyphicon-flash:before {
775   content: "\e162";
776 }
777 .glyphicon-log-out:before {
778   content: "\e163";
779 }
780 .glyphicon-new-window:before {
781   content: "\e164";
782 }
783 .glyphicon-record:before {
784   content: "\e165";
785 }
786 .glyphicon-save:before {
787   content: "\e166";
788 }
789 .glyphicon-open:before {
790   content: "\e167";
791 }
792 .glyphicon-saved:before {
793   content: "\e168";
794 }
795 .glyphicon-import:before {
796   content: "\e169";
797 }
798 .glyphicon-export:before {
799   content: "\e170";
800 }
801 .glyphicon-send:before {
802   content: "\e171";
803 }
804 .glyphicon-floppy-disk:before {
805   content: "\e172";
806 }
807 .glyphicon-floppy-saved:before {
808   content: "\e173";
809 }
810 .glyphicon-floppy-remove:before {
811   content: "\e174";
812 }
813 .glyphicon-floppy-save:before {
814   content: "\e175";
815 }
816 .glyphicon-floppy-open:before {
817   content: "\e176";
818 }
819 .glyphicon-credit-card:before {
820   content: "\e177";
821 }
822 .glyphicon-transfer:before {
823   content: "\e178";
824 }
825 .glyphicon-cutlery:before {
826   content: "\e179";
827 }
828 .glyphicon-header:before {
829   content: "\e180";
830 }
831 .glyphicon-compressed:before {
832   content: "\e181";
833 }
834 .glyphicon-earphone:before {
835   content: "\e182";
836 }
837 .glyphicon-phone-alt:before {
838   content: "\e183";
839 }
840 .glyphicon-tower:before {
841   content: "\e184";
842 }
843 .glyphicon-stats:before {
844   content: "\e185";
845 }
846 .glyphicon-sd-video:before {
847   content: "\e186";
848 }
849 .glyphicon-hd-video:before {
850   content: "\e187";
851 }
852 .glyphicon-subtitles:before {
853   content: "\e188";
854 }
855 .glyphicon-sound-stereo:before {
856   content: "\e189";
857 }
858 .glyphicon-sound-dolby:before {
859   content: "\e190";
860 }
861 .glyphicon-sound-5-1:before {
862   content: "\e191";
863 }
864 .glyphicon-sound-6-1:before {
865   content: "\e192";
866 }
867 .glyphicon-sound-7-1:before {
868   content: "\e193";
869 }
870 .glyphicon-copyright-mark:before {
871   content: "\e194";
872 }
873 .glyphicon-registration-mark:before {
874   content: "\e195";
875 }
876 .glyphicon-cloud-download:before {
877   content: "\e197";
878 }
879 .glyphicon-cloud-upload:before {
880   content: "\e198";
881 }
882 .glyphicon-tree-conifer:before {
883   content: "\e199";
884 }
885 .glyphicon-tree-deciduous:before {
886   content: "\e200";
887 }
888 .glyphicon-cd:before {
889   content: "\e201";
890 }
891 .glyphicon-save-file:before {
892   content: "\e202";
893 }
894 .glyphicon-open-file:before {
895   content: "\e203";
896 }
897 .glyphicon-level-up:before {
898   content: "\e204";
899 }
900 .glyphicon-copy:before {
901   content: "\e205";
902 }
903 .glyphicon-paste:before {
904   content: "\e206";
905 }
906 .glyphicon-alert:before {
907   content: "\e209";
908 }
909 .glyphicon-equalizer:before {
910   content: "\e210";
911 }
912 .glyphicon-king:before {
913   content: "\e211";
914 }
915 .glyphicon-queen:before {
916   content: "\e212";
917 }
918 .glyphicon-pawn:before {
919   content: "\e213";
920 }
921 .glyphicon-bishop:before {
922   content: "\e214";
923 }
924 .glyphicon-knight:before {
925   content: "\e215";
926 }
927 .glyphicon-baby-formula:before {
928   content: "\e216";
929 }
930 .glyphicon-tent:before {
931   content: "\26fa";
932 }
933 .glyphicon-blackboard:before {
934   content: "\e218";
935 }
936 .glyphicon-bed:before {
937   content: "\e219";
938 }
939 .glyphicon-apple:before {
940   content: "\f8ff";
941 }
942 .glyphicon-erase:before {
943   content: "\e221";
944 }
945 .glyphicon-hourglass:before {
946   content: "\231b";
947 }
948 .glyphicon-lamp:before {
949   content: "\e223";
950 }
951 .glyphicon-duplicate:before {
952   content: "\e224";
953 }
954 .glyphicon-piggy-bank:before {
955   content: "\e225";
956 }
957 .glyphicon-scissors:before {
958   content: "\e226";
959 }
960 .glyphicon-bitcoin:before {
961   content: "\e227";
962 }
963 .glyphicon-btc:before {
964   content: "\e227";
965 }
966 .glyphicon-xbt:before {
967   content: "\e227";
968 }
969 .glyphicon-yen:before {
970   content: "\00a5";
971 }
972 .glyphicon-jpy:before {
973   content: "\00a5";
974 }
975 .glyphicon-ruble:before {
976   content: "\20bd";
977 }
978 .glyphicon-rub:before {
979   content: "\20bd";
980 }
981 .glyphicon-scale:before {
982   content: "\e230";
983 }
984 .glyphicon-ice-lolly:before {
985   content: "\e231";
986 }
987 .glyphicon-ice-lolly-tasted:before {
988   content: "\e232";
989 }
990 .glyphicon-education:before {
991   content: "\e233";
992 }
993 .glyphicon-option-horizontal:before {
994   content: "\e234";
995 }
996 .glyphicon-option-vertical:before {
997   content: "\e235";
998 }
999 .glyphicon-menu-hamburger:before {
1000   content: "\e236";
1001 }
1002 .glyphicon-modal-window:before {
1003   content: "\e237";
1004 }
1005 .glyphicon-oil:before {
1006   content: "\e238";
1007 }
1008 .glyphicon-grain:before {
1009   content: "\e239";
1010 }
1011 .glyphicon-sunglasses:before {
1012   content: "\e240";
1013 }
1014 .glyphicon-text-size:before {
1015   content: "\e241";
1016 }
1017 .glyphicon-text-color:before {
1018   content: "\e242";
1019 }
1020 .glyphicon-text-background:before {
1021   content: "\e243";
1022 }
1023 .glyphicon-object-align-top:before {
1024   content: "\e244";
1025 }
1026 .glyphicon-object-align-bottom:before {
1027   content: "\e245";
1028 }
1029 .glyphicon-object-align-horizontal:before {
1030   content: "\e246";
1031 }
1032 .glyphicon-object-align-left:before {
1033   content: "\e247";
1034 }
1035 .glyphicon-object-align-vertical:before {
1036   content: "\e248";
1037 }
1038 .glyphicon-object-align-right:before {
1039   content: "\e249";
1040 }
1041 .glyphicon-triangle-right:before {
1042   content: "\e250";
1043 }
1044 .glyphicon-triangle-left:before {
1045   content: "\e251";
1046 }
1047 .glyphicon-triangle-bottom:before {
1048   content: "\e252";
1049 }
1050 .glyphicon-triangle-top:before {
1051   content: "\e253";
1052 }
1053 .glyphicon-console:before {
1054   content: "\e254";
1055 }
1056 .glyphicon-superscript:before {
1057   content: "\e255";
1058 }
1059 .glyphicon-subscript:before {
1060   content: "\e256";
1061 }
1062 .glyphicon-menu-left:before {
1063   content: "\e257";
1064 }
1065 .glyphicon-menu-right:before {
1066   content: "\e258";
1067 }
1068 .glyphicon-menu-down:before {
1069   content: "\e259";
1070 }
1071 .glyphicon-menu-up:before {
1072   content: "\e260";
1073 }
1074 * {
1075   -webkit-box-sizing: border-box;
1076   -moz-box-sizing: border-box;
1077   box-sizing: border-box;
1078 }
1079 *:before,
1080 *:after {
1081   -webkit-box-sizing: border-box;
1082   -moz-box-sizing: border-box;
1083   box-sizing: border-box;
1084 }
1085 html {
1086   font-size: 10px;
1087   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
1088 }
1089 body {
1090   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1091   font-size: 13px;
1092   line-height: 1.42857143;
1093   color: #000;
1094   background-color: #fff;
1095 }
1096 input,
1097 button,
1098 select,
1099 textarea {
1100   font-family: inherit;
1101   font-size: inherit;
1102   line-height: inherit;
1103 }
1104 a {
1105   color: #337ab7;
1106   text-decoration: none;
1107 }
1108 a:hover,
1109 a:focus {
1110   color: #23527c;
1111   text-decoration: underline;
1112 }
1113 a:focus {
1114   outline: 5px auto -webkit-focus-ring-color;
1115   outline-offset: -2px;
1116 }
1117 figure {
1118   margin: 0;
1119 }
1120 img {
1121   vertical-align: middle;
1122 }
1123 .img-responsive,
1124 .thumbnail > img,
1125 .thumbnail a > img,
1126 .carousel-inner > .item > img,
1127 .carousel-inner > .item > a > img {
1128   display: block;
1129   max-width: 100%;
1130   height: auto;
1131 }
1132 .img-rounded {
1133   border-radius: 3px;
1134 }
1135 .img-thumbnail {
1136   padding: 4px;
1137   line-height: 1.42857143;
1138   background-color: #fff;
1139   border: 1px solid #ddd;
1140   border-radius: 2px;
1141   -webkit-transition: all 0.2s ease-in-out;
1142   -o-transition: all 0.2s ease-in-out;
1143   transition: all 0.2s ease-in-out;
1144   display: inline-block;
1145   max-width: 100%;
1146   height: auto;
1147 }
1148 .img-circle {
1149   border-radius: 50%;
1150 }
1151 hr {
1152   margin-top: 18px;
1153   margin-bottom: 18px;
1154   border: 0;
1155   border-top: 1px solid #eeeeee;
1156 }
1157 .sr-only {
1158   position: absolute;
1159   width: 1px;
1160   height: 1px;
1161   margin: -1px;
1162   padding: 0;
1163   overflow: hidden;
1164   clip: rect(0, 0, 0, 0);
1165   border: 0;
1166 }
1167 .sr-only-focusable:active,
1168 .sr-only-focusable:focus {
1169   position: static;
1170   width: auto;
1171   height: auto;
1172   margin: 0;
1173   overflow: visible;
1174   clip: auto;
1175 }
1176 [role="button"] {
1177   cursor: pointer;
1178 }
1179 h1,
1180 h2,
1181 h3,
1182 h4,
1183 h5,
1184 h6,
1185 .h1,
1186 .h2,
1187 .h3,
1188 .h4,
1189 .h5,
1190 .h6 {
1191   font-family: inherit;
1192   font-weight: 500;
1193   line-height: 1.1;
1194   color: inherit;
1195 }
1196 h1 small,
1197 h2 small,
1198 h3 small,
1199 h4 small,
1200 h5 small,
1201 h6 small,
1202 .h1 small,
1203 .h2 small,
1204 .h3 small,
1205 .h4 small,
1206 .h5 small,
1207 .h6 small,
1208 h1 .small,
1209 h2 .small,
1210 h3 .small,
1211 h4 .small,
1212 h5 .small,
1213 h6 .small,
1214 .h1 .small,
1215 .h2 .small,
1216 .h3 .small,
1217 .h4 .small,
1218 .h5 .small,
1219 .h6 .small {
1220   font-weight: normal;
1221   line-height: 1;
1222   color: #777777;
1223 }
1224 h1,
1225 .h1,
1226 h2,
1227 .h2,
1228 h3,
1229 .h3 {
1230   margin-top: 18px;
1231   margin-bottom: 9px;
1232 }
1233 h1 small,
1234 .h1 small,
1235 h2 small,
1236 .h2 small,
1237 h3 small,
1238 .h3 small,
1239 h1 .small,
1240 .h1 .small,
1241 h2 .small,
1242 .h2 .small,
1243 h3 .small,
1244 .h3 .small {
1245   font-size: 65%;
1246 }
1247 h4,
1248 .h4,
1249 h5,
1250 .h5,
1251 h6,
1252 .h6 {
1253   margin-top: 9px;
1254   margin-bottom: 9px;
1255 }
1256 h4 small,
1257 .h4 small,
1258 h5 small,
1259 .h5 small,
1260 h6 small,
1261 .h6 small,
1262 h4 .small,
1263 .h4 .small,
1264 h5 .small,
1265 .h5 .small,
1266 h6 .small,
1267 .h6 .small {
1268   font-size: 75%;
1269 }
1270 h1,
1271 .h1 {
1272   font-size: 33px;
1273 }
1274 h2,
1275 .h2 {
1276   font-size: 27px;
1277 }
1278 h3,
1279 .h3 {
1280   font-size: 23px;
1281 }
1282 h4,
1283 .h4 {
1284   font-size: 17px;
1285 }
1286 h5,
1287 .h5 {
1288   font-size: 13px;
1289 }
1290 h6,
1291 .h6 {
1292   font-size: 12px;
1293 }
1294 p {
1295   margin: 0 0 9px;
1296 }
1297 .lead {
1298   margin-bottom: 18px;
1299   font-size: 14px;
1300   font-weight: 300;
1301   line-height: 1.4;
1302 }
1303 @media (min-width: 768px) {
1304   .lead {
1305     font-size: 19.5px;
1306   }
1307 }
1308 small,
1309 .small {
1310   font-size: 92%;
1311 }
1312 mark,
1313 .mark {
1314   background-color: #fcf8e3;
1315   padding: .2em;
1316 }
1317 .text-left {
1318   text-align: left;
1319 }
1320 .text-right {
1321   text-align: right;
1322 }
1323 .text-center {
1324   text-align: center;
1325 }
1326 .text-justify {
1327   text-align: justify;
1328 }
1329 .text-nowrap {
1330   white-space: nowrap;
1331 }
1332 .text-lowercase {
1333   text-transform: lowercase;
1334 }
1335 .text-uppercase {
1336   text-transform: uppercase;
1337 }
1338 .text-capitalize {
1339   text-transform: capitalize;
1340 }
1341 .text-muted {
1342   color: #777777;
1343 }
1344 .text-primary {
1345   color: #337ab7;
1346 }
1347 a.text-primary:hover,
1348 a.text-primary:focus {
1349   color: #286090;
1350 }
1351 .text-success {
1352   color: #3c763d;
1353 }
1354 a.text-success:hover,
1355 a.text-success:focus {
1356   color: #2b542c;
1357 }
1358 .text-info {
1359   color: #31708f;
1360 }
1361 a.text-info:hover,
1362 a.text-info:focus {
1363   color: #245269;
1364 }
1365 .text-warning {
1366   color: #8a6d3b;
1367 }
1368 a.text-warning:hover,
1369 a.text-warning:focus {
1370   color: #66512c;
1371 }
1372 .text-danger {
1373   color: #a94442;
1374 }
1375 a.text-danger:hover,
1376 a.text-danger:focus {
1377   color: #843534;
1378 }
1379 .bg-primary {
1380   color: #fff;
1381   background-color: #337ab7;
1382 }
1383 a.bg-primary:hover,
1384 a.bg-primary:focus {
1385   background-color: #286090;
1386 }
1387 .bg-success {
1388   background-color: #dff0d8;
1389 }
1390 a.bg-success:hover,
1391 a.bg-success:focus {
1392   background-color: #c1e2b3;
1393 }
1394 .bg-info {
1395   background-color: #d9edf7;
1396 }
1397 a.bg-info:hover,
1398 a.bg-info:focus {
1399   background-color: #afd9ee;
1400 }
1401 .bg-warning {
1402   background-color: #fcf8e3;
1403 }
1404 a.bg-warning:hover,
1405 a.bg-warning:focus {
1406   background-color: #f7ecb5;
1407 }
1408 .bg-danger {
1409   background-color: #f2dede;
1410 }
1411 a.bg-danger:hover,
1412 a.bg-danger:focus {
1413   background-color: #e4b9b9;
1414 }
1415 .page-header {
1416   padding-bottom: 8px;
1417   margin: 36px 0 18px;
1418   border-bottom: 1px solid #eeeeee;
1419 }
1420 ul,
1421 ol {
1422   margin-top: 0;
1423   margin-bottom: 9px;
1424 }
1425 ul ul,
1426 ol ul,
1427 ul ol,
1428 ol ol {
1429   margin-bottom: 0;
1430 }
1431 .list-unstyled {
1432   padding-left: 0;
1433   list-style: none;
1434 }
1435 .list-inline {
1436   padding-left: 0;
1437   list-style: none;
1438   margin-left: -5px;
1439 }
1440 .list-inline > li {
1441   display: inline-block;
1442   padding-left: 5px;
1443   padding-right: 5px;
1444 }
1445 dl {
1446   margin-top: 0;
1447   margin-bottom: 18px;
1448 }
1449 dt,
1450 dd {
1451   line-height: 1.42857143;
1452 }
1453 dt {
1454   font-weight: bold;
1455 }
1456 dd {
1457   margin-left: 0;
1458 }
1459 @media (min-width: 541px) {
1460   .dl-horizontal dt {
1461     float: left;
1462     width: 160px;
1463     clear: left;
1464     text-align: right;
1465     overflow: hidden;
1466     text-overflow: ellipsis;
1467     white-space: nowrap;
1468   }
1469   .dl-horizontal dd {
1470     margin-left: 180px;
1471   }
1472 }
1473 abbr[title],
1474 abbr[data-original-title] {
1475   cursor: help;
1476   border-bottom: 1px dotted #777777;
1477 }
1478 .initialism {
1479   font-size: 90%;
1480   text-transform: uppercase;
1481 }
1482 blockquote {
1483   padding: 9px 18px;
1484   margin: 0 0 18px;
1485   font-size: inherit;
1486   border-left: 5px solid #eeeeee;
1487 }
1488 blockquote p:last-child,
1489 blockquote ul:last-child,
1490 blockquote ol:last-child {
1491   margin-bottom: 0;
1492 }
1493 blockquote footer,
1494 blockquote small,
1495 blockquote .small {
1496   display: block;
1497   font-size: 80%;
1498   line-height: 1.42857143;
1499   color: #777777;
1500 }
1501 blockquote footer:before,
1502 blockquote small:before,
1503 blockquote .small:before {
1504   content: '\2014 \00A0';
1505 }
1506 .blockquote-reverse,
1507 blockquote.pull-right {
1508   padding-right: 15px;
1509   padding-left: 0;
1510   border-right: 5px solid #eeeeee;
1511   border-left: 0;
1512   text-align: right;
1513 }
1514 .blockquote-reverse footer:before,
1515 blockquote.pull-right footer:before,
1516 .blockquote-reverse small:before,
1517 blockquote.pull-right small:before,
1518 .blockquote-reverse .small:before,
1519 blockquote.pull-right .small:before {
1520   content: '';
1521 }
1522 .blockquote-reverse footer:after,
1523 blockquote.pull-right footer:after,
1524 .blockquote-reverse small:after,
1525 blockquote.pull-right small:after,
1526 .blockquote-reverse .small:after,
1527 blockquote.pull-right .small:after {
1528   content: '\00A0 \2014';
1529 }
1530 address {
1531   margin-bottom: 18px;
1532   font-style: normal;
1533   line-height: 1.42857143;
1534 }
1535 code,
1536 kbd,
1537 pre,
1538 samp {
1539   font-family: monospace;
1540 }
1541 code {
1542   padding: 2px 4px;
1543   font-size: 90%;
1544   color: #c7254e;
1545   background-color: #f9f2f4;
1546   border-radius: 2px;
1547 }
1548 kbd {
1549   padding: 2px 4px;
1550   font-size: 90%;
1551   color: #888;
1552   background-color: transparent;
1553   border-radius: 1px;
1554   box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
1555 }
1556 kbd kbd {
1557   padding: 0;
1558   font-size: 100%;
1559   font-weight: bold;
1560   box-shadow: none;
1561 }
1562 pre {
1563   display: block;
1564   padding: 8.5px;
1565   margin: 0 0 9px;
1566   font-size: 12px;
1567   line-height: 1.42857143;
1568   word-break: break-all;
1569   word-wrap: break-word;
1570   color: #333333;
1571   background-color: #f5f5f5;
1572   border: 1px solid #ccc;
1573   border-radius: 2px;
1574 }
1575 pre code {
1576   padding: 0;
1577   font-size: inherit;
1578   color: inherit;
1579   white-space: pre-wrap;
1580   background-color: transparent;
1581   border-radius: 0;
1582 }
1583 .pre-scrollable {
1584   max-height: 340px;
1585   overflow-y: scroll;
1586 }
1587 .container {
1588   margin-right: auto;
1589   margin-left: auto;
1590   padding-left: 0px;
1591   padding-right: 0px;
1592 }
1593 @media (min-width: 768px) {
1594   .container {
1595     width: 768px;
1596   }
1597 }
1598 @media (min-width: 992px) {
1599   .container {
1600     width: 940px;
1601   }
1602 }
1603 @media (min-width: 1200px) {
1604   .container {
1605     width: 1140px;
1606   }
1607 }
1608 .container-fluid {
1609   margin-right: auto;
1610   margin-left: auto;
1611   padding-left: 0px;
1612   padding-right: 0px;
1613 }
1614 .row {
1615   margin-left: 0px;
1616   margin-right: 0px;
1617 }
1618 .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
1619   position: relative;
1620   min-height: 1px;
1621   padding-left: 0px;
1622   padding-right: 0px;
1623 }
1624 .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
1625   float: left;
1626 }
1627 .col-xs-12 {
1628   width: 100%;
1629 }
1630 .col-xs-11 {
1631   width: 91.66666667%;
1632 }
1633 .col-xs-10 {
1634   width: 83.33333333%;
1635 }
1636 .col-xs-9 {
1637   width: 75%;
1638 }
1639 .col-xs-8 {
1640   width: 66.66666667%;
1641 }
1642 .col-xs-7 {
1643   width: 58.33333333%;
1644 }
1645 .col-xs-6 {
1646   width: 50%;
1647 }
1648 .col-xs-5 {
1649   width: 41.66666667%;
1650 }
1651 .col-xs-4 {
1652   width: 33.33333333%;
1653 }
1654 .col-xs-3 {
1655   width: 25%;
1656 }
1657 .col-xs-2 {
1658   width: 16.66666667%;
1659 }
1660 .col-xs-1 {
1661   width: 8.33333333%;
1662 }
1663 .col-xs-pull-12 {
1664   right: 100%;
1665 }
1666 .col-xs-pull-11 {
1667   right: 91.66666667%;
1668 }
1669 .col-xs-pull-10 {
1670   right: 83.33333333%;
1671 }
1672 .col-xs-pull-9 {
1673   right: 75%;
1674 }
1675 .col-xs-pull-8 {
1676   right: 66.66666667%;
1677 }
1678 .col-xs-pull-7 {
1679   right: 58.33333333%;
1680 }
1681 .col-xs-pull-6 {
1682   right: 50%;
1683 }
1684 .col-xs-pull-5 {
1685   right: 41.66666667%;
1686 }
1687 .col-xs-pull-4 {
1688   right: 33.33333333%;
1689 }
1690 .col-xs-pull-3 {
1691   right: 25%;
1692 }
1693 .col-xs-pull-2 {
1694   right: 16.66666667%;
1695 }
1696 .col-xs-pull-1 {
1697   right: 8.33333333%;
1698 }
1699 .col-xs-pull-0 {
1700   right: auto;
1701 }
1702 .col-xs-push-12 {
1703   left: 100%;
1704 }
1705 .col-xs-push-11 {
1706   left: 91.66666667%;
1707 }
1708 .col-xs-push-10 {
1709   left: 83.33333333%;
1710 }
1711 .col-xs-push-9 {
1712   left: 75%;
1713 }
1714 .col-xs-push-8 {
1715   left: 66.66666667%;
1716 }
1717 .col-xs-push-7 {
1718   left: 58.33333333%;
1719 }
1720 .col-xs-push-6 {
1721   left: 50%;
1722 }
1723 .col-xs-push-5 {
1724   left: 41.66666667%;
1725 }
1726 .col-xs-push-4 {
1727   left: 33.33333333%;
1728 }
1729 .col-xs-push-3 {
1730   left: 25%;
1731 }
1732 .col-xs-push-2 {
1733   left: 16.66666667%;
1734 }
1735 .col-xs-push-1 {
1736   left: 8.33333333%;
1737 }
1738 .col-xs-push-0 {
1739   left: auto;
1740 }
1741 .col-xs-offset-12 {
1742   margin-left: 100%;
1743 }
1744 .col-xs-offset-11 {
1745   margin-left: 91.66666667%;
1746 }
1747 .col-xs-offset-10 {
1748   margin-left: 83.33333333%;
1749 }
1750 .col-xs-offset-9 {
1751   margin-left: 75%;
1752 }
1753 .col-xs-offset-8 {
1754   margin-left: 66.66666667%;
1755 }
1756 .col-xs-offset-7 {
1757   margin-left: 58.33333333%;
1758 }
1759 .col-xs-offset-6 {
1760   margin-left: 50%;
1761 }
1762 .col-xs-offset-5 {
1763   margin-left: 41.66666667%;
1764 }
1765 .col-xs-offset-4 {
1766   margin-left: 33.33333333%;
1767 }
1768 .col-xs-offset-3 {
1769   margin-left: 25%;
1770 }
1771 .col-xs-offset-2 {
1772   margin-left: 16.66666667%;
1773 }
1774 .col-xs-offset-1 {
1775   margin-left: 8.33333333%;
1776 }
1777 .col-xs-offset-0 {
1778   margin-left: 0%;
1779 }
1780 @media (min-width: 768px) {
1781   .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
1782     float: left;
1783   }
1784   .col-sm-12 {
1785     width: 100%;
1786   }
1787   .col-sm-11 {
1788     width: 91.66666667%;
1789   }
1790   .col-sm-10 {
1791     width: 83.33333333%;
1792   }
1793   .col-sm-9 {
1794     width: 75%;
1795   }
1796   .col-sm-8 {
1797     width: 66.66666667%;
1798   }
1799   .col-sm-7 {
1800     width: 58.33333333%;
1801   }
1802   .col-sm-6 {
1803     width: 50%;
1804   }
1805   .col-sm-5 {
1806     width: 41.66666667%;
1807   }
1808   .col-sm-4 {
1809     width: 33.33333333%;
1810   }
1811   .col-sm-3 {
1812     width: 25%;
1813   }
1814   .col-sm-2 {
1815     width: 16.66666667%;
1816   }
1817   .col-sm-1 {
1818     width: 8.33333333%;
1819   }
1820   .col-sm-pull-12 {
1821     right: 100%;
1822   }
1823   .col-sm-pull-11 {
1824     right: 91.66666667%;
1825   }
1826   .col-sm-pull-10 {
1827     right: 83.33333333%;
1828   }
1829   .col-sm-pull-9 {
1830     right: 75%;
1831   }
1832   .col-sm-pull-8 {
1833     right: 66.66666667%;
1834   }
1835   .col-sm-pull-7 {
1836     right: 58.33333333%;
1837   }
1838   .col-sm-pull-6 {
1839     right: 50%;
1840   }
1841   .col-sm-pull-5 {
1842     right: 41.66666667%;
1843   }
1844   .col-sm-pull-4 {
1845     right: 33.33333333%;
1846   }
1847   .col-sm-pull-3 {
1848     right: 25%;
1849   }
1850   .col-sm-pull-2 {
1851     right: 16.66666667%;
1852   }
1853   .col-sm-pull-1 {
1854     right: 8.33333333%;
1855   }
1856   .col-sm-pull-0 {
1857     right: auto;
1858   }
1859   .col-sm-push-12 {
1860     left: 100%;
1861   }
1862   .col-sm-push-11 {
1863     left: 91.66666667%;
1864   }
1865   .col-sm-push-10 {
1866     left: 83.33333333%;
1867   }
1868   .col-sm-push-9 {
1869     left: 75%;
1870   }
1871   .col-sm-push-8 {
1872     left: 66.66666667%;
1873   }
1874   .col-sm-push-7 {
1875     left: 58.33333333%;
1876   }
1877   .col-sm-push-6 {
1878     left: 50%;
1879   }
1880   .col-sm-push-5 {
1881     left: 41.66666667%;
1882   }
1883   .col-sm-push-4 {
1884     left: 33.33333333%;
1885   }
1886   .col-sm-push-3 {
1887     left: 25%;
1888   }
1889   .col-sm-push-2 {
1890     left: 16.66666667%;
1891   }
1892   .col-sm-push-1 {
1893     left: 8.33333333%;
1894   }
1895   .col-sm-push-0 {
1896     left: auto;
1897   }
1898   .col-sm-offset-12 {
1899     margin-left: 100%;
1900   }
1901   .col-sm-offset-11 {
1902     margin-left: 91.66666667%;
1903   }
1904   .col-sm-offset-10 {
1905     margin-left: 83.33333333%;
1906   }
1907   .col-sm-offset-9 {
1908     margin-left: 75%;
1909   }
1910   .col-sm-offset-8 {
1911     margin-left: 66.66666667%;
1912   }
1913   .col-sm-offset-7 {
1914     margin-left: 58.33333333%;
1915   }
1916   .col-sm-offset-6 {
1917     margin-left: 50%;
1918   }
1919   .col-sm-offset-5 {
1920     margin-left: 41.66666667%;
1921   }
1922   .col-sm-offset-4 {
1923     margin-left: 33.33333333%;
1924   }
1925   .col-sm-offset-3 {
1926     margin-left: 25%;
1927   }
1928   .col-sm-offset-2 {
1929     margin-left: 16.66666667%;
1930   }
1931   .col-sm-offset-1 {
1932     margin-left: 8.33333333%;
1933   }
1934   .col-sm-offset-0 {
1935     margin-left: 0%;
1936   }
1937 }
1938 @media (min-width: 992px) {
1939   .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
1940     float: left;
1941   }
1942   .col-md-12 {
1943     width: 100%;
1944   }
1945   .col-md-11 {
1946     width: 91.66666667%;
1947   }
1948   .col-md-10 {
1949     width: 83.33333333%;
1950   }
1951   .col-md-9 {
1952     width: 75%;
1953   }
1954   .col-md-8 {
1955     width: 66.66666667%;
1956   }
1957   .col-md-7 {
1958     width: 58.33333333%;
1959   }
1960   .col-md-6 {
1961     width: 50%;
1962   }
1963   .col-md-5 {
1964     width: 41.66666667%;
1965   }
1966   .col-md-4 {
1967     width: 33.33333333%;
1968   }
1969   .col-md-3 {
1970     width: 25%;
1971   }
1972   .col-md-2 {
1973     width: 16.66666667%;
1974   }
1975   .col-md-1 {
1976     width: 8.33333333%;
1977   }
1978   .col-md-pull-12 {
1979     right: 100%;
1980   }
1981   .col-md-pull-11 {
1982     right: 91.66666667%;
1983   }
1984   .col-md-pull-10 {
1985     right: 83.33333333%;
1986   }
1987   .col-md-pull-9 {
1988     right: 75%;
1989   }
1990   .col-md-pull-8 {
1991     right: 66.66666667%;
1992   }
1993   .col-md-pull-7 {
1994     right: 58.33333333%;
1995   }
1996   .col-md-pull-6 {
1997     right: 50%;
1998   }
1999   .col-md-pull-5 {
2000     right: 41.66666667%;
2001   }
2002   .col-md-pull-4 {
2003     right: 33.33333333%;
2004   }
2005   .col-md-pull-3 {
2006     right: 25%;
2007   }
2008   .col-md-pull-2 {
2009     right: 16.66666667%;
2010   }
2011   .col-md-pull-1 {
2012     right: 8.33333333%;
2013   }
2014   .col-md-pull-0 {
2015     right: auto;
2016   }
2017   .col-md-push-12 {
2018     left: 100%;
2019   }
2020   .col-md-push-11 {
2021     left: 91.66666667%;
2022   }
2023   .col-md-push-10 {
2024     left: 83.33333333%;
2025   }
2026   .col-md-push-9 {
2027     left: 75%;
2028   }
2029   .col-md-push-8 {
2030     left: 66.66666667%;
2031   }
2032   .col-md-push-7 {
2033     left: 58.33333333%;
2034   }
2035   .col-md-push-6 {
2036     left: 50%;
2037   }
2038   .col-md-push-5 {
2039     left: 41.66666667%;
2040   }
2041   .col-md-push-4 {
2042     left: 33.33333333%;
2043   }
2044   .col-md-push-3 {
2045     left: 25%;
2046   }
2047   .col-md-push-2 {
2048     left: 16.66666667%;
2049   }
2050   .col-md-push-1 {
2051     left: 8.33333333%;
2052   }
2053   .col-md-push-0 {
2054     left: auto;
2055   }
2056   .col-md-offset-12 {
2057     margin-left: 100%;
2058   }
2059   .col-md-offset-11 {
2060     margin-left: 91.66666667%;
2061   }
2062   .col-md-offset-10 {
2063     margin-left: 83.33333333%;
2064   }
2065   .col-md-offset-9 {
2066     margin-left: 75%;
2067   }
2068   .col-md-offset-8 {
2069     margin-left: 66.66666667%;
2070   }
2071   .col-md-offset-7 {
2072     margin-left: 58.33333333%;
2073   }
2074   .col-md-offset-6 {
2075     margin-left: 50%;
2076   }
2077   .col-md-offset-5 {
2078     margin-left: 41.66666667%;
2079   }
2080   .col-md-offset-4 {
2081     margin-left: 33.33333333%;
2082   }
2083   .col-md-offset-3 {
2084     margin-left: 25%;
2085   }
2086   .col-md-offset-2 {
2087     margin-left: 16.66666667%;
2088   }
2089   .col-md-offset-1 {
2090     margin-left: 8.33333333%;
2091   }
2092   .col-md-offset-0 {
2093     margin-left: 0%;
2094   }
2095 }
2096 @media (min-width: 1200px) {
2097   .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
2098     float: left;
2099   }
2100   .col-lg-12 {
2101     width: 100%;
2102   }
2103   .col-lg-11 {
2104     width: 91.66666667%;
2105   }
2106   .col-lg-10 {
2107     width: 83.33333333%;
2108   }
2109   .col-lg-9 {
2110     width: 75%;
2111   }
2112   .col-lg-8 {
2113     width: 66.66666667%;
2114   }
2115   .col-lg-7 {
2116     width: 58.33333333%;
2117   }
2118   .col-lg-6 {
2119     width: 50%;
2120   }
2121   .col-lg-5 {
2122     width: 41.66666667%;
2123   }
2124   .col-lg-4 {
2125     width: 33.33333333%;
2126   }
2127   .col-lg-3 {
2128     width: 25%;
2129   }
2130   .col-lg-2 {
2131     width: 16.66666667%;
2132   }
2133   .col-lg-1 {
2134     width: 8.33333333%;
2135   }
2136   .col-lg-pull-12 {
2137     right: 100%;
2138   }
2139   .col-lg-pull-11 {
2140     right: 91.66666667%;
2141   }
2142   .col-lg-pull-10 {
2143     right: 83.33333333%;
2144   }
2145   .col-lg-pull-9 {
2146     right: 75%;
2147   }
2148   .col-lg-pull-8 {
2149     right: 66.66666667%;
2150   }
2151   .col-lg-pull-7 {
2152     right: 58.33333333%;
2153   }
2154   .col-lg-pull-6 {
2155     right: 50%;
2156   }
2157   .col-lg-pull-5 {
2158     right: 41.66666667%;
2159   }
2160   .col-lg-pull-4 {
2161     right: 33.33333333%;
2162   }
2163   .col-lg-pull-3 {
2164     right: 25%;
2165   }
2166   .col-lg-pull-2 {
2167     right: 16.66666667%;
2168   }
2169   .col-lg-pull-1 {
2170     right: 8.33333333%;
2171   }
2172   .col-lg-pull-0 {
2173     right: auto;
2174   }
2175   .col-lg-push-12 {
2176     left: 100%;
2177   }
2178   .col-lg-push-11 {
2179     left: 91.66666667%;
2180   }
2181   .col-lg-push-10 {
2182     left: 83.33333333%;
2183   }
2184   .col-lg-push-9 {
2185     left: 75%;
2186   }
2187   .col-lg-push-8 {
2188     left: 66.66666667%;
2189   }
2190   .col-lg-push-7 {
2191     left: 58.33333333%;
2192   }
2193   .col-lg-push-6 {
2194     left: 50%;
2195   }
2196   .col-lg-push-5 {
2197     left: 41.66666667%;
2198   }
2199   .col-lg-push-4 {
2200     left: 33.33333333%;
2201   }
2202   .col-lg-push-3 {
2203     left: 25%;
2204   }
2205   .col-lg-push-2 {
2206     left: 16.66666667%;
2207   }
2208   .col-lg-push-1 {
2209     left: 8.33333333%;
2210   }
2211   .col-lg-push-0 {
2212     left: auto;
2213   }
2214   .col-lg-offset-12 {
2215     margin-left: 100%;
2216   }
2217   .col-lg-offset-11 {
2218     margin-left: 91.66666667%;
2219   }
2220   .col-lg-offset-10 {
2221     margin-left: 83.33333333%;
2222   }
2223   .col-lg-offset-9 {
2224     margin-left: 75%;
2225   }
2226   .col-lg-offset-8 {
2227     margin-left: 66.66666667%;
2228   }
2229   .col-lg-offset-7 {
2230     margin-left: 58.33333333%;
2231   }
2232   .col-lg-offset-6 {
2233     margin-left: 50%;
2234   }
2235   .col-lg-offset-5 {
2236     margin-left: 41.66666667%;
2237   }
2238   .col-lg-offset-4 {
2239     margin-left: 33.33333333%;
2240   }
2241   .col-lg-offset-3 {
2242     margin-left: 25%;
2243   }
2244   .col-lg-offset-2 {
2245     margin-left: 16.66666667%;
2246   }
2247   .col-lg-offset-1 {
2248     margin-left: 8.33333333%;
2249   }
2250   .col-lg-offset-0 {
2251     margin-left: 0%;
2252   }
2253 }
2254 table {
2255   background-color: transparent;
2256 }
2257 caption {
2258   padding-top: 8px;
2259   padding-bottom: 8px;
2260   color: #777777;
2261   text-align: left;
2262 }
2263 th {
2264   text-align: left;
2265 }
2266 .table {
2267   width: 100%;
2268   max-width: 100%;
2269   margin-bottom: 18px;
2270 }
2271 .table > thead > tr > th,
2272 .table > tbody > tr > th,
2273 .table > tfoot > tr > th,
2274 .table > thead > tr > td,
2275 .table > tbody > tr > td,
2276 .table > tfoot > tr > td {
2277   padding: 8px;
2278   line-height: 1.42857143;
2279   vertical-align: top;
2280   border-top: 1px solid #ddd;
2281 }
2282 .table > thead > tr > th {
2283   vertical-align: bottom;
2284   border-bottom: 2px solid #ddd;
2285 }
2286 .table > caption + thead > tr:first-child > th,
2287 .table > colgroup + thead > tr:first-child > th,
2288 .table > thead:first-child > tr:first-child > th,
2289 .table > caption + thead > tr:first-child > td,
2290 .table > colgroup + thead > tr:first-child > td,
2291 .table > thead:first-child > tr:first-child > td {
2292   border-top: 0;
2293 }
2294 .table > tbody + tbody {
2295   border-top: 2px solid #ddd;
2296 }
2297 .table .table {
2298   background-color: #fff;
2299 }
2300 .table-condensed > thead > tr > th,
2301 .table-condensed > tbody > tr > th,
2302 .table-condensed > tfoot > tr > th,
2303 .table-condensed > thead > tr > td,
2304 .table-condensed > tbody > tr > td,
2305 .table-condensed > tfoot > tr > td {
2306   padding: 5px;
2307 }
2308 .table-bordered {
2309   border: 1px solid #ddd;
2310 }
2311 .table-bordered > thead > tr > th,
2312 .table-bordered > tbody > tr > th,
2313 .table-bordered > tfoot > tr > th,
2314 .table-bordered > thead > tr > td,
2315 .table-bordered > tbody > tr > td,
2316 .table-bordered > tfoot > tr > td {
2317   border: 1px solid #ddd;
2318 }
2319 .table-bordered > thead > tr > th,
2320 .table-bordered > thead > tr > td {
2321   border-bottom-width: 2px;
2322 }
2323 .table-striped > tbody > tr:nth-of-type(odd) {
2324   background-color: #f9f9f9;
2325 }
2326 .table-hover > tbody > tr:hover {
2327   background-color: #f5f5f5;
2328 }
2329 table col[class*="col-"] {
2330   position: static;
2331   float: none;
2332   display: table-column;
2333 }
2334 table td[class*="col-"],
2335 table th[class*="col-"] {
2336   position: static;
2337   float: none;
2338   display: table-cell;
2339 }
2340 .table > thead > tr > td.active,
2341 .table > tbody > tr > td.active,
2342 .table > tfoot > tr > td.active,
2343 .table > thead > tr > th.active,
2344 .table > tbody > tr > th.active,
2345 .table > tfoot > tr > th.active,
2346 .table > thead > tr.active > td,
2347 .table > tbody > tr.active > td,
2348 .table > tfoot > tr.active > td,
2349 .table > thead > tr.active > th,
2350 .table > tbody > tr.active > th,
2351 .table > tfoot > tr.active > th {
2352   background-color: #f5f5f5;
2353 }
2354 .table-hover > tbody > tr > td.active:hover,
2355 .table-hover > tbody > tr > th.active:hover,
2356 .table-hover > tbody > tr.active:hover > td,
2357 .table-hover > tbody > tr:hover > .active,
2358 .table-hover > tbody > tr.active:hover > th {
2359   background-color: #e8e8e8;
2360 }
2361 .table > thead > tr > td.success,
2362 .table > tbody > tr > td.success,
2363 .table > tfoot > tr > td.success,
2364 .table > thead > tr > th.success,
2365 .table > tbody > tr > th.success,
2366 .table > tfoot > tr > th.success,
2367 .table > thead > tr.success > td,
2368 .table > tbody > tr.success > td,
2369 .table > tfoot > tr.success > td,
2370 .table > thead > tr.success > th,
2371 .table > tbody > tr.success > th,
2372 .table > tfoot > tr.success > th {
2373   background-color: #dff0d8;
2374 }
2375 .table-hover > tbody > tr > td.success:hover,
2376 .table-hover > tbody > tr > th.success:hover,
2377 .table-hover > tbody > tr.success:hover > td,
2378 .table-hover > tbody > tr:hover > .success,
2379 .table-hover > tbody > tr.success:hover > th {
2380   background-color: #d0e9c6;
2381 }
2382 .table > thead > tr > td.info,
2383 .table > tbody > tr > td.info,
2384 .table > tfoot > tr > td.info,
2385 .table > thead > tr > th.info,
2386 .table > tbody > tr > th.info,
2387 .table > tfoot > tr > th.info,
2388 .table > thead > tr.info > td,
2389 .table > tbody > tr.info > td,
2390 .table > tfoot > tr.info > td,
2391 .table > thead > tr.info > th,
2392 .table > tbody > tr.info > th,
2393 .table > tfoot > tr.info > th {
2394   background-color: #d9edf7;
2395 }
2396 .table-hover > tbody > tr > td.info:hover,
2397 .table-hover > tbody > tr > th.info:hover,
2398 .table-hover > tbody > tr.info:hover > td,
2399 .table-hover > tbody > tr:hover > .info,
2400 .table-hover > tbody > tr.info:hover > th {
2401   background-color: #c4e3f3;
2402 }
2403 .table > thead > tr > td.warning,
2404 .table > tbody > tr > td.warning,
2405 .table > tfoot > tr > td.warning,
2406 .table > thead > tr > th.warning,
2407 .table > tbody > tr > th.warning,
2408 .table > tfoot > tr > th.warning,
2409 .table > thead > tr.warning > td,
2410 .table > tbody > tr.warning > td,
2411 .table > tfoot > tr.warning > td,
2412 .table > thead > tr.warning > th,
2413 .table > tbody > tr.warning > th,
2414 .table > tfoot > tr.warning > th {
2415   background-color: #fcf8e3;
2416 }
2417 .table-hover > tbody > tr > td.warning:hover,
2418 .table-hover > tbody > tr > th.warning:hover,
2419 .table-hover > tbody > tr.warning:hover > td,
2420 .table-hover > tbody > tr:hover > .warning,
2421 .table-hover > tbody > tr.warning:hover > th {
2422   background-color: #faf2cc;
2423 }
2424 .table > thead > tr > td.danger,
2425 .table > tbody > tr > td.danger,
2426 .table > tfoot > tr > td.danger,
2427 .table > thead > tr > th.danger,
2428 .table > tbody > tr > th.danger,
2429 .table > tfoot > tr > th.danger,
2430 .table > thead > tr.danger > td,
2431 .table > tbody > tr.danger > td,
2432 .table > tfoot > tr.danger > td,
2433 .table > thead > tr.danger > th,
2434 .table > tbody > tr.danger > th,
2435 .table > tfoot > tr.danger > th {
2436   background-color: #f2dede;
2437 }
2438 .table-hover > tbody > tr > td.danger:hover,
2439 .table-hover > tbody > tr > th.danger:hover,
2440 .table-hover > tbody > tr.danger:hover > td,
2441 .table-hover > tbody > tr:hover > .danger,
2442 .table-hover > tbody > tr.danger:hover > th {
2443   background-color: #ebcccc;
2444 }
2445 .table-responsive {
2446   overflow-x: auto;
2447   min-height: 0.01%;
2448 }
2449 @media screen and (max-width: 767px) {
2450   .table-responsive {
2451     width: 100%;
2452     margin-bottom: 13.5px;
2453     overflow-y: hidden;
2454     -ms-overflow-style: -ms-autohiding-scrollbar;
2455     border: 1px solid #ddd;
2456   }
2457   .table-responsive > .table {
2458     margin-bottom: 0;
2459   }
2460   .table-responsive > .table > thead > tr > th,
2461   .table-responsive > .table > tbody > tr > th,
2462   .table-responsive > .table > tfoot > tr > th,
2463   .table-responsive > .table > thead > tr > td,
2464   .table-responsive > .table > tbody > tr > td,
2465   .table-responsive > .table > tfoot > tr > td {
2466     white-space: nowrap;
2467   }
2468   .table-responsive > .table-bordered {
2469     border: 0;
2470   }
2471   .table-responsive > .table-bordered > thead > tr > th:first-child,
2472   .table-responsive > .table-bordered > tbody > tr > th:first-child,
2473   .table-responsive > .table-bordered > tfoot > tr > th:first-child,
2474   .table-responsive > .table-bordered > thead > tr > td:first-child,
2475   .table-responsive > .table-bordered > tbody > tr > td:first-child,
2476   .table-responsive > .table-bordered > tfoot > tr > td:first-child {
2477     border-left: 0;
2478   }
2479   .table-responsive > .table-bordered > thead > tr > th:last-child,
2480   .table-responsive > .table-bordered > tbody > tr > th:last-child,
2481   .table-responsive > .table-bordered > tfoot > tr > th:last-child,
2482   .table-responsive > .table-bordered > thead > tr > td:last-child,
2483   .table-responsive > .table-bordered > tbody > tr > td:last-child,
2484   .table-responsive > .table-bordered > tfoot > tr > td:last-child {
2485     border-right: 0;
2486   }
2487   .table-responsive > .table-bordered > tbody > tr:last-child > th,
2488   .table-responsive > .table-bordered > tfoot > tr:last-child > th,
2489   .table-responsive > .table-bordered > tbody > tr:last-child > td,
2490   .table-responsive > .table-bordered > tfoot > tr:last-child > td {
2491     border-bottom: 0;
2492   }
2493 }
2494 fieldset {
2495   padding: 0;
2496   margin: 0;
2497   border: 0;
2498   min-width: 0;
2499 }
2500 legend {
2501   display: block;
2502   width: 100%;
2503   padding: 0;
2504   margin-bottom: 18px;
2505   font-size: 19.5px;
2506   line-height: inherit;
2507   color: #333333;
2508   border: 0;
2509   border-bottom: 1px solid #e5e5e5;
2510 }
2511 label {
2512   display: inline-block;
2513   max-width: 100%;
2514   margin-bottom: 5px;
2515   font-weight: bold;
2516 }
2517 input[type="search"] {
2518   -webkit-box-sizing: border-box;
2519   -moz-box-sizing: border-box;
2520   box-sizing: border-box;
2521 }
2522 input[type="radio"],
2523 input[type="checkbox"] {
2524   margin: 4px 0 0;
2525   margin-top: 1px \9;
2526   line-height: normal;
2527 }
2528 input[type="file"] {
2529   display: block;
2530 }
2531 input[type="range"] {
2532   display: block;
2533   width: 100%;
2534 }
2535 select[multiple],
2536 select[size] {
2537   height: auto;
2538 }
2539 input[type="file"]:focus,
2540 input[type="radio"]:focus,
2541 input[type="checkbox"]:focus {
2542   outline: 5px auto -webkit-focus-ring-color;
2543   outline-offset: -2px;
2544 }
2545 output {
2546   display: block;
2547   padding-top: 7px;
2548   font-size: 13px;
2549   line-height: 1.42857143;
2550   color: #555555;
2551 }
2552 .form-control {
2553   display: block;
2554   width: 100%;
2555   height: 32px;
2556   padding: 6px 12px;
2557   font-size: 13px;
2558   line-height: 1.42857143;
2559   color: #555555;
2560   background-color: #fff;
2561   background-image: none;
2562   border: 1px solid #ccc;
2563   border-radius: 2px;
2564   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2565   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2566   -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2567   -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2568   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2569 }
2570 .form-control:focus {
2571   border-color: #66afe9;
2572   outline: 0;
2573   -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2574   box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2575 }
2576 .form-control::-moz-placeholder {
2577   color: #999;
2578   opacity: 1;
2579 }
2580 .form-control:-ms-input-placeholder {
2581   color: #999;
2582 }
2583 .form-control::-webkit-input-placeholder {
2584   color: #999;
2585 }
2586 .form-control::-ms-expand {
2587   border: 0;
2588   background-color: transparent;
2589 }
2590 .form-control[disabled],
2591 .form-control[readonly],
2592 fieldset[disabled] .form-control {
2593   background-color: #eeeeee;
2594   opacity: 1;
2595 }
2596 .form-control[disabled],
2597 fieldset[disabled] .form-control {
2598   cursor: not-allowed;
2599 }
2600 textarea.form-control {
2601   height: auto;
2602 }
2603 input[type="search"] {
2604   -webkit-appearance: none;
2605 }
2606 @media screen and (-webkit-min-device-pixel-ratio: 0) {
2607   input[type="date"].form-control,
2608   input[type="time"].form-control,
2609   input[type="datetime-local"].form-control,
2610   input[type="month"].form-control {
2611     line-height: 32px;
2612   }
2613   input[type="date"].input-sm,
2614   input[type="time"].input-sm,
2615   input[type="datetime-local"].input-sm,
2616   input[type="month"].input-sm,
2617   .input-group-sm input[type="date"],
2618   .input-group-sm input[type="time"],
2619   .input-group-sm input[type="datetime-local"],
2620   .input-group-sm input[type="month"] {
2621     line-height: 30px;
2622   }
2623   input[type="date"].input-lg,
2624   input[type="time"].input-lg,
2625   input[type="datetime-local"].input-lg,
2626   input[type="month"].input-lg,
2627   .input-group-lg input[type="date"],
2628   .input-group-lg input[type="time"],
2629   .input-group-lg input[type="datetime-local"],
2630   .input-group-lg input[type="month"] {
2631     line-height: 45px;
2632   }
2633 }
2634 .form-group {
2635   margin-bottom: 15px;
2636 }
2637 .radio,
2638 .checkbox {
2639   position: relative;
2640   display: block;
2641   margin-top: 10px;
2642   margin-bottom: 10px;
2643 }
2644 .radio label,
2645 .checkbox label {
2646   min-height: 18px;
2647   padding-left: 20px;
2648   margin-bottom: 0;
2649   font-weight: normal;
2650   cursor: pointer;
2651 }
2652 .radio input[type="radio"],
2653 .radio-inline input[type="radio"],
2654 .checkbox input[type="checkbox"],
2655 .checkbox-inline input[type="checkbox"] {
2656   position: absolute;
2657   margin-left: -20px;
2658   margin-top: 4px \9;
2659 }
2660 .radio + .radio,
2661 .checkbox + .checkbox {
2662   margin-top: -5px;
2663 }
2664 .radio-inline,
2665 .checkbox-inline {
2666   position: relative;
2667   display: inline-block;
2668   padding-left: 20px;
2669   margin-bottom: 0;
2670   vertical-align: middle;
2671   font-weight: normal;
2672   cursor: pointer;
2673 }
2674 .radio-inline + .radio-inline,
2675 .checkbox-inline + .checkbox-inline {
2676   margin-top: 0;
2677   margin-left: 10px;
2678 }
2679 input[type="radio"][disabled],
2680 input[type="checkbox"][disabled],
2681 input[type="radio"].disabled,
2682 input[type="checkbox"].disabled,
2683 fieldset[disabled] input[type="radio"],
2684 fieldset[disabled] input[type="checkbox"] {
2685   cursor: not-allowed;
2686 }
2687 .radio-inline.disabled,
2688 .checkbox-inline.disabled,
2689 fieldset[disabled] .radio-inline,
2690 fieldset[disabled] .checkbox-inline {
2691   cursor: not-allowed;
2692 }
2693 .radio.disabled label,
2694 .checkbox.disabled label,
2695 fieldset[disabled] .radio label,
2696 fieldset[disabled] .checkbox label {
2697   cursor: not-allowed;
2698 }
2699 .form-control-static {
2700   padding-top: 7px;
2701   padding-bottom: 7px;
2702   margin-bottom: 0;
2703   min-height: 31px;
2704 }
2705 .form-control-static.input-lg,
2706 .form-control-static.input-sm {
2707   padding-left: 0;
2708   padding-right: 0;
2709 }
2710 .input-sm {
2711   height: 30px;
2712   padding: 5px 10px;
2713   font-size: 12px;
2714   line-height: 1.5;
2715   border-radius: 1px;
2716 }
2717 select.input-sm {
2718   height: 30px;
2719   line-height: 30px;
2720 }
2721 textarea.input-sm,
2722 select[multiple].input-sm {
2723   height: auto;
2724 }
2725 .form-group-sm .form-control {
2726   height: 30px;
2727   padding: 5px 10px;
2728   font-size: 12px;
2729   line-height: 1.5;
2730   border-radius: 1px;
2731 }
2732 .form-group-sm select.form-control {
2733   height: 30px;
2734   line-height: 30px;
2735 }
2736 .form-group-sm textarea.form-control,
2737 .form-group-sm select[multiple].form-control {
2738   height: auto;
2739 }
2740 .form-group-sm .form-control-static {
2741   height: 30px;
2742   min-height: 30px;
2743   padding: 6px 10px;
2744   font-size: 12px;
2745   line-height: 1.5;
2746 }
2747 .input-lg {
2748   height: 45px;
2749   padding: 10px 16px;
2750   font-size: 17px;
2751   line-height: 1.3333333;
2752   border-radius: 3px;
2753 }
2754 select.input-lg {
2755   height: 45px;
2756   line-height: 45px;
2757 }
2758 textarea.input-lg,
2759 select[multiple].input-lg {
2760   height: auto;
2761 }
2762 .form-group-lg .form-control {
2763   height: 45px;
2764   padding: 10px 16px;
2765   font-size: 17px;
2766   line-height: 1.3333333;
2767   border-radius: 3px;
2768 }
2769 .form-group-lg select.form-control {
2770   height: 45px;
2771   line-height: 45px;
2772 }
2773 .form-group-lg textarea.form-control,
2774 .form-group-lg select[multiple].form-control {
2775   height: auto;
2776 }
2777 .form-group-lg .form-control-static {
2778   height: 45px;
2779   min-height: 35px;
2780   padding: 11px 16px;
2781   font-size: 17px;
2782   line-height: 1.3333333;
2783 }
2784 .has-feedback {
2785   position: relative;
2786 }
2787 .has-feedback .form-control {
2788   padding-right: 40px;
2789 }
2790 .form-control-feedback {
2791   position: absolute;
2792   top: 0;
2793   right: 0;
2794   z-index: 2;
2795   display: block;
2796   width: 32px;
2797   height: 32px;
2798   line-height: 32px;
2799   text-align: center;
2800   pointer-events: none;
2801 }
2802 .input-lg + .form-control-feedback,
2803 .input-group-lg + .form-control-feedback,
2804 .form-group-lg .form-control + .form-control-feedback {
2805   width: 45px;
2806   height: 45px;
2807   line-height: 45px;
2808 }
2809 .input-sm + .form-control-feedback,
2810 .input-group-sm + .form-control-feedback,
2811 .form-group-sm .form-control + .form-control-feedback {
2812   width: 30px;
2813   height: 30px;
2814   line-height: 30px;
2815 }
2816 .has-success .help-block,
2817 .has-success .control-label,
2818 .has-success .radio,
2819 .has-success .checkbox,
2820 .has-success .radio-inline,
2821 .has-success .checkbox-inline,
2822 .has-success.radio label,
2823 .has-success.checkbox label,
2824 .has-success.radio-inline label,
2825 .has-success.checkbox-inline label {
2826   color: #3c763d;
2827 }
2828 .has-success .form-control {
2829   border-color: #3c763d;
2830   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2831   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2832 }
2833 .has-success .form-control:focus {
2834   border-color: #2b542c;
2835   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2836   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2837 }
2838 .has-success .input-group-addon {
2839   color: #3c763d;
2840   border-color: #3c763d;
2841   background-color: #dff0d8;
2842 }
2843 .has-success .form-control-feedback {
2844   color: #3c763d;
2845 }
2846 .has-warning .help-block,
2847 .has-warning .control-label,
2848 .has-warning .radio,
2849 .has-warning .checkbox,
2850 .has-warning .radio-inline,
2851 .has-warning .checkbox-inline,
2852 .has-warning.radio label,
2853 .has-warning.checkbox label,
2854 .has-warning.radio-inline label,
2855 .has-warning.checkbox-inline label {
2856   color: #8a6d3b;
2857 }
2858 .has-warning .form-control {
2859   border-color: #8a6d3b;
2860   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2861   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2862 }
2863 .has-warning .form-control:focus {
2864   border-color: #66512c;
2865   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2866   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2867 }
2868 .has-warning .input-group-addon {
2869   color: #8a6d3b;
2870   border-color: #8a6d3b;
2871   background-color: #fcf8e3;
2872 }
2873 .has-warning .form-control-feedback {
2874   color: #8a6d3b;
2875 }
2876 .has-error .help-block,
2877 .has-error .control-label,
2878 .has-error .radio,
2879 .has-error .checkbox,
2880 .has-error .radio-inline,
2881 .has-error .checkbox-inline,
2882 .has-error.radio label,
2883 .has-error.checkbox label,
2884 .has-error.radio-inline label,
2885 .has-error.checkbox-inline label {
2886   color: #a94442;
2887 }
2888 .has-error .form-control {
2889   border-color: #a94442;
2890   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2891   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2892 }
2893 .has-error .form-control:focus {
2894   border-color: #843534;
2895   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2896   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2897 }
2898 .has-error .input-group-addon {
2899   color: #a94442;
2900   border-color: #a94442;
2901   background-color: #f2dede;
2902 }
2903 .has-error .form-control-feedback {
2904   color: #a94442;
2905 }
2906 .has-feedback label ~ .form-control-feedback {
2907   top: 23px;
2908 }
2909 .has-feedback label.sr-only ~ .form-control-feedback {
2910   top: 0;
2911 }
2912 .help-block {
2913   display: block;
2914   margin-top: 5px;
2915   margin-bottom: 10px;
2916   color: #404040;
2917 }
2918 @media (min-width: 768px) {
2919   .form-inline .form-group {
2920     display: inline-block;
2921     margin-bottom: 0;
2922     vertical-align: middle;
2923   }
2924   .form-inline .form-control {
2925     display: inline-block;
2926     width: auto;
2927     vertical-align: middle;
2928   }
2929   .form-inline .form-control-static {
2930     display: inline-block;
2931   }
2932   .form-inline .input-group {
2933     display: inline-table;
2934     vertical-align: middle;
2935   }
2936   .form-inline .input-group .input-group-addon,
2937   .form-inline .input-group .input-group-btn,
2938   .form-inline .input-group .form-control {
2939     width: auto;
2940   }
2941   .form-inline .input-group > .form-control {
2942     width: 100%;
2943   }
2944   .form-inline .control-label {
2945     margin-bottom: 0;
2946     vertical-align: middle;
2947   }
2948   .form-inline .radio,
2949   .form-inline .checkbox {
2950     display: inline-block;
2951     margin-top: 0;
2952     margin-bottom: 0;
2953     vertical-align: middle;
2954   }
2955   .form-inline .radio label,
2956   .form-inline .checkbox label {
2957     padding-left: 0;
2958   }
2959   .form-inline .radio input[type="radio"],
2960   .form-inline .checkbox input[type="checkbox"] {
2961     position: relative;
2962     margin-left: 0;
2963   }
2964   .form-inline .has-feedback .form-control-feedback {
2965     top: 0;
2966   }
2967 }
2968 .form-horizontal .radio,
2969 .form-horizontal .checkbox,
2970 .form-horizontal .radio-inline,
2971 .form-horizontal .checkbox-inline {
2972   margin-top: 0;
2973   margin-bottom: 0;
2974   padding-top: 7px;
2975 }
2976 .form-horizontal .radio,
2977 .form-horizontal .checkbox {
2978   min-height: 25px;
2979 }
2980 .form-horizontal .form-group {
2981   margin-left: 0px;
2982   margin-right: 0px;
2983 }
2984 @media (min-width: 768px) {
2985   .form-horizontal .control-label {
2986     text-align: right;
2987     margin-bottom: 0;
2988     padding-top: 7px;
2989   }
2990 }
2991 .form-horizontal .has-feedback .form-control-feedback {
2992   right: 0px;
2993 }
2994 @media (min-width: 768px) {
2995   .form-horizontal .form-group-lg .control-label {
2996     padding-top: 11px;
2997     font-size: 17px;
2998   }
2999 }
3000 @media (min-width: 768px) {
3001   .form-horizontal .form-group-sm .control-label {
3002     padding-top: 6px;
3003     font-size: 12px;
3004   }
3005 }
3006 .btn {
3007   display: inline-block;
3008   margin-bottom: 0;
3009   font-weight: normal;
3010   text-align: center;
3011   vertical-align: middle;
3012   touch-action: manipulation;
3013   cursor: pointer;
3014   background-image: none;
3015   border: 1px solid transparent;
3016   white-space: nowrap;
3017   padding: 6px 12px;
3018   font-size: 13px;
3019   line-height: 1.42857143;
3020   border-radius: 2px;
3021   -webkit-user-select: none;
3022   -moz-user-select: none;
3023   -ms-user-select: none;
3024   user-select: none;
3025 }
3026 .btn:focus,
3027 .btn:active:focus,
3028 .btn.active:focus,
3029 .btn.focus,
3030 .btn:active.focus,
3031 .btn.active.focus {
3032   outline: 5px auto -webkit-focus-ring-color;
3033   outline-offset: -2px;
3034 }
3035 .btn:hover,
3036 .btn:focus,
3037 .btn.focus {
3038   color: #333;
3039   text-decoration: none;
3040 }
3041 .btn:active,
3042 .btn.active {
3043   outline: 0;
3044   background-image: none;
3045   -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3046   box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3047 }
3048 .btn.disabled,
3049 .btn[disabled],
3050 fieldset[disabled] .btn {
3051   cursor: not-allowed;
3052   opacity: 0.65;
3053   filter: alpha(opacity=65);
3054   -webkit-box-shadow: none;
3055   box-shadow: none;
3056 }
3057 a.btn.disabled,
3058 fieldset[disabled] a.btn {
3059   pointer-events: none;
3060 }
3061 .btn-default {
3062   color: #333;
3063   background-color: #fff;
3064   border-color: #ccc;
3065 }
3066 .btn-default:focus,
3067 .btn-default.focus {
3068   color: #333;
3069   background-color: #e6e6e6;
3070   border-color: #8c8c8c;
3071 }
3072 .btn-default:hover {
3073   color: #333;
3074   background-color: #e6e6e6;
3075   border-color: #adadad;
3076 }
3077 .btn-default:active,
3078 .btn-default.active,
3079 .open > .dropdown-toggle.btn-default {
3080   color: #333;
3081   background-color: #e6e6e6;
3082   border-color: #adadad;
3083 }
3084 .btn-default:active:hover,
3085 .btn-default.active:hover,
3086 .open > .dropdown-toggle.btn-default:hover,
3087 .btn-default:active:focus,
3088 .btn-default.active:focus,
3089 .open > .dropdown-toggle.btn-default:focus,
3090 .btn-default:active.focus,
3091 .btn-default.active.focus,
3092 .open > .dropdown-toggle.btn-default.focus {
3093   color: #333;
3094   background-color: #d4d4d4;
3095   border-color: #8c8c8c;
3096 }
3097 .btn-default:active,
3098 .btn-default.active,
3099 .open > .dropdown-toggle.btn-default {
3100   background-image: none;
3101 }
3102 .btn-default.disabled:hover,
3103 .btn-default[disabled]:hover,
3104 fieldset[disabled] .btn-default:hover,
3105 .btn-default.disabled:focus,
3106 .btn-default[disabled]:focus,
3107 fieldset[disabled] .btn-default:focus,
3108 .btn-default.disabled.focus,
3109 .btn-default[disabled].focus,
3110 fieldset[disabled] .btn-default.focus {
3111   background-color: #fff;
3112   border-color: #ccc;
3113 }
3114 .btn-default .badge {
3115   color: #fff;
3116   background-color: #333;
3117 }
3118 .btn-primary {
3119   color: #fff;
3120   background-color: #337ab7;
3121   border-color: #2e6da4;
3122 }
3123 .btn-primary:focus,
3124 .btn-primary.focus {
3125   color: #fff;
3126   background-color: #286090;
3127   border-color: #122b40;
3128 }
3129 .btn-primary:hover {
3130   color: #fff;
3131   background-color: #286090;
3132   border-color: #204d74;
3133 }
3134 .btn-primary:active,
3135 .btn-primary.active,
3136 .open > .dropdown-toggle.btn-primary {
3137   color: #fff;
3138   background-color: #286090;
3139   border-color: #204d74;
3140 }
3141 .btn-primary:active:hover,
3142 .btn-primary.active:hover,
3143 .open > .dropdown-toggle.btn-primary:hover,
3144 .btn-primary:active:focus,
3145 .btn-primary.active:focus,
3146 .open > .dropdown-toggle.btn-primary:focus,
3147 .btn-primary:active.focus,
3148 .btn-primary.active.focus,
3149 .open > .dropdown-toggle.btn-primary.focus {
3150   color: #fff;
3151   background-color: #204d74;
3152   border-color: #122b40;
3153 }
3154 .btn-primary:active,
3155 .btn-primary.active,
3156 .open > .dropdown-toggle.btn-primary {
3157   background-image: none;
3158 }
3159 .btn-primary.disabled:hover,
3160 .btn-primary[disabled]:hover,
3161 fieldset[disabled] .btn-primary:hover,
3162 .btn-primary.disabled:focus,
3163 .btn-primary[disabled]:focus,
3164 fieldset[disabled] .btn-primary:focus,
3165 .btn-primary.disabled.focus,
3166 .btn-primary[disabled].focus,
3167 fieldset[disabled] .btn-primary.focus {
3168   background-color: #337ab7;
3169   border-color: #2e6da4;
3170 }
3171 .btn-primary .badge {
3172   color: #337ab7;
3173   background-color: #fff;
3174 }
3175 .btn-success {
3176   color: #fff;
3177   background-color: #5cb85c;
3178   border-color: #4cae4c;
3179 }
3180 .btn-success:focus,
3181 .btn-success.focus {
3182   color: #fff;
3183   background-color: #449d44;
3184   border-color: #255625;
3185 }
3186 .btn-success:hover {
3187   color: #fff;
3188   background-color: #449d44;
3189   border-color: #398439;
3190 }
3191 .btn-success:active,
3192 .btn-success.active,
3193 .open > .dropdown-toggle.btn-success {
3194   color: #fff;
3195   background-color: #449d44;
3196   border-color: #398439;
3197 }
3198 .btn-success:active:hover,
3199 .btn-success.active:hover,
3200 .open > .dropdown-toggle.btn-success:hover,
3201 .btn-success:active:focus,
3202 .btn-success.active:focus,
3203 .open > .dropdown-toggle.btn-success:focus,
3204 .btn-success:active.focus,
3205 .btn-success.active.focus,
3206 .open > .dropdown-toggle.btn-success.focus {
3207   color: #fff;
3208   background-color: #398439;
3209   border-color: #255625;
3210 }
3211 .btn-success:active,
3212 .btn-success.active,
3213 .open > .dropdown-toggle.btn-success {
3214   background-image: none;
3215 }
3216 .btn-success.disabled:hover,
3217 .btn-success[disabled]:hover,
3218 fieldset[disabled] .btn-success:hover,
3219 .btn-success.disabled:focus,
3220 .btn-success[disabled]:focus,
3221 fieldset[disabled] .btn-success:focus,
3222 .btn-success.disabled.focus,
3223 .btn-success[disabled].focus,
3224 fieldset[disabled] .btn-success.focus {
3225   background-color: #5cb85c;
3226   border-color: #4cae4c;
3227 }
3228 .btn-success .badge {
3229   color: #5cb85c;
3230   background-color: #fff;
3231 }
3232 .btn-info {
3233   color: #fff;
3234   background-color: #5bc0de;
3235   border-color: #46b8da;
3236 }
3237 .btn-info:focus,
3238 .btn-info.focus {
3239   color: #fff;
3240   background-color: #31b0d5;
3241   border-color: #1b6d85;
3242 }
3243 .btn-info:hover {
3244   color: #fff;
3245   background-color: #31b0d5;
3246   border-color: #269abc;
3247 }
3248 .btn-info:active,
3249 .btn-info.active,
3250 .open > .dropdown-toggle.btn-info {
3251   color: #fff;
3252   background-color: #31b0d5;
3253   border-color: #269abc;
3254 }
3255 .btn-info:active:hover,
3256 .btn-info.active:hover,
3257 .open > .dropdown-toggle.btn-info:hover,
3258 .btn-info:active:focus,
3259 .btn-info.active:focus,
3260 .open > .dropdown-toggle.btn-info:focus,
3261 .btn-info:active.focus,
3262 .btn-info.active.focus,
3263 .open > .dropdown-toggle.btn-info.focus {
3264   color: #fff;
3265   background-color: #269abc;
3266   border-color: #1b6d85;
3267 }
3268 .btn-info:active,
3269 .btn-info.active,
3270 .open > .dropdown-toggle.btn-info {
3271   background-image: none;
3272 }
3273 .btn-info.disabled:hover,
3274 .btn-info[disabled]:hover,
3275 fieldset[disabled] .btn-info:hover,
3276 .btn-info.disabled:focus,
3277 .btn-info[disabled]:focus,
3278 fieldset[disabled] .btn-info:focus,
3279 .btn-info.disabled.focus,
3280 .btn-info[disabled].focus,
3281 fieldset[disabled] .btn-info.focus {
3282   background-color: #5bc0de;
3283   border-color: #46b8da;
3284 }
3285 .btn-info .badge {
3286   color: #5bc0de;
3287   background-color: #fff;
3288 }
3289 .btn-warning {
3290   color: #fff;
3291   background-color: #f0ad4e;
3292   border-color: #eea236;
3293 }
3294 .btn-warning:focus,
3295 .btn-warning.focus {
3296   color: #fff;
3297   background-color: #ec971f;
3298   border-color: #985f0d;
3299 }
3300 .btn-warning:hover {
3301   color: #fff;
3302   background-color: #ec971f;
3303   border-color: #d58512;
3304 }
3305 .btn-warning:active,
3306 .btn-warning.active,
3307 .open > .dropdown-toggle.btn-warning {
3308   color: #fff;
3309   background-color: #ec971f;
3310   border-color: #d58512;
3311 }
3312 .btn-warning:active:hover,
3313 .btn-warning.active:hover,
3314 .open > .dropdown-toggle.btn-warning:hover,
3315 .btn-warning:active:focus,
3316 .btn-warning.active:focus,
3317 .open > .dropdown-toggle.btn-warning:focus,
3318 .btn-warning:active.focus,
3319 .btn-warning.active.focus,
3320 .open > .dropdown-toggle.btn-warning.focus {
3321   color: #fff;
3322   background-color: #d58512;
3323   border-color: #985f0d;
3324 }
3325 .btn-warning:active,
3326 .btn-warning.active,
3327 .open > .dropdown-toggle.btn-warning {
3328   background-image: none;
3329 }
3330 .btn-warning.disabled:hover,
3331 .btn-warning[disabled]:hover,
3332 fieldset[disabled] .btn-warning:hover,
3333 .btn-warning.disabled:focus,
3334 .btn-warning[disabled]:focus,
3335 fieldset[disabled] .btn-warning:focus,
3336 .btn-warning.disabled.focus,
3337 .btn-warning[disabled].focus,
3338 fieldset[disabled] .btn-warning.focus {
3339   background-color: #f0ad4e;
3340   border-color: #eea236;
3341 }
3342 .btn-warning .badge {
3343   color: #f0ad4e;
3344   background-color: #fff;
3345 }
3346 .btn-danger {
3347   color: #fff;
3348   background-color: #d9534f;
3349   border-color: #d43f3a;
3350 }
3351 .btn-danger:focus,
3352 .btn-danger.focus {
3353   color: #fff;
3354   background-color: #c9302c;
3355   border-color: #761c19;
3356 }
3357 .btn-danger:hover {
3358   color: #fff;
3359   background-color: #c9302c;
3360   border-color: #ac2925;
3361 }
3362 .btn-danger:active,
3363 .btn-danger.active,
3364 .open > .dropdown-toggle.btn-danger {
3365   color: #fff;
3366   background-color: #c9302c;
3367   border-color: #ac2925;
3368 }
3369 .btn-danger:active:hover,
3370 .btn-danger.active:hover,
3371 .open > .dropdown-toggle.btn-danger:hover,
3372 .btn-danger:active:focus,
3373 .btn-danger.active:focus,
3374 .open > .dropdown-toggle.btn-danger:focus,
3375 .btn-danger:active.focus,
3376 .btn-danger.active.focus,
3377 .open > .dropdown-toggle.btn-danger.focus {
3378   color: #fff;
3379   background-color: #ac2925;
3380   border-color: #761c19;
3381 }
3382 .btn-danger:active,
3383 .btn-danger.active,
3384 .open > .dropdown-toggle.btn-danger {
3385   background-image: none;
3386 }
3387 .btn-danger.disabled:hover,
3388 .btn-danger[disabled]:hover,
3389 fieldset[disabled] .btn-danger:hover,
3390 .btn-danger.disabled:focus,
3391 .btn-danger[disabled]:focus,
3392 fieldset[disabled] .btn-danger:focus,
3393 .btn-danger.disabled.focus,
3394 .btn-danger[disabled].focus,
3395 fieldset[disabled] .btn-danger.focus {
3396   background-color: #d9534f;
3397   border-color: #d43f3a;
3398 }
3399 .btn-danger .badge {
3400   color: #d9534f;
3401   background-color: #fff;
3402 }
3403 .btn-link {
3404   color: #337ab7;
3405   font-weight: normal;
3406   border-radius: 0;
3407 }
3408 .btn-link,
3409 .btn-link:active,
3410 .btn-link.active,
3411 .btn-link[disabled],
3412 fieldset[disabled] .btn-link {
3413   background-color: transparent;
3414   -webkit-box-shadow: none;
3415   box-shadow: none;
3416 }
3417 .btn-link,
3418 .btn-link:hover,
3419 .btn-link:focus,
3420 .btn-link:active {
3421   border-color: transparent;
3422 }
3423 .btn-link:hover,
3424 .btn-link:focus {
3425   color: #23527c;
3426   text-decoration: underline;
3427   background-color: transparent;
3428 }
3429 .btn-link[disabled]:hover,
3430 fieldset[disabled] .btn-link:hover,
3431 .btn-link[disabled]:focus,
3432 fieldset[disabled] .btn-link:focus {
3433   color: #777777;
3434   text-decoration: none;
3435 }
3436 .btn-lg,
3437 .btn-group-lg > .btn {
3438   padding: 10px 16px;
3439   font-size: 17px;
3440   line-height: 1.3333333;
3441   border-radius: 3px;
3442 }
3443 .btn-sm,
3444 .btn-group-sm > .btn {
3445   padding: 5px 10px;
3446   font-size: 12px;
3447   line-height: 1.5;
3448   border-radius: 1px;
3449 }
3450 .btn-xs,
3451 .btn-group-xs > .btn {
3452   padding: 1px 5px;
3453   font-size: 12px;
3454   line-height: 1.5;
3455   border-radius: 1px;
3456 }
3457 .btn-block {
3458   display: block;
3459   width: 100%;
3460 }
3461 .btn-block + .btn-block {
3462   margin-top: 5px;
3463 }
3464 input[type="submit"].btn-block,
3465 input[type="reset"].btn-block,
3466 input[type="button"].btn-block {
3467   width: 100%;
3468 }
3469 .fade {
3470   opacity: 0;
3471   -webkit-transition: opacity 0.15s linear;
3472   -o-transition: opacity 0.15s linear;
3473   transition: opacity 0.15s linear;
3474 }
3475 .fade.in {
3476   opacity: 1;
3477 }
3478 .collapse {
3479   display: none;
3480 }
3481 .collapse.in {
3482   display: block;
3483 }
3484 tr.collapse.in {
3485   display: table-row;
3486 }
3487 tbody.collapse.in {
3488   display: table-row-group;
3489 }
3490 .collapsing {
3491   position: relative;
3492   height: 0;
3493   overflow: hidden;
3494   -webkit-transition-property: height, visibility;
3495   transition-property: height, visibility;
3496   -webkit-transition-duration: 0.35s;
3497   transition-duration: 0.35s;
3498   -webkit-transition-timing-function: ease;
3499   transition-timing-function: ease;
3500 }
3501 .caret {
3502   display: inline-block;
3503   width: 0;
3504   height: 0;
3505   margin-left: 2px;
3506   vertical-align: middle;
3507   border-top: 4px dashed;
3508   border-top: 4px solid \9;
3509   border-right: 4px solid transparent;
3510   border-left: 4px solid transparent;
3511 }
3512 .dropup,
3513 .dropdown {
3514   position: relative;
3515 }
3516 .dropdown-toggle:focus {
3517   outline: 0;
3518 }
3519 .dropdown-menu {
3520   position: absolute;
3521   top: 100%;
3522   left: 0;
3523   z-index: 1000;
3524   display: none;
3525   float: left;
3526   min-width: 160px;
3527   padding: 5px 0;
3528   margin: 2px 0 0;
3529   list-style: none;
3530   font-size: 13px;
3531   text-align: left;
3532   background-color: #fff;
3533   border: 1px solid #ccc;
3534   border: 1px solid rgba(0, 0, 0, 0.15);
3535   border-radius: 2px;
3536   -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3537   box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3538   background-clip: padding-box;
3539 }
3540 .dropdown-menu.pull-right {
3541   right: 0;
3542   left: auto;
3543 }
3544 .dropdown-menu .divider {
3545   height: 1px;
3546   margin: 8px 0;
3547   overflow: hidden;
3548   background-color: #e5e5e5;
3549 }
3550 .dropdown-menu > li > a {
3551   display: block;
3552   padding: 3px 20px;
3553   clear: both;
3554   font-weight: normal;
3555   line-height: 1.42857143;
3556   color: #333333;
3557   white-space: nowrap;
3558 }
3559 .dropdown-menu > li > a:hover,
3560 .dropdown-menu > li > a:focus {
3561   text-decoration: none;
3562   color: #262626;
3563   background-color: #f5f5f5;
3564 }
3565 .dropdown-menu > .active > a,
3566 .dropdown-menu > .active > a:hover,
3567 .dropdown-menu > .active > a:focus {
3568   color: #fff;
3569   text-decoration: none;
3570   outline: 0;
3571   background-color: #337ab7;
3572 }
3573 .dropdown-menu > .disabled > a,
3574 .dropdown-menu > .disabled > a:hover,
3575 .dropdown-menu > .disabled > a:focus {
3576   color: #777777;
3577 }
3578 .dropdown-menu > .disabled > a:hover,
3579 .dropdown-menu > .disabled > a:focus {
3580   text-decoration: none;
3581   background-color: transparent;
3582   background-image: none;
3583   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
3584   cursor: not-allowed;
3585 }
3586 .open > .dropdown-menu {
3587   display: block;
3588 }
3589 .open > a {
3590   outline: 0;
3591 }
3592 .dropdown-menu-right {
3593   left: auto;
3594   right: 0;
3595 }
3596 .dropdown-menu-left {
3597   left: 0;
3598   right: auto;
3599 }
3600 .dropdown-header {
3601   display: block;
3602   padding: 3px 20px;
3603   font-size: 12px;
3604   line-height: 1.42857143;
3605   color: #777777;
3606   white-space: nowrap;
3607 }
3608 .dropdown-backdrop {
3609   position: fixed;
3610   left: 0;
3611   right: 0;
3612   bottom: 0;
3613   top: 0;
3614   z-index: 990;
3615 }
3616 .pull-right > .dropdown-menu {
3617   right: 0;
3618   left: auto;
3619 }
3620 .dropup .caret,
3621 .navbar-fixed-bottom .dropdown .caret {
3622   border-top: 0;
3623   border-bottom: 4px dashed;
3624   border-bottom: 4px solid \9;
3625   content: "";
3626 }
3627 .dropup .dropdown-menu,
3628 .navbar-fixed-bottom .dropdown .dropdown-menu {
3629   top: auto;
3630   bottom: 100%;
3631   margin-bottom: 2px;
3632 }
3633 @media (min-width: 541px) {
3634   .navbar-right .dropdown-menu {
3635     left: auto;
3636     right: 0;
3637   }
3638   .navbar-right .dropdown-menu-left {
3639     left: 0;
3640     right: auto;
3641   }
3642 }
3643 .btn-group,
3644 .btn-group-vertical {
3645   position: relative;
3646   display: inline-block;
3647   vertical-align: middle;
3648 }
3649 .btn-group > .btn,
3650 .btn-group-vertical > .btn {
3651   position: relative;
3652   float: left;
3653 }
3654 .btn-group > .btn:hover,
3655 .btn-group-vertical > .btn:hover,
3656 .btn-group > .btn:focus,
3657 .btn-group-vertical > .btn:focus,
3658 .btn-group > .btn:active,
3659 .btn-group-vertical > .btn:active,
3660 .btn-group > .btn.active,
3661 .btn-group-vertical > .btn.active {
3662   z-index: 2;
3663 }
3664 .btn-group .btn + .btn,
3665 .btn-group .btn + .btn-group,
3666 .btn-group .btn-group + .btn,
3667 .btn-group .btn-group + .btn-group {
3668   margin-left: -1px;
3669 }
3670 .btn-toolbar {
3671   margin-left: -5px;
3672 }
3673 .btn-toolbar .btn,
3674 .btn-toolbar .btn-group,
3675 .btn-toolbar .input-group {
3676   float: left;
3677 }
3678 .btn-toolbar > .btn,
3679 .btn-toolbar > .btn-group,
3680 .btn-toolbar > .input-group {
3681   margin-left: 5px;
3682 }
3683 .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
3684   border-radius: 0;
3685 }
3686 .btn-group > .btn:first-child {
3687   margin-left: 0;
3688 }
3689 .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
3690   border-bottom-right-radius: 0;
3691   border-top-right-radius: 0;
3692 }
3693 .btn-group > .btn:last-child:not(:first-child),
3694 .btn-group > .dropdown-toggle:not(:first-child) {
3695   border-bottom-left-radius: 0;
3696   border-top-left-radius: 0;
3697 }
3698 .btn-group > .btn-group {
3699   float: left;
3700 }
3701 .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
3702   border-radius: 0;
3703 }
3704 .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
3705 .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3706   border-bottom-right-radius: 0;
3707   border-top-right-radius: 0;
3708 }
3709 .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
3710   border-bottom-left-radius: 0;
3711   border-top-left-radius: 0;
3712 }
3713 .btn-group .dropdown-toggle:active,
3714 .btn-group.open .dropdown-toggle {
3715   outline: 0;
3716 }
3717 .btn-group > .btn + .dropdown-toggle {
3718   padding-left: 8px;
3719   padding-right: 8px;
3720 }
3721 .btn-group > .btn-lg + .dropdown-toggle {
3722   padding-left: 12px;
3723   padding-right: 12px;
3724 }
3725 .btn-group.open .dropdown-toggle {
3726   -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3727   box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3728 }
3729 .btn-group.open .dropdown-toggle.btn-link {
3730   -webkit-box-shadow: none;
3731   box-shadow: none;
3732 }
3733 .btn .caret {
3734   margin-left: 0;
3735 }
3736 .btn-lg .caret {
3737   border-width: 5px 5px 0;
3738   border-bottom-width: 0;
3739 }
3740 .dropup .btn-lg .caret {
3741   border-width: 0 5px 5px;
3742 }
3743 .btn-group-vertical > .btn,
3744 .btn-group-vertical > .btn-group,
3745 .btn-group-vertical > .btn-group > .btn {
3746   display: block;
3747   float: none;
3748   width: 100%;
3749   max-width: 100%;
3750 }
3751 .btn-group-vertical > .btn-group > .btn {
3752   float: none;
3753 }
3754 .btn-group-vertical > .btn + .btn,
3755 .btn-group-vertical > .btn + .btn-group,
3756 .btn-group-vertical > .btn-group + .btn,
3757 .btn-group-vertical > .btn-group + .btn-group {
3758   margin-top: -1px;
3759   margin-left: 0;
3760 }
3761 .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
3762   border-radius: 0;
3763 }
3764 .btn-group-vertical > .btn:first-child:not(:last-child) {
3765   border-top-right-radius: 2px;
3766   border-top-left-radius: 2px;
3767   border-bottom-right-radius: 0;
3768   border-bottom-left-radius: 0;
3769 }
3770 .btn-group-vertical > .btn:last-child:not(:first-child) {
3771   border-top-right-radius: 0;
3772   border-top-left-radius: 0;
3773   border-bottom-right-radius: 2px;
3774   border-bottom-left-radius: 2px;
3775 }
3776 .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
3777   border-radius: 0;
3778 }
3779 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
3780 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3781   border-bottom-right-radius: 0;
3782   border-bottom-left-radius: 0;
3783 }
3784 .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
3785   border-top-right-radius: 0;
3786   border-top-left-radius: 0;
3787 }
3788 .btn-group-justified {
3789   display: table;
3790   width: 100%;
3791   table-layout: fixed;
3792   border-collapse: separate;
3793 }
3794 .btn-group-justified > .btn,
3795 .btn-group-justified > .btn-group {
3796   float: none;
3797   display: table-cell;
3798   width: 1%;
3799 }
3800 .btn-group-justified > .btn-group .btn {
3801   width: 100%;
3802 }
3803 .btn-group-justified > .btn-group .dropdown-menu {
3804   left: auto;
3805 }
3806 [data-toggle="buttons"] > .btn input[type="radio"],
3807 [data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
3808 [data-toggle="buttons"] > .btn input[type="checkbox"],
3809 [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
3810   position: absolute;
3811   clip: rect(0, 0, 0, 0);
3812   pointer-events: none;
3813 }
3814 .input-group {
3815   position: relative;
3816   display: table;
3817   border-collapse: separate;
3818 }
3819 .input-group[class*="col-"] {
3820   float: none;
3821   padding-left: 0;
3822   padding-right: 0;
3823 }
3824 .input-group .form-control {
3825   position: relative;
3826   z-index: 2;
3827   float: left;
3828   width: 100%;
3829   margin-bottom: 0;
3830 }
3831 .input-group .form-control:focus {
3832   z-index: 3;
3833 }
3834 .input-group-lg > .form-control,
3835 .input-group-lg > .input-group-addon,
3836 .input-group-lg > .input-group-btn > .btn {
3837   height: 45px;
3838   padding: 10px 16px;
3839   font-size: 17px;
3840   line-height: 1.3333333;
3841   border-radius: 3px;
3842 }
3843 select.input-group-lg > .form-control,
3844 select.input-group-lg > .input-group-addon,
3845 select.input-group-lg > .input-group-btn > .btn {
3846   height: 45px;
3847   line-height: 45px;
3848 }
3849 textarea.input-group-lg > .form-control,
3850 textarea.input-group-lg > .input-group-addon,
3851 textarea.input-group-lg > .input-group-btn > .btn,
3852 select[multiple].input-group-lg > .form-control,
3853 select[multiple].input-group-lg > .input-group-addon,
3854 select[multiple].input-group-lg > .input-group-btn > .btn {
3855   height: auto;
3856 }
3857 .input-group-sm > .form-control,
3858 .input-group-sm > .input-group-addon,
3859 .input-group-sm > .input-group-btn > .btn {
3860   height: 30px;
3861   padding: 5px 10px;
3862   font-size: 12px;
3863   line-height: 1.5;
3864   border-radius: 1px;
3865 }
3866 select.input-group-sm > .form-control,
3867 select.input-group-sm > .input-group-addon,
3868 select.input-group-sm > .input-group-btn > .btn {
3869   height: 30px;
3870   line-height: 30px;
3871 }
3872 textarea.input-group-sm > .form-control,
3873 textarea.input-group-sm > .input-group-addon,
3874 textarea.input-group-sm > .input-group-btn > .btn,
3875 select[multiple].input-group-sm > .form-control,
3876 select[multiple].input-group-sm > .input-group-addon,
3877 select[multiple].input-group-sm > .input-group-btn > .btn {
3878   height: auto;
3879 }
3880 .input-group-addon,
3881 .input-group-btn,
3882 .input-group .form-control {
3883   display: table-cell;
3884 }
3885 .input-group-addon:not(:first-child):not(:last-child),
3886 .input-group-btn:not(:first-child):not(:last-child),
3887 .input-group .form-control:not(:first-child):not(:last-child) {
3888   border-radius: 0;
3889 }
3890 .input-group-addon,
3891 .input-group-btn {
3892   width: 1%;
3893   white-space: nowrap;
3894   vertical-align: middle;
3895 }
3896 .input-group-addon {
3897   padding: 6px 12px;
3898   font-size: 13px;
3899   font-weight: normal;
3900   line-height: 1;
3901   color: #555555;
3902   text-align: center;
3903   background-color: #eeeeee;
3904   border: 1px solid #ccc;
3905   border-radius: 2px;
3906 }
3907 .input-group-addon.input-sm {
3908   padding: 5px 10px;
3909   font-size: 12px;
3910   border-radius: 1px;
3911 }
3912 .input-group-addon.input-lg {
3913   padding: 10px 16px;
3914   font-size: 17px;
3915   border-radius: 3px;
3916 }
3917 .input-group-addon input[type="radio"],
3918 .input-group-addon input[type="checkbox"] {
3919   margin-top: 0;
3920 }
3921 .input-group .form-control:first-child,
3922 .input-group-addon:first-child,
3923 .input-group-btn:first-child > .btn,
3924 .input-group-btn:first-child > .btn-group > .btn,
3925 .input-group-btn:first-child > .dropdown-toggle,
3926 .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
3927 .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
3928   border-bottom-right-radius: 0;
3929   border-top-right-radius: 0;
3930 }
3931 .input-group-addon:first-child {
3932   border-right: 0;
3933 }
3934 .input-group .form-control:last-child,
3935 .input-group-addon:last-child,
3936 .input-group-btn:last-child > .btn,
3937 .input-group-btn:last-child > .btn-group > .btn,
3938 .input-group-btn:last-child > .dropdown-toggle,
3939 .input-group-btn:first-child > .btn:not(:first-child),
3940 .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
3941   border-bottom-left-radius: 0;
3942   border-top-left-radius: 0;
3943 }
3944 .input-group-addon:last-child {
3945   border-left: 0;
3946 }
3947 .input-group-btn {
3948   position: relative;
3949   font-size: 0;
3950   white-space: nowrap;
3951 }
3952 .input-group-btn > .btn {
3953   position: relative;
3954 }
3955 .input-group-btn > .btn + .btn {
3956   margin-left: -1px;
3957 }
3958 .input-group-btn > .btn:hover,
3959 .input-group-btn > .btn:focus,
3960 .input-group-btn > .btn:active {
3961   z-index: 2;
3962 }
3963 .input-group-btn:first-child > .btn,
3964 .input-group-btn:first-child > .btn-group {
3965   margin-right: -1px;
3966 }
3967 .input-group-btn:last-child > .btn,
3968 .input-group-btn:last-child > .btn-group {
3969   z-index: 2;
3970   margin-left: -1px;
3971 }
3972 .nav {
3973   margin-bottom: 0;
3974   padding-left: 0;
3975   list-style: none;
3976 }
3977 .nav > li {
3978   position: relative;
3979   display: block;
3980 }
3981 .nav > li > a {
3982   position: relative;
3983   display: block;
3984   padding: 10px 15px;
3985 }
3986 .nav > li > a:hover,
3987 .nav > li > a:focus {
3988   text-decoration: none;
3989   background-color: #eeeeee;
3990 }
3991 .nav > li.disabled > a {
3992   color: #777777;
3993 }
3994 .nav > li.disabled > a:hover,
3995 .nav > li.disabled > a:focus {
3996   color: #777777;
3997   text-decoration: none;
3998   background-color: transparent;
3999   cursor: not-allowed;
4000 }
4001 .nav .open > a,
4002 .nav .open > a:hover,
4003 .nav .open > a:focus {
4004   background-color: #eeeeee;
4005   border-color: #337ab7;
4006 }
4007 .nav .nav-divider {
4008   height: 1px;
4009   margin: 8px 0;
4010   overflow: hidden;
4011   background-color: #e5e5e5;
4012 }
4013 .nav > li > a > img {
4014   max-width: none;
4015 }
4016 .nav-tabs {
4017   border-bottom: 1px solid #ddd;
4018 }
4019 .nav-tabs > li {
4020   float: left;
4021   margin-bottom: -1px;
4022 }
4023 .nav-tabs > li > a {
4024   margin-right: 2px;
4025   line-height: 1.42857143;
4026   border: 1px solid transparent;
4027   border-radius: 2px 2px 0 0;
4028 }
4029 .nav-tabs > li > a:hover {
4030   border-color: #eeeeee #eeeeee #ddd;
4031 }
4032 .nav-tabs > li.active > a,
4033 .nav-tabs > li.active > a:hover,
4034 .nav-tabs > li.active > a:focus {
4035   color: #555555;
4036   background-color: #fff;
4037   border: 1px solid #ddd;
4038   border-bottom-color: transparent;
4039   cursor: default;
4040 }
4041 .nav-tabs.nav-justified {
4042   width: 100%;
4043   border-bottom: 0;
4044 }
4045 .nav-tabs.nav-justified > li {
4046   float: none;
4047 }
4048 .nav-tabs.nav-justified > li > a {
4049   text-align: center;
4050   margin-bottom: 5px;
4051 }
4052 .nav-tabs.nav-justified > .dropdown .dropdown-menu {
4053   top: auto;
4054   left: auto;
4055 }
4056 @media (min-width: 768px) {
4057   .nav-tabs.nav-justified > li {
4058     display: table-cell;
4059     width: 1%;
4060   }
4061   .nav-tabs.nav-justified > li > a {
4062     margin-bottom: 0;
4063   }
4064 }
4065 .nav-tabs.nav-justified > li > a {
4066   margin-right: 0;
4067   border-radius: 2px;
4068 }
4069 .nav-tabs.nav-justified > .active > a,
4070 .nav-tabs.nav-justified > .active > a:hover,
4071 .nav-tabs.nav-justified > .active > a:focus {
4072   border: 1px solid #ddd;
4073 }
4074 @media (min-width: 768px) {
4075   .nav-tabs.nav-justified > li > a {
4076     border-bottom: 1px solid #ddd;
4077     border-radius: 2px 2px 0 0;
4078   }
4079   .nav-tabs.nav-justified > .active > a,
4080   .nav-tabs.nav-justified > .active > a:hover,
4081   .nav-tabs.nav-justified > .active > a:focus {
4082     border-bottom-color: #fff;
4083   }
4084 }
4085 .nav-pills > li {
4086   float: left;
4087 }
4088 .nav-pills > li > a {
4089   border-radius: 2px;
4090 }
4091 .nav-pills > li + li {
4092   margin-left: 2px;
4093 }
4094 .nav-pills > li.active > a,
4095 .nav-pills > li.active > a:hover,
4096 .nav-pills > li.active > a:focus {
4097   color: #fff;
4098   background-color: #337ab7;
4099 }
4100 .nav-stacked > li {
4101   float: none;
4102 }
4103 .nav-stacked > li + li {
4104   margin-top: 2px;
4105   margin-left: 0;
4106 }
4107 .nav-justified {
4108   width: 100%;
4109 }
4110 .nav-justified > li {
4111   float: none;
4112 }
4113 .nav-justified > li > a {
4114   text-align: center;
4115   margin-bottom: 5px;
4116 }
4117 .nav-justified > .dropdown .dropdown-menu {
4118   top: auto;
4119   left: auto;
4120 }
4121 @media (min-width: 768px) {
4122   .nav-justified > li {
4123     display: table-cell;
4124     width: 1%;
4125   }
4126   .nav-justified > li > a {
4127     margin-bottom: 0;
4128   }
4129 }
4130 .nav-tabs-justified {
4131   border-bottom: 0;
4132 }
4133 .nav-tabs-justified > li > a {
4134   margin-right: 0;
4135   border-radius: 2px;
4136 }
4137 .nav-tabs-justified > .active > a,
4138 .nav-tabs-justified > .active > a:hover,
4139 .nav-tabs-justified > .active > a:focus {
4140   border: 1px solid #ddd;
4141 }
4142 @media (min-width: 768px) {
4143   .nav-tabs-justified > li > a {
4144     border-bottom: 1px solid #ddd;
4145     border-radius: 2px 2px 0 0;
4146   }
4147   .nav-tabs-justified > .active > a,
4148   .nav-tabs-justified > .active > a:hover,
4149   .nav-tabs-justified > .active > a:focus {
4150     border-bottom-color: #fff;
4151   }
4152 }
4153 .tab-content > .tab-pane {
4154   display: none;
4155 }
4156 .tab-content > .active {
4157   display: block;
4158 }
4159 .nav-tabs .dropdown-menu {
4160   margin-top: -1px;
4161   border-top-right-radius: 0;
4162   border-top-left-radius: 0;
4163 }
4164 .navbar {
4165   position: relative;
4166   min-height: 30px;
4167   margin-bottom: 18px;
4168   border: 1px solid transparent;
4169 }
4170 @media (min-width: 541px) {
4171   .navbar {
4172     border-radius: 2px;
4173   }
4174 }
4175 @media (min-width: 541px) {
4176   .navbar-header {
4177     float: left;
4178   }
4179 }
4180 .navbar-collapse {
4181   overflow-x: visible;
4182   padding-right: 0px;
4183   padding-left: 0px;
4184   border-top: 1px solid transparent;
4185   box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
4186   -webkit-overflow-scrolling: touch;
4187 }
4188 .navbar-collapse.in {
4189   overflow-y: auto;
4190 }
4191 @media (min-width: 541px) {
4192   .navbar-collapse {
4193     width: auto;
4194     border-top: 0;
4195     box-shadow: none;
4196   }
4197   .navbar-collapse.collapse {
4198     display: block !important;
4199     height: auto !important;
4200     padding-bottom: 0;
4201     overflow: visible !important;
4202   }
4203   .navbar-collapse.in {
4204     overflow-y: visible;
4205   }
4206   .navbar-fixed-top .navbar-collapse,
4207   .navbar-static-top .navbar-collapse,
4208   .navbar-fixed-bottom .navbar-collapse {
4209     padding-left: 0;
4210     padding-right: 0;
4211   }
4212 }
4213 .navbar-fixed-top .navbar-collapse,
4214 .navbar-fixed-bottom .navbar-collapse {
4215   max-height: 340px;
4216 }
4217 @media (max-device-width: 540px) and (orientation: landscape) {
4218   .navbar-fixed-top .navbar-collapse,
4219   .navbar-fixed-bottom .navbar-collapse {
4220     max-height: 200px;
4221   }
4222 }
4223 .container > .navbar-header,
4224 .container-fluid > .navbar-header,
4225 .container > .navbar-collapse,
4226 .container-fluid > .navbar-collapse {
4227   margin-right: 0px;
4228   margin-left: 0px;
4229 }
4230 @media (min-width: 541px) {
4231   .container > .navbar-header,
4232   .container-fluid > .navbar-header,
4233   .container > .navbar-collapse,
4234   .container-fluid > .navbar-collapse {
4235     margin-right: 0;
4236     margin-left: 0;
4237   }
4238 }
4239 .navbar-static-top {
4240   z-index: 1000;
4241   border-width: 0 0 1px;
4242 }
4243 @media (min-width: 541px) {
4244   .navbar-static-top {
4245     border-radius: 0;
4246   }
4247 }
4248 .navbar-fixed-top,
4249 .navbar-fixed-bottom {
4250   position: fixed;
4251   right: 0;
4252   left: 0;
4253   z-index: 1030;
4254 }
4255 @media (min-width: 541px) {
4256   .navbar-fixed-top,
4257   .navbar-fixed-bottom {
4258     border-radius: 0;
4259   }
4260 }
4261 .navbar-fixed-top {
4262   top: 0;
4263   border-width: 0 0 1px;
4264 }
4265 .navbar-fixed-bottom {
4266   bottom: 0;
4267   margin-bottom: 0;
4268   border-width: 1px 0 0;
4269 }
4270 .navbar-brand {
4271   float: left;
4272   padding: 6px 0px;
4273   font-size: 17px;
4274   line-height: 18px;
4275   height: 30px;
4276 }
4277 .navbar-brand:hover,
4278 .navbar-brand:focus {
4279   text-decoration: none;
4280 }
4281 .navbar-brand > img {
4282   display: block;
4283 }
4284 @media (min-width: 541px) {
4285   .navbar > .container .navbar-brand,
4286   .navbar > .container-fluid .navbar-brand {
4287     margin-left: 0px;
4288   }
4289 }
4290 .navbar-toggle {
4291   position: relative;
4292   float: right;
4293   margin-right: 0px;
4294   padding: 9px 10px;
4295   margin-top: -2px;
4296   margin-bottom: -2px;
4297   background-color: transparent;
4298   background-image: none;
4299   border: 1px solid transparent;
4300   border-radius: 2px;
4301 }
4302 .navbar-toggle:focus {
4303   outline: 0;
4304 }
4305 .navbar-toggle .icon-bar {
4306   display: block;
4307   width: 22px;
4308   height: 2px;
4309   border-radius: 1px;
4310 }
4311 .navbar-toggle .icon-bar + .icon-bar {
4312   margin-top: 4px;
4313 }
4314 @media (min-width: 541px) {
4315   .navbar-toggle {
4316     display: none;
4317   }
4318 }
4319 .navbar-nav {
4320   margin: 3px 0px;
4321 }
4322 .navbar-nav > li > a {
4323   padding-top: 10px;
4324   padding-bottom: 10px;
4325   line-height: 18px;
4326 }
4327 @media (max-width: 540px) {
4328   .navbar-nav .open .dropdown-menu {
4329     position: static;
4330     float: none;
4331     width: auto;
4332     margin-top: 0;
4333     background-color: transparent;
4334     border: 0;
4335     box-shadow: none;
4336   }
4337   .navbar-nav .open .dropdown-menu > li > a,
4338   .navbar-nav .open .dropdown-menu .dropdown-header {
4339     padding: 5px 15px 5px 25px;
4340   }
4341   .navbar-nav .open .dropdown-menu > li > a {
4342     line-height: 18px;
4343   }
4344   .navbar-nav .open .dropdown-menu > li > a:hover,
4345   .navbar-nav .open .dropdown-menu > li > a:focus {
4346     background-image: none;
4347   }
4348 }
4349 @media (min-width: 541px) {
4350   .navbar-nav {
4351     float: left;
4352     margin: 0;
4353   }
4354   .navbar-nav > li {
4355     float: left;
4356   }
4357   .navbar-nav > li > a {
4358     padding-top: 6px;
4359     padding-bottom: 6px;
4360   }
4361 }
4362 .navbar-form {
4363   margin-left: 0px;
4364   margin-right: 0px;
4365   padding: 10px 0px;
4366   border-top: 1px solid transparent;
4367   border-bottom: 1px solid transparent;
4368   -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4369   box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4370   margin-top: -1px;
4371   margin-bottom: -1px;
4372 }
4373 @media (min-width: 768px) {
4374   .navbar-form .form-group {
4375     display: inline-block;
4376     margin-bottom: 0;
4377     vertical-align: middle;
4378   }
4379   .navbar-form .form-control {
4380     display: inline-block;
4381     width: auto;
4382     vertical-align: middle;
4383   }
4384   .navbar-form .form-control-static {
4385     display: inline-block;
4386   }
4387   .navbar-form .input-group {
4388     display: inline-table;
4389     vertical-align: middle;
4390   }
4391   .navbar-form .input-group .input-group-addon,
4392   .navbar-form .input-group .input-group-btn,
4393   .navbar-form .input-group .form-control {
4394     width: auto;
4395   }
4396   .navbar-form .input-group > .form-control {
4397     width: 100%;
4398   }
4399   .navbar-form .control-label {
4400     margin-bottom: 0;
4401     vertical-align: middle;
4402   }
4403   .navbar-form .radio,
4404   .navbar-form .checkbox {
4405     display: inline-block;
4406     margin-top: 0;
4407     margin-bottom: 0;
4408     vertical-align: middle;
4409   }
4410   .navbar-form .radio label,
4411   .navbar-form .checkbox label {
4412     padding-left: 0;
4413   }
4414   .navbar-form .radio input[type="radio"],
4415   .navbar-form .checkbox input[type="checkbox"] {
4416     position: relative;
4417     margin-left: 0;
4418   }
4419   .navbar-form .has-feedback .form-control-feedback {
4420     top: 0;
4421   }
4422 }
4423 @media (max-width: 540px) {
4424   .navbar-form .form-group {
4425     margin-bottom: 5px;
4426   }
4427   .navbar-form .form-group:last-child {
4428     margin-bottom: 0;
4429   }
4430 }
4431 @media (min-width: 541px) {
4432   .navbar-form {
4433     width: auto;
4434     border: 0;
4435     margin-left: 0;
4436     margin-right: 0;
4437     padding-top: 0;
4438     padding-bottom: 0;
4439     -webkit-box-shadow: none;
4440     box-shadow: none;
4441   }
4442 }
4443 .navbar-nav > li > .dropdown-menu {
4444   margin-top: 0;
4445   border-top-right-radius: 0;
4446   border-top-left-radius: 0;
4447 }
4448 .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
4449   margin-bottom: 0;
4450   border-top-right-radius: 2px;
4451   border-top-left-radius: 2px;
4452   border-bottom-right-radius: 0;
4453   border-bottom-left-radius: 0;
4454 }
4455 .navbar-btn {
4456   margin-top: -1px;
4457   margin-bottom: -1px;
4458 }
4459 .navbar-btn.btn-sm {
4460   margin-top: 0px;
4461   margin-bottom: 0px;
4462 }
4463 .navbar-btn.btn-xs {
4464   margin-top: 4px;
4465   margin-bottom: 4px;
4466 }
4467 .navbar-text {
4468   margin-top: 6px;
4469   margin-bottom: 6px;
4470 }
4471 @media (min-width: 541px) {
4472   .navbar-text {
4473     float: left;
4474     margin-left: 0px;
4475     margin-right: 0px;
4476   }
4477 }
4478 @media (min-width: 541px) {
4479   .navbar-left {
4480     float: left !important;
4481     float: left;
4482   }
4483   .navbar-right {
4484     float: right !important;
4485     float: right;
4486     margin-right: 0px;
4487   }
4488   .navbar-right ~ .navbar-right {
4489     margin-right: 0;
4490   }
4491 }
4492 .navbar-default {
4493   background-color: #f8f8f8;
4494   border-color: #e7e7e7;
4495 }
4496 .navbar-default .navbar-brand {
4497   color: #777;
4498 }
4499 .navbar-default .navbar-brand:hover,
4500 .navbar-default .navbar-brand:focus {
4501   color: #5e5e5e;
4502   background-color: transparent;
4503 }
4504 .navbar-default .navbar-text {
4505   color: #777;
4506 }
4507 .navbar-default .navbar-nav > li > a {
4508   color: #777;
4509 }
4510 .navbar-default .navbar-nav > li > a:hover,
4511 .navbar-default .navbar-nav > li > a:focus {
4512   color: #333;
4513   background-color: transparent;
4514 }
4515 .navbar-default .navbar-nav > .active > a,
4516 .navbar-default .navbar-nav > .active > a:hover,
4517 .navbar-default .navbar-nav > .active > a:focus {
4518   color: #555;
4519   background-color: #e7e7e7;
4520 }
4521 .navbar-default .navbar-nav > .disabled > a,
4522 .navbar-default .navbar-nav > .disabled > a:hover,
4523 .navbar-default .navbar-nav > .disabled > a:focus {
4524   color: #ccc;
4525   background-color: transparent;
4526 }
4527 .navbar-default .navbar-toggle {
4528   border-color: #ddd;
4529 }
4530 .navbar-default .navbar-toggle:hover,
4531 .navbar-default .navbar-toggle:focus {
4532   background-color: #ddd;
4533 }
4534 .navbar-default .navbar-toggle .icon-bar {
4535   background-color: #888;
4536 }
4537 .navbar-default .navbar-collapse,
4538 .navbar-default .navbar-form {
4539   border-color: #e7e7e7;
4540 }
4541 .navbar-default .navbar-nav > .open > a,
4542 .navbar-default .navbar-nav > .open > a:hover,
4543 .navbar-default .navbar-nav > .open > a:focus {
4544   background-color: #e7e7e7;
4545   color: #555;
4546 }
4547 @media (max-width: 540px) {
4548   .navbar-default .navbar-nav .open .dropdown-menu > li > a {
4549     color: #777;
4550   }
4551   .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
4552   .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
4553     color: #333;
4554     background-color: transparent;
4555   }
4556   .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
4557   .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
4558   .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
4559     color: #555;
4560     background-color: #e7e7e7;
4561   }
4562   .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
4563   .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4564   .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4565     color: #ccc;
4566     background-color: transparent;
4567   }
4568 }
4569 .navbar-default .navbar-link {
4570   color: #777;
4571 }
4572 .navbar-default .navbar-link:hover {
4573   color: #333;
4574 }
4575 .navbar-default .btn-link {
4576   color: #777;
4577 }
4578 .navbar-default .btn-link:hover,
4579 .navbar-default .btn-link:focus {
4580   color: #333;
4581 }
4582 .navbar-default .btn-link[disabled]:hover,
4583 fieldset[disabled] .navbar-default .btn-link:hover,
4584 .navbar-default .btn-link[disabled]:focus,
4585 fieldset[disabled] .navbar-default .btn-link:focus {
4586   color: #ccc;
4587 }
4588 .navbar-inverse {
4589   background-color: #222;
4590   border-color: #080808;
4591 }
4592 .navbar-inverse .navbar-brand {
4593   color: #9d9d9d;
4594 }
4595 .navbar-inverse .navbar-brand:hover,
4596 .navbar-inverse .navbar-brand:focus {
4597   color: #fff;
4598   background-color: transparent;
4599 }
4600 .navbar-inverse .navbar-text {
4601   color: #9d9d9d;
4602 }
4603 .navbar-inverse .navbar-nav > li > a {
4604   color: #9d9d9d;
4605 }
4606 .navbar-inverse .navbar-nav > li > a:hover,
4607 .navbar-inverse .navbar-nav > li > a:focus {
4608   color: #fff;
4609   background-color: transparent;
4610 }
4611 .navbar-inverse .navbar-nav > .active > a,
4612 .navbar-inverse .navbar-nav > .active > a:hover,
4613 .navbar-inverse .navbar-nav > .active > a:focus {
4614   color: #fff;
4615   background-color: #080808;
4616 }
4617 .navbar-inverse .navbar-nav > .disabled > a,
4618 .navbar-inverse .navbar-nav > .disabled > a:hover,
4619 .navbar-inverse .navbar-nav > .disabled > a:focus {
4620   color: #444;
4621   background-color: transparent;
4622 }
4623 .navbar-inverse .navbar-toggle {
4624   border-color: #333;
4625 }
4626 .navbar-inverse .navbar-toggle:hover,
4627 .navbar-inverse .navbar-toggle:focus {
4628   background-color: #333;
4629 }
4630 .navbar-inverse .navbar-toggle .icon-bar {
4631   background-color: #fff;
4632 }
4633 .navbar-inverse .navbar-collapse,
4634 .navbar-inverse .navbar-form {
4635   border-color: #101010;
4636 }
4637 .navbar-inverse .navbar-nav > .open > a,
4638 .navbar-inverse .navbar-nav > .open > a:hover,
4639 .navbar-inverse .navbar-nav > .open > a:focus {
4640   background-color: #080808;
4641   color: #fff;
4642 }
4643 @media (max-width: 540px) {
4644   .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
4645     border-color: #080808;
4646   }
4647   .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
4648     background-color: #080808;
4649   }
4650   .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
4651     color: #9d9d9d;
4652   }
4653   .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
4654   .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
4655     color: #fff;
4656     background-color: transparent;
4657   }
4658   .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
4659   .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
4660   .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
4661     color: #fff;
4662     background-color: #080808;
4663   }
4664   .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
4665   .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4666   .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4667     color: #444;
4668     background-color: transparent;
4669   }
4670 }
4671 .navbar-inverse .navbar-link {
4672   color: #9d9d9d;
4673 }
4674 .navbar-inverse .navbar-link:hover {
4675   color: #fff;
4676 }
4677 .navbar-inverse .btn-link {
4678   color: #9d9d9d;
4679 }
4680 .navbar-inverse .btn-link:hover,
4681 .navbar-inverse .btn-link:focus {
4682   color: #fff;
4683 }
4684 .navbar-inverse .btn-link[disabled]:hover,
4685 fieldset[disabled] .navbar-inverse .btn-link:hover,
4686 .navbar-inverse .btn-link[disabled]:focus,
4687 fieldset[disabled] .navbar-inverse .btn-link:focus {
4688   color: #444;
4689 }
4690 .breadcrumb {
4691   padding: 8px 15px;
4692   margin-bottom: 18px;
4693   list-style: none;
4694   background-color: #f5f5f5;
4695   border-radius: 2px;
4696 }
4697 .breadcrumb > li {
4698   display: inline-block;
4699 }
4700 .breadcrumb > li + li:before {
4701   content: "/\00a0";
4702   padding: 0 5px;
4703   color: #5e5e5e;
4704 }
4705 .breadcrumb > .active {
4706   color: #777777;
4707 }
4708 .pagination {
4709   display: inline-block;
4710   padding-left: 0;
4711   margin: 18px 0;
4712   border-radius: 2px;
4713 }
4714 .pagination > li {
4715   display: inline;
4716 }
4717 .pagination > li > a,
4718 .pagination > li > span {
4719   position: relative;
4720   float: left;
4721   padding: 6px 12px;
4722   line-height: 1.42857143;
4723   text-decoration: none;
4724   color: #337ab7;
4725   background-color: #fff;
4726   border: 1px solid #ddd;
4727   margin-left: -1px;
4728 }
4729 .pagination > li:first-child > a,
4730 .pagination > li:first-child > span {
4731   margin-left: 0;
4732   border-bottom-left-radius: 2px;
4733   border-top-left-radius: 2px;
4734 }
4735 .pagination > li:last-child > a,
4736 .pagination > li:last-child > span {
4737   border-bottom-right-radius: 2px;
4738   border-top-right-radius: 2px;
4739 }
4740 .pagination > li > a:hover,
4741 .pagination > li > span:hover,
4742 .pagination > li > a:focus,
4743 .pagination > li > span:focus {
4744   z-index: 2;
4745   color: #23527c;
4746   background-color: #eeeeee;
4747   border-color: #ddd;
4748 }
4749 .pagination > .active > a,
4750 .pagination > .active > span,
4751 .pagination > .active > a:hover,
4752 .pagination > .active > span:hover,
4753 .pagination > .active > a:focus,
4754 .pagination > .active > span:focus {
4755   z-index: 3;
4756   color: #fff;
4757   background-color: #337ab7;
4758   border-color: #337ab7;
4759   cursor: default;
4760 }
4761 .pagination > .disabled > span,
4762 .pagination > .disabled > span:hover,
4763 .pagination > .disabled > span:focus,
4764 .pagination > .disabled > a,
4765 .pagination > .disabled > a:hover,
4766 .pagination > .disabled > a:focus {
4767   color: #777777;
4768   background-color: #fff;
4769   border-color: #ddd;
4770   cursor: not-allowed;
4771 }
4772 .pagination-lg > li > a,
4773 .pagination-lg > li > span {
4774   padding: 10px 16px;
4775   font-size: 17px;
4776   line-height: 1.3333333;
4777 }
4778 .pagination-lg > li:first-child > a,
4779 .pagination-lg > li:first-child > span {
4780   border-bottom-left-radius: 3px;
4781   border-top-left-radius: 3px;
4782 }
4783 .pagination-lg > li:last-child > a,
4784 .pagination-lg > li:last-child > span {
4785   border-bottom-right-radius: 3px;
4786   border-top-right-radius: 3px;
4787 }
4788 .pagination-sm > li > a,
4789 .pagination-sm > li > span {
4790   padding: 5px 10px;
4791   font-size: 12px;
4792   line-height: 1.5;
4793 }
4794 .pagination-sm > li:first-child > a,
4795 .pagination-sm > li:first-child > span {
4796   border-bottom-left-radius: 1px;
4797   border-top-left-radius: 1px;
4798 }
4799 .pagination-sm > li:last-child > a,
4800 .pagination-sm > li:last-child > span {
4801   border-bottom-right-radius: 1px;
4802   border-top-right-radius: 1px;
4803 }
4804 .pager {
4805   padding-left: 0;
4806   margin: 18px 0;
4807   list-style: none;
4808   text-align: center;
4809 }
4810 .pager li {
4811   display: inline;
4812 }
4813 .pager li > a,
4814 .pager li > span {
4815   display: inline-block;
4816   padding: 5px 14px;
4817   background-color: #fff;
4818   border: 1px solid #ddd;
4819   border-radius: 15px;
4820 }
4821 .pager li > a:hover,
4822 .pager li > a:focus {
4823   text-decoration: none;
4824   background-color: #eeeeee;
4825 }
4826 .pager .next > a,
4827 .pager .next > span {
4828   float: right;
4829 }
4830 .pager .previous > a,
4831 .pager .previous > span {
4832   float: left;
4833 }
4834 .pager .disabled > a,
4835 .pager .disabled > a:hover,
4836 .pager .disabled > a:focus,
4837 .pager .disabled > span {
4838   color: #777777;
4839   background-color: #fff;
4840   cursor: not-allowed;
4841 }
4842 .label {
4843   display: inline;
4844   padding: .2em .6em .3em;
4845   font-size: 75%;
4846   font-weight: bold;
4847   line-height: 1;
4848   color: #fff;
4849   text-align: center;
4850   white-space: nowrap;
4851   vertical-align: baseline;
4852   border-radius: .25em;
4853 }
4854 a.label:hover,
4855 a.label:focus {
4856   color: #fff;
4857   text-decoration: none;
4858   cursor: pointer;
4859 }
4860 .label:empty {
4861   display: none;
4862 }
4863 .btn .label {
4864   position: relative;
4865   top: -1px;
4866 }
4867 .label-default {
4868   background-color: #777777;
4869 }
4870 .label-default[href]:hover,
4871 .label-default[href]:focus {
4872   background-color: #5e5e5e;
4873 }
4874 .label-primary {
4875   background-color: #337ab7;
4876 }
4877 .label-primary[href]:hover,
4878 .label-primary[href]:focus {
4879   background-color: #286090;
4880 }
4881 .label-success {
4882   background-color: #5cb85c;
4883 }
4884 .label-success[href]:hover,
4885 .label-success[href]:focus {
4886   background-color: #449d44;
4887 }
4888 .label-info {
4889   background-color: #5bc0de;
4890 }
4891 .label-info[href]:hover,
4892 .label-info[href]:focus {
4893   background-color: #31b0d5;
4894 }
4895 .label-warning {
4896   background-color: #f0ad4e;
4897 }
4898 .label-warning[href]:hover,
4899 .label-warning[href]:focus {
4900   background-color: #ec971f;
4901 }
4902 .label-danger {
4903   background-color: #d9534f;
4904 }
4905 .label-danger[href]:hover,
4906 .label-danger[href]:focus {
4907   background-color: #c9302c;
4908 }
4909 .badge {
4910   display: inline-block;
4911   min-width: 10px;
4912   padding: 3px 7px;
4913   font-size: 12px;
4914   font-weight: bold;
4915   color: #fff;
4916   line-height: 1;
4917   vertical-align: middle;
4918   white-space: nowrap;
4919   text-align: center;
4920   background-color: #777777;
4921   border-radius: 10px;
4922 }
4923 .badge:empty {
4924   display: none;
4925 }
4926 .btn .badge {
4927   position: relative;
4928   top: -1px;
4929 }
4930 .btn-xs .badge,
4931 .btn-group-xs > .btn .badge {
4932   top: 0;
4933   padding: 1px 5px;
4934 }
4935 a.badge:hover,
4936 a.badge:focus {
4937   color: #fff;
4938   text-decoration: none;
4939   cursor: pointer;
4940 }
4941 .list-group-item.active > .badge,
4942 .nav-pills > .active > a > .badge {
4943   color: #337ab7;
4944   background-color: #fff;
4945 }
4946 .list-group-item > .badge {
4947   float: right;
4948 }
4949 .list-group-item > .badge + .badge {
4950   margin-right: 5px;
4951 }
4952 .nav-pills > li > a > .badge {
4953   margin-left: 3px;
4954 }
4955 .jumbotron {
4956   padding-top: 30px;
4957   padding-bottom: 30px;
4958   margin-bottom: 30px;
4959   color: inherit;
4960   background-color: #eeeeee;
4961 }
4962 .jumbotron h1,
4963 .jumbotron .h1 {
4964   color: inherit;
4965 }
4966 .jumbotron p {
4967   margin-bottom: 15px;
4968   font-size: 20px;
4969   font-weight: 200;
4970 }
4971 .jumbotron > hr {
4972   border-top-color: #d5d5d5;
4973 }
4974 .container .jumbotron,
4975 .container-fluid .jumbotron {
4976   border-radius: 3px;
4977   padding-left: 0px;
4978   padding-right: 0px;
4979 }
4980 .jumbotron .container {
4981   max-width: 100%;
4982 }
4983 @media screen and (min-width: 768px) {
4984   .jumbotron {
4985     padding-top: 48px;
4986     padding-bottom: 48px;
4987   }
4988   .container .jumbotron,
4989   .container-fluid .jumbotron {
4990     padding-left: 60px;
4991     padding-right: 60px;
4992   }
4993   .jumbotron h1,
4994   .jumbotron .h1 {
4995     font-size: 59px;
4996   }
4997 }
4998 .thumbnail {
4999   display: block;
5000   padding: 4px;
5001   margin-bottom: 18px;
5002   line-height: 1.42857143;
5003   background-color: #fff;
5004   border: 1px solid #ddd;
5005   border-radius: 2px;
5006   -webkit-transition: border 0.2s ease-in-out;
5007   -o-transition: border 0.2s ease-in-out;
5008   transition: border 0.2s ease-in-out;
5009 }
5010 .thumbnail > img,
5011 .thumbnail a > img {
5012   margin-left: auto;
5013   margin-right: auto;
5014 }
5015 a.thumbnail:hover,
5016 a.thumbnail:focus,
5017 a.thumbnail.active {
5018   border-color: #337ab7;
5019 }
5020 .thumbnail .caption {
5021   padding: 9px;
5022   color: #000;
5023 }
5024 .alert {
5025   padding: 15px;
5026   margin-bottom: 18px;
5027   border: 1px solid transparent;
5028   border-radius: 2px;
5029 }
5030 .alert h4 {
5031   margin-top: 0;
5032   color: inherit;
5033 }
5034 .alert .alert-link {
5035   font-weight: bold;
5036 }
5037 .alert > p,
5038 .alert > ul {
5039   margin-bottom: 0;
5040 }
5041 .alert > p + p {
5042   margin-top: 5px;
5043 }
5044 .alert-dismissable,
5045 .alert-dismissible {
5046   padding-right: 35px;
5047 }
5048 .alert-dismissable .close,
5049 .alert-dismissible .close {
5050   position: relative;
5051   top: -2px;
5052   right: -21px;
5053   color: inherit;
5054 }
5055 .alert-success {
5056   background-color: #dff0d8;
5057   border-color: #d6e9c6;
5058   color: #3c763d;
5059 }
5060 .alert-success hr {
5061   border-top-color: #c9e2b3;
5062 }
5063 .alert-success .alert-link {
5064   color: #2b542c;
5065 }
5066 .alert-info {
5067   background-color: #d9edf7;
5068   border-color: #bce8f1;
5069   color: #31708f;
5070 }
5071 .alert-info hr {
5072   border-top-color: #a6e1ec;
5073 }
5074 .alert-info .alert-link {
5075   color: #245269;
5076 }
5077 .alert-warning {
5078   background-color: #fcf8e3;
5079   border-color: #faebcc;
5080   color: #8a6d3b;
5081 }
5082 .alert-warning hr {
5083   border-top-color: #f7e1b5;
5084 }
5085 .alert-warning .alert-link {
5086   color: #66512c;
5087 }
5088 .alert-danger {
5089   background-color: #f2dede;
5090   border-color: #ebccd1;
5091   color: #a94442;
5092 }
5093 .alert-danger hr {
5094   border-top-color: #e4b9c0;
5095 }
5096 .alert-danger .alert-link {
5097   color: #843534;
5098 }
5099 @-webkit-keyframes progress-bar-stripes {
5100   from {
5101     background-position: 40px 0;
5102   }
5103   to {
5104     background-position: 0 0;
5105   }
5106 }
5107 @keyframes progress-bar-stripes {
5108   from {
5109     background-position: 40px 0;
5110   }
5111   to {
5112     background-position: 0 0;
5113   }
5114 }
5115 .progress {
5116   overflow: hidden;
5117   height: 18px;
5118   margin-bottom: 18px;
5119   background-color: #f5f5f5;
5120   border-radius: 2px;
5121   -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5122   box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5123 }
5124 .progress-bar {
5125   float: left;
5126   width: 0%;
5127   height: 100%;
5128   font-size: 12px;
5129   line-height: 18px;
5130   color: #fff;
5131   text-align: center;
5132   background-color: #337ab7;
5133   -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5134   box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5135   -webkit-transition: width 0.6s ease;
5136   -o-transition: width 0.6s ease;
5137   transition: width 0.6s ease;
5138 }
5139 .progress-striped .progress-bar,
5140 .progress-bar-striped {
5141   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5142   background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5143   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5144   background-size: 40px 40px;
5145 }
5146 .progress.active .progress-bar,
5147 .progress-bar.active {
5148   -webkit-animation: progress-bar-stripes 2s linear infinite;
5149   -o-animation: progress-bar-stripes 2s linear infinite;
5150   animation: progress-bar-stripes 2s linear infinite;
5151 }
5152 .progress-bar-success {
5153   background-color: #5cb85c;
5154 }
5155 .progress-striped .progress-bar-success {
5156   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5157   background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5158   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5159 }
5160 .progress-bar-info {
5161   background-color: #5bc0de;
5162 }
5163 .progress-striped .progress-bar-info {
5164   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5165   background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5166   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5167 }
5168 .progress-bar-warning {
5169   background-color: #f0ad4e;
5170 }
5171 .progress-striped .progress-bar-warning {
5172   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5173   background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5174   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5175 }
5176 .progress-bar-danger {
5177   background-color: #d9534f;
5178 }
5179 .progress-striped .progress-bar-danger {
5180   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5181   background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5182   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5183 }
5184 .media {
5185   margin-top: 15px;
5186 }
5187 .media:first-child {
5188   margin-top: 0;
5189 }
5190 .media,
5191 .media-body {
5192   zoom: 1;
5193   overflow: hidden;
5194 }
5195 .media-body {
5196   width: 10000px;
5197 }
5198 .media-object {
5199   display: block;
5200 }
5201 .media-object.img-thumbnail {
5202   max-width: none;
5203 }
5204 .media-right,
5205 .media > .pull-right {
5206   padding-left: 10px;
5207 }
5208 .media-left,
5209 .media > .pull-left {
5210   padding-right: 10px;
5211 }
5212 .media-left,
5213 .media-right,
5214 .media-body {
5215   display: table-cell;
5216   vertical-align: top;
5217 }
5218 .media-middle {
5219   vertical-align: middle;
5220 }
5221 .media-bottom {
5222   vertical-align: bottom;
5223 }
5224 .media-heading {
5225   margin-top: 0;
5226   margin-bottom: 5px;
5227 }
5228 .media-list {
5229   padding-left: 0;
5230   list-style: none;
5231 }
5232 .list-group {
5233   margin-bottom: 20px;
5234   padding-left: 0;
5235 }
5236 .list-group-item {
5237   position: relative;
5238   display: block;
5239   padding: 10px 15px;
5240   margin-bottom: -1px;
5241   background-color: #fff;
5242   border: 1px solid #ddd;
5243 }
5244 .list-group-item:first-child {
5245   border-top-right-radius: 2px;
5246   border-top-left-radius: 2px;
5247 }
5248 .list-group-item:last-child {
5249   margin-bottom: 0;
5250   border-bottom-right-radius: 2px;
5251   border-bottom-left-radius: 2px;
5252 }
5253 a.list-group-item,
5254 button.list-group-item {
5255   color: #555;
5256 }
5257 a.list-group-item .list-group-item-heading,
5258 button.list-group-item .list-group-item-heading {
5259   color: #333;
5260 }
5261 a.list-group-item:hover,
5262 button.list-group-item:hover,
5263 a.list-group-item:focus,
5264 button.list-group-item:focus {
5265   text-decoration: none;
5266   color: #555;
5267   background-color: #f5f5f5;
5268 }
5269 button.list-group-item {
5270   width: 100%;
5271   text-align: left;
5272 }
5273 .list-group-item.disabled,
5274 .list-group-item.disabled:hover,
5275 .list-group-item.disabled:focus {
5276   background-color: #eeeeee;
5277   color: #777777;
5278   cursor: not-allowed;
5279 }
5280 .list-group-item.disabled .list-group-item-heading,
5281 .list-group-item.disabled:hover .list-group-item-heading,
5282 .list-group-item.disabled:focus .list-group-item-heading {
5283   color: inherit;
5284 }
5285 .list-group-item.disabled .list-group-item-text,
5286 .list-group-item.disabled:hover .list-group-item-text,
5287 .list-group-item.disabled:focus .list-group-item-text {
5288   color: #777777;
5289 }
5290 .list-group-item.active,
5291 .list-group-item.active:hover,
5292 .list-group-item.active:focus {
5293   z-index: 2;
5294   color: #fff;
5295   background-color: #337ab7;
5296   border-color: #337ab7;
5297 }
5298 .list-group-item.active .list-group-item-heading,
5299 .list-group-item.active:hover .list-group-item-heading,
5300 .list-group-item.active:focus .list-group-item-heading,
5301 .list-group-item.active .list-group-item-heading > small,
5302 .list-group-item.active:hover .list-group-item-heading > small,
5303 .list-group-item.active:focus .list-group-item-heading > small,
5304 .list-group-item.active .list-group-item-heading > .small,
5305 .list-group-item.active:hover .list-group-item-heading > .small,
5306 .list-group-item.active:focus .list-group-item-heading > .small {
5307   color: inherit;
5308 }
5309 .list-group-item.active .list-group-item-text,
5310 .list-group-item.active:hover .list-group-item-text,
5311 .list-group-item.active:focus .list-group-item-text {
5312   color: #c7ddef;
5313 }
5314 .list-group-item-success {
5315   color: #3c763d;
5316   background-color: #dff0d8;
5317 }
5318 a.list-group-item-success,
5319 button.list-group-item-success {
5320   color: #3c763d;
5321 }
5322 a.list-group-item-success .list-group-item-heading,
5323 button.list-group-item-success .list-group-item-heading {
5324   color: inherit;
5325 }
5326 a.list-group-item-success:hover,
5327 button.list-group-item-success:hover,
5328 a.list-group-item-success:focus,
5329 button.list-group-item-success:focus {
5330   color: #3c763d;
5331   background-color: #d0e9c6;
5332 }
5333 a.list-group-item-success.active,
5334 button.list-group-item-success.active,
5335 a.list-group-item-success.active:hover,
5336 button.list-group-item-success.active:hover,
5337 a.list-group-item-success.active:focus,
5338 button.list-group-item-success.active:focus {
5339   color: #fff;
5340   background-color: #3c763d;
5341   border-color: #3c763d;
5342 }
5343 .list-group-item-info {
5344   color: #31708f;
5345   background-color: #d9edf7;
5346 }
5347 a.list-group-item-info,
5348 button.list-group-item-info {
5349   color: #31708f;
5350 }
5351 a.list-group-item-info .list-group-item-heading,
5352 button.list-group-item-info .list-group-item-heading {
5353   color: inherit;
5354 }
5355 a.list-group-item-info:hover,
5356 button.list-group-item-info:hover,
5357 a.list-group-item-info:focus,
5358 button.list-group-item-info:focus {
5359   color: #31708f;
5360   background-color: #c4e3f3;
5361 }
5362 a.list-group-item-info.active,
5363 button.list-group-item-info.active,
5364 a.list-group-item-info.active:hover,
5365 button.list-group-item-info.active:hover,
5366 a.list-group-item-info.active:focus,
5367 button.list-group-item-info.active:focus {
5368   color: #fff;
5369   background-color: #31708f;
5370   border-color: #31708f;
5371 }
5372 .list-group-item-warning {
5373   color: #8a6d3b;
5374   background-color: #fcf8e3;
5375 }
5376 a.list-group-item-warning,
5377 button.list-group-item-warning {
5378   color: #8a6d3b;
5379 }
5380 a.list-group-item-warning .list-group-item-heading,
5381 button.list-group-item-warning .list-group-item-heading {
5382   color: inherit;
5383 }
5384 a.list-group-item-warning:hover,
5385 button.list-group-item-warning:hover,
5386 a.list-group-item-warning:focus,
5387 button.list-group-item-warning:focus {
5388   color: #8a6d3b;
5389   background-color: #faf2cc;
5390 }
5391 a.list-group-item-warning.active,
5392 button.list-group-item-warning.active,
5393 a.list-group-item-warning.active:hover,
5394 button.list-group-item-warning.active:hover,
5395 a.list-group-item-warning.active:focus,
5396 button.list-group-item-warning.active:focus {
5397   color: #fff;
5398   background-color: #8a6d3b;
5399   border-color: #8a6d3b;
5400 }
5401 .list-group-item-danger {
5402   color: #a94442;
5403   background-color: #f2dede;
5404 }
5405 a.list-group-item-danger,
5406 button.list-group-item-danger {
5407   color: #a94442;
5408 }
5409 a.list-group-item-danger .list-group-item-heading,
5410 button.list-group-item-danger .list-group-item-heading {
5411   color: inherit;
5412 }
5413 a.list-group-item-danger:hover,
5414 button.list-group-item-danger:hover,
5415 a.list-group-item-danger:focus,
5416 button.list-group-item-danger:focus {
5417   color: #a94442;
5418   background-color: #ebcccc;
5419 }
5420 a.list-group-item-danger.active,
5421 button.list-group-item-danger.active,
5422 a.list-group-item-danger.active:hover,
5423 button.list-group-item-danger.active:hover,
5424 a.list-group-item-danger.active:focus,
5425 button.list-group-item-danger.active:focus {
5426   color: #fff;
5427   background-color: #a94442;
5428   border-color: #a94442;
5429 }
5430 .list-group-item-heading {
5431   margin-top: 0;
5432   margin-bottom: 5px;
5433 }
5434 .list-group-item-text {
5435   margin-bottom: 0;
5436   line-height: 1.3;
5437 }
5438 .panel {
5439   margin-bottom: 18px;
5440   background-color: #fff;
5441   border: 1px solid transparent;
5442   border-radius: 2px;
5443   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5444   box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5445 }
5446 .panel-body {
5447   padding: 15px;
5448 }
5449 .panel-heading {
5450   padding: 10px 15px;
5451   border-bottom: 1px solid transparent;
5452   border-top-right-radius: 1px;
5453   border-top-left-radius: 1px;
5454 }
5455 .panel-heading > .dropdown .dropdown-toggle {
5456   color: inherit;
5457 }
5458 .panel-title {
5459   margin-top: 0;
5460   margin-bottom: 0;
5461   font-size: 15px;
5462   color: inherit;
5463 }
5464 .panel-title > a,
5465 .panel-title > small,
5466 .panel-title > .small,
5467 .panel-title > small > a,
5468 .panel-title > .small > a {
5469   color: inherit;
5470 }
5471 .panel-footer {
5472   padding: 10px 15px;
5473   background-color: #f5f5f5;
5474   border-top: 1px solid #ddd;
5475   border-bottom-right-radius: 1px;
5476   border-bottom-left-radius: 1px;
5477 }
5478 .panel > .list-group,
5479 .panel > .panel-collapse > .list-group {
5480   margin-bottom: 0;
5481 }
5482 .panel > .list-group .list-group-item,
5483 .panel > .panel-collapse > .list-group .list-group-item {
5484   border-width: 1px 0;
5485   border-radius: 0;
5486 }
5487 .panel > .list-group:first-child .list-group-item:first-child,
5488 .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
5489   border-top: 0;
5490   border-top-right-radius: 1px;
5491   border-top-left-radius: 1px;
5492 }
5493 .panel > .list-group:last-child .list-group-item:last-child,
5494 .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
5495   border-bottom: 0;
5496   border-bottom-right-radius: 1px;
5497   border-bottom-left-radius: 1px;
5498 }
5499 .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
5500   border-top-right-radius: 0;
5501   border-top-left-radius: 0;
5502 }
5503 .panel-heading + .list-group .list-group-item:first-child {
5504   border-top-width: 0;
5505 }
5506 .list-group + .panel-footer {
5507   border-top-width: 0;
5508 }
5509 .panel > .table,
5510 .panel > .table-responsive > .table,
5511 .panel > .panel-collapse > .table {
5512   margin-bottom: 0;
5513 }
5514 .panel > .table caption,
5515 .panel > .table-responsive > .table caption,
5516 .panel > .panel-collapse > .table caption {
5517   padding-left: 15px;
5518   padding-right: 15px;
5519 }
5520 .panel > .table:first-child,
5521 .panel > .table-responsive:first-child > .table:first-child {
5522   border-top-right-radius: 1px;
5523   border-top-left-radius: 1px;
5524 }
5525 .panel > .table:first-child > thead:first-child > tr:first-child,
5526 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
5527 .panel > .table:first-child > tbody:first-child > tr:first-child,
5528 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
5529   border-top-left-radius: 1px;
5530   border-top-right-radius: 1px;
5531 }
5532 .panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
5533 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
5534 .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5535 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5536 .panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
5537 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
5538 .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
5539 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
5540   border-top-left-radius: 1px;
5541 }
5542 .panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
5543 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
5544 .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5545 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5546 .panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
5547 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
5548 .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
5549 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
5550   border-top-right-radius: 1px;
5551 }
5552 .panel > .table:last-child,
5553 .panel > .table-responsive:last-child > .table:last-child {
5554   border-bottom-right-radius: 1px;
5555   border-bottom-left-radius: 1px;
5556 }
5557 .panel > .table:last-child > tbody:last-child > tr:last-child,
5558 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
5559 .panel > .table:last-child > tfoot:last-child > tr:last-child,
5560 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
5561   border-bottom-left-radius: 1px;
5562   border-bottom-right-radius: 1px;
5563 }
5564 .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5565 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5566 .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5567 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5568 .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5569 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5570 .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
5571 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
5572   border-bottom-left-radius: 1px;
5573 }
5574 .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5575 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5576 .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5577 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5578 .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5579 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5580 .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
5581 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
5582   border-bottom-right-radius: 1px;
5583 }
5584 .panel > .panel-body + .table,
5585 .panel > .panel-body + .table-responsive,
5586 .panel > .table + .panel-body,
5587 .panel > .table-responsive + .panel-body {
5588   border-top: 1px solid #ddd;
5589 }
5590 .panel > .table > tbody:first-child > tr:first-child th,
5591 .panel > .table > tbody:first-child > tr:first-child td {
5592   border-top: 0;
5593 }
5594 .panel > .table-bordered,
5595 .panel > .table-responsive > .table-bordered {
5596   border: 0;
5597 }
5598 .panel > .table-bordered > thead > tr > th:first-child,
5599 .panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
5600 .panel > .table-bordered > tbody > tr > th:first-child,
5601 .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
5602 .panel > .table-bordered > tfoot > tr > th:first-child,
5603 .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
5604 .panel > .table-bordered > thead > tr > td:first-child,
5605 .panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
5606 .panel > .table-bordered > tbody > tr > td:first-child,
5607 .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
5608 .panel > .table-bordered > tfoot > tr > td:first-child,
5609 .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
5610   border-left: 0;
5611 }
5612 .panel > .table-bordered > thead > tr > th:last-child,
5613 .panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
5614 .panel > .table-bordered > tbody > tr > th:last-child,
5615 .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
5616 .panel > .table-bordered > tfoot > tr > th:last-child,
5617 .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
5618 .panel > .table-bordered > thead > tr > td:last-child,
5619 .panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
5620 .panel > .table-bordered > tbody > tr > td:last-child,
5621 .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
5622 .panel > .table-bordered > tfoot > tr > td:last-child,
5623 .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
5624   border-right: 0;
5625 }
5626 .panel > .table-bordered > thead > tr:first-child > td,
5627 .panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
5628 .panel > .table-bordered > tbody > tr:first-child > td,
5629 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
5630 .panel > .table-bordered > thead > tr:first-child > th,
5631 .panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
5632 .panel > .table-bordered > tbody > tr:first-child > th,
5633 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
5634   border-bottom: 0;
5635 }
5636 .panel > .table-bordered > tbody > tr:last-child > td,
5637 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
5638 .panel > .table-bordered > tfoot > tr:last-child > td,
5639 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
5640 .panel > .table-bordered > tbody > tr:last-child > th,
5641 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
5642 .panel > .table-bordered > tfoot > tr:last-child > th,
5643 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
5644   border-bottom: 0;
5645 }
5646 .panel > .table-responsive {
5647   border: 0;
5648   margin-bottom: 0;
5649 }
5650 .panel-group {
5651   margin-bottom: 18px;
5652 }
5653 .panel-group .panel {
5654   margin-bottom: 0;
5655   border-radius: 2px;
5656 }
5657 .panel-group .panel + .panel {
5658   margin-top: 5px;
5659 }
5660 .panel-group .panel-heading {
5661   border-bottom: 0;
5662 }
5663 .panel-group .panel-heading + .panel-collapse > .panel-body,
5664 .panel-group .panel-heading + .panel-collapse > .list-group {
5665   border-top: 1px solid #ddd;
5666 }
5667 .panel-group .panel-footer {
5668   border-top: 0;
5669 }
5670 .panel-group .panel-footer + .panel-collapse .panel-body {
5671   border-bottom: 1px solid #ddd;
5672 }
5673 .panel-default {
5674   border-color: #ddd;
5675 }
5676 .panel-default > .panel-heading {
5677   color: #333333;
5678   background-color: #f5f5f5;
5679   border-color: #ddd;
5680 }
5681 .panel-default > .panel-heading + .panel-collapse > .panel-body {
5682   border-top-color: #ddd;
5683 }
5684 .panel-default > .panel-heading .badge {
5685   color: #f5f5f5;
5686   background-color: #333333;
5687 }
5688 .panel-default > .panel-footer + .panel-collapse > .panel-body {
5689   border-bottom-color: #ddd;
5690 }
5691 .panel-primary {
5692   border-color: #337ab7;
5693 }
5694 .panel-primary > .panel-heading {
5695   color: #fff;
5696   background-color: #337ab7;
5697   border-color: #337ab7;
5698 }
5699 .panel-primary > .panel-heading + .panel-collapse > .panel-body {
5700   border-top-color: #337ab7;
5701 }
5702 .panel-primary > .panel-heading .badge {
5703   color: #337ab7;
5704   background-color: #fff;
5705 }
5706 .panel-primary > .panel-footer + .panel-collapse > .panel-body {
5707   border-bottom-color: #337ab7;
5708 }
5709 .panel-success {
5710   border-color: #d6e9c6;
5711 }
5712 .panel-success > .panel-heading {
5713   color: #3c763d;
5714   background-color: #dff0d8;
5715   border-color: #d6e9c6;
5716 }
5717 .panel-success > .panel-heading + .panel-collapse > .panel-body {
5718   border-top-color: #d6e9c6;
5719 }
5720 .panel-success > .panel-heading .badge {
5721   color: #dff0d8;
5722   background-color: #3c763d;
5723 }
5724 .panel-success > .panel-footer + .panel-collapse > .panel-body {
5725   border-bottom-color: #d6e9c6;
5726 }
5727 .panel-info {
5728   border-color: #bce8f1;
5729 }
5730 .panel-info > .panel-heading {
5731   color: #31708f;
5732   background-color: #d9edf7;
5733   border-color: #bce8f1;
5734 }
5735 .panel-info > .panel-heading + .panel-collapse > .panel-body {
5736   border-top-color: #bce8f1;
5737 }
5738 .panel-info > .panel-heading .badge {
5739   color: #d9edf7;
5740   background-color: #31708f;
5741 }
5742 .panel-info > .panel-footer + .panel-collapse > .panel-body {
5743   border-bottom-color: #bce8f1;
5744 }
5745 .panel-warning {
5746   border-color: #faebcc;
5747 }
5748 .panel-warning > .panel-heading {
5749   color: #8a6d3b;
5750   background-color: #fcf8e3;
5751   border-color: #faebcc;
5752 }
5753 .panel-warning > .panel-heading + .panel-collapse > .panel-body {
5754   border-top-color: #faebcc;
5755 }
5756 .panel-warning > .panel-heading .badge {
5757   color: #fcf8e3;
5758   background-color: #8a6d3b;
5759 }
5760 .panel-warning > .panel-footer + .panel-collapse > .panel-body {
5761   border-bottom-color: #faebcc;
5762 }
5763 .panel-danger {
5764   border-color: #ebccd1;
5765 }
5766 .panel-danger > .panel-heading {
5767   color: #a94442;
5768   background-color: #f2dede;
5769   border-color: #ebccd1;
5770 }
5771 .panel-danger > .panel-heading + .panel-collapse > .panel-body {
5772   border-top-color: #ebccd1;
5773 }
5774 .panel-danger > .panel-heading .badge {
5775   color: #f2dede;
5776   background-color: #a94442;
5777 }
5778 .panel-danger > .panel-footer + .panel-collapse > .panel-body {
5779   border-bottom-color: #ebccd1;
5780 }
5781 .embed-responsive {
5782   position: relative;
5783   display: block;
5784   height: 0;
5785   padding: 0;
5786   overflow: hidden;
5787 }
5788 .embed-responsive .embed-responsive-item,
5789 .embed-responsive iframe,
5790 .embed-responsive embed,
5791 .embed-responsive object,
5792 .embed-responsive video {
5793   position: absolute;
5794   top: 0;
5795   left: 0;
5796   bottom: 0;
5797   height: 100%;
5798   width: 100%;
5799   border: 0;
5800 }
5801 .embed-responsive-16by9 {
5802   padding-bottom: 56.25%;
5803 }
5804 .embed-responsive-4by3 {
5805   padding-bottom: 75%;
5806 }
5807 .well {
5808   min-height: 20px;
5809   padding: 19px;
5810   margin-bottom: 20px;
5811   background-color: #f5f5f5;
5812   border: 1px solid #e3e3e3;
5813   border-radius: 2px;
5814   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5815   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5816 }
5817 .well blockquote {
5818   border-color: #ddd;
5819   border-color: rgba(0, 0, 0, 0.15);
5820 }
5821 .well-lg {
5822   padding: 24px;
5823   border-radius: 3px;
5824 }
5825 .well-sm {
5826   padding: 9px;
5827   border-radius: 1px;
5828 }
5829 .close {
5830   float: right;
5831   font-size: 19.5px;
5832   font-weight: bold;
5833   line-height: 1;
5834   color: #000;
5835   text-shadow: 0 1px 0 #fff;
5836   opacity: 0.2;
5837   filter: alpha(opacity=20);
5838 }
5839 .close:hover,
5840 .close:focus {
5841   color: #000;
5842   text-decoration: none;
5843   cursor: pointer;
5844   opacity: 0.5;
5845   filter: alpha(opacity=50);
5846 }
5847 button.close {
5848   padding: 0;
5849   cursor: pointer;
5850   background: transparent;
5851   border: 0;
5852   -webkit-appearance: none;
5853 }
5854 .modal-open {
5855   overflow: hidden;
5856 }
5857 .modal {
5858   display: none;
5859   overflow: hidden;
5860   position: fixed;
5861   top: 0;
5862   right: 0;
5863   bottom: 0;
5864   left: 0;
5865   z-index: 1050;
5866   -webkit-overflow-scrolling: touch;
5867   outline: 0;
5868 }
5869 .modal.fade .modal-dialog {
5870   -webkit-transform: translate(0, -25%);
5871   -ms-transform: translate(0, -25%);
5872   -o-transform: translate(0, -25%);
5873   transform: translate(0, -25%);
5874   -webkit-transition: -webkit-transform 0.3s ease-out;
5875   -moz-transition: -moz-transform 0.3s ease-out;
5876   -o-transition: -o-transform 0.3s ease-out;
5877   transition: transform 0.3s ease-out;
5878 }
5879 .modal.in .modal-dialog {
5880   -webkit-transform: translate(0, 0);
5881   -ms-transform: translate(0, 0);
5882   -o-transform: translate(0, 0);
5883   transform: translate(0, 0);
5884 }
5885 .modal-open .modal {
5886   overflow-x: hidden;
5887   overflow-y: auto;
5888 }
5889 .modal-dialog {
5890   position: relative;
5891   width: auto;
5892   margin: 10px;
5893 }
5894 .modal-content {
5895   position: relative;
5896   background-color: #fff;
5897   border: 1px solid #999;
5898   border: 1px solid rgba(0, 0, 0, 0.2);
5899   border-radius: 3px;
5900   -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5901   box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5902   background-clip: padding-box;
5903   outline: 0;
5904 }
5905 .modal-backdrop {
5906   position: fixed;
5907   top: 0;
5908   right: 0;
5909   bottom: 0;
5910   left: 0;
5911   z-index: 1040;
5912   background-color: #000;
5913 }
5914 .modal-backdrop.fade {
5915   opacity: 0;
5916   filter: alpha(opacity=0);
5917 }
5918 .modal-backdrop.in {
5919   opacity: 0.5;
5920   filter: alpha(opacity=50);
5921 }
5922 .modal-header {
5923   padding: 15px;
5924   border-bottom: 1px solid #e5e5e5;
5925 }
5926 .modal-header .close {
5927   margin-top: -2px;
5928 }
5929 .modal-title {
5930   margin: 0;
5931   line-height: 1.42857143;
5932 }
5933 .modal-body {
5934   position: relative;
5935   padding: 15px;
5936 }
5937 .modal-footer {
5938   padding: 15px;
5939   text-align: right;
5940   border-top: 1px solid #e5e5e5;
5941 }
5942 .modal-footer .btn + .btn {
5943   margin-left: 5px;
5944   margin-bottom: 0;
5945 }
5946 .modal-footer .btn-group .btn + .btn {
5947   margin-left: -1px;
5948 }
5949 .modal-footer .btn-block + .btn-block {
5950   margin-left: 0;
5951 }
5952 .modal-scrollbar-measure {
5953   position: absolute;
5954   top: -9999px;
5955   width: 50px;
5956   height: 50px;
5957   overflow: scroll;
5958 }
5959 @media (min-width: 768px) {
5960   .modal-dialog {
5961     width: 600px;
5962     margin: 30px auto;
5963   }
5964   .modal-content {
5965     -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5966     box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5967   }
5968   .modal-sm {
5969     width: 300px;
5970   }
5971 }
5972 @media (min-width: 992px) {
5973   .modal-lg {
5974     width: 900px;
5975   }
5976 }
5977 .tooltip {
5978   position: absolute;
5979   z-index: 1070;
5980   display: block;
5981   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
5982   font-style: normal;
5983   font-weight: normal;
5984   letter-spacing: normal;
5985   line-break: auto;
5986   line-height: 1.42857143;
5987   text-align: left;
5988   text-align: start;
5989   text-decoration: none;
5990   text-shadow: none;
5991   text-transform: none;
5992   white-space: normal;
5993   word-break: normal;
5994   word-spacing: normal;
5995   word-wrap: normal;
5996   font-size: 12px;
5997   opacity: 0;
5998   filter: alpha(opacity=0);
5999 }
6000 .tooltip.in {
6001   opacity: 0.9;
6002   filter: alpha(opacity=90);
6003 }
6004 .tooltip.top {
6005   margin-top: -3px;
6006   padding: 5px 0;
6007 }
6008 .tooltip.right {
6009   margin-left: 3px;
6010   padding: 0 5px;
6011 }
6012 .tooltip.bottom {
6013   margin-top: 3px;
6014   padding: 5px 0;
6015 }
6016 .tooltip.left {
6017   margin-left: -3px;
6018   padding: 0 5px;
6019 }
6020 .tooltip-inner {
6021   max-width: 200px;
6022   padding: 3px 8px;
6023   color: #fff;
6024   text-align: center;
6025   background-color: #000;
6026   border-radius: 2px;
6027 }
6028 .tooltip-arrow {
6029   position: absolute;
6030   width: 0;
6031   height: 0;
6032   border-color: transparent;
6033   border-style: solid;
6034 }
6035 .tooltip.top .tooltip-arrow {
6036   bottom: 0;
6037   left: 50%;
6038   margin-left: -5px;
6039   border-width: 5px 5px 0;
6040   border-top-color: #000;
6041 }
6042 .tooltip.top-left .tooltip-arrow {
6043   bottom: 0;
6044   right: 5px;
6045   margin-bottom: -5px;
6046   border-width: 5px 5px 0;
6047   border-top-color: #000;
6048 }
6049 .tooltip.top-right .tooltip-arrow {
6050   bottom: 0;
6051   left: 5px;
6052   margin-bottom: -5px;
6053   border-width: 5px 5px 0;
6054   border-top-color: #000;
6055 }
6056 .tooltip.right .tooltip-arrow {
6057   top: 50%;
6058   left: 0;
6059   margin-top: -5px;
6060   border-width: 5px 5px 5px 0;
6061   border-right-color: #000;
6062 }
6063 .tooltip.left .tooltip-arrow {
6064   top: 50%;
6065   right: 0;
6066   margin-top: -5px;
6067   border-width: 5px 0 5px 5px;
6068   border-left-color: #000;
6069 }
6070 .tooltip.bottom .tooltip-arrow {
6071   top: 0;
6072   left: 50%;
6073   margin-left: -5px;
6074   border-width: 0 5px 5px;
6075   border-bottom-color: #000;
6076 }
6077 .tooltip.bottom-left .tooltip-arrow {
6078   top: 0;
6079   right: 5px;
6080   margin-top: -5px;
6081   border-width: 0 5px 5px;
6082   border-bottom-color: #000;
6083 }
6084 .tooltip.bottom-right .tooltip-arrow {
6085   top: 0;
6086   left: 5px;
6087   margin-top: -5px;
6088   border-width: 0 5px 5px;
6089   border-bottom-color: #000;
6090 }
6091 .popover {
6092   position: absolute;
6093   top: 0;
6094   left: 0;
6095   z-index: 1060;
6096   display: none;
6097   max-width: 276px;
6098   padding: 1px;
6099   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
6100   font-style: normal;
6101   font-weight: normal;
6102   letter-spacing: normal;
6103   line-break: auto;
6104   line-height: 1.42857143;
6105   text-align: left;
6106   text-align: start;
6107   text-decoration: none;
6108   text-shadow: none;
6109   text-transform: none;
6110   white-space: normal;
6111   word-break: normal;
6112   word-spacing: normal;
6113   word-wrap: normal;
6114   font-size: 13px;
6115   background-color: #fff;
6116   background-clip: padding-box;
6117   border: 1px solid #ccc;
6118   border: 1px solid rgba(0, 0, 0, 0.2);
6119   border-radius: 3px;
6120   -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6121   box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6122 }
6123 .popover.top {
6124   margin-top: -10px;
6125 }
6126 .popover.right {
6127   margin-left: 10px;
6128 }
6129 .popover.bottom {
6130   margin-top: 10px;
6131 }
6132 .popover.left {
6133   margin-left: -10px;
6134 }
6135 .popover-title {
6136   margin: 0;
6137   padding: 8px 14px;
6138   font-size: 13px;
6139   background-color: #f7f7f7;
6140   border-bottom: 1px solid #ebebeb;
6141   border-radius: 2px 2px 0 0;
6142 }
6143 .popover-content {
6144   padding: 9px 14px;
6145 }
6146 .popover > .arrow,
6147 .popover > .arrow:after {
6148   position: absolute;
6149   display: block;
6150   width: 0;
6151   height: 0;
6152   border-color: transparent;
6153   border-style: solid;
6154 }
6155 .popover > .arrow {
6156   border-width: 11px;
6157 }
6158 .popover > .arrow:after {
6159   border-width: 10px;
6160   content: "";
6161 }
6162 .popover.top > .arrow {
6163   left: 50%;
6164   margin-left: -11px;
6165   border-bottom-width: 0;
6166   border-top-color: #999999;
6167   border-top-color: rgba(0, 0, 0, 0.25);
6168   bottom: -11px;
6169 }
6170 .popover.top > .arrow:after {
6171   content: " ";
6172   bottom: 1px;
6173   margin-left: -10px;
6174   border-bottom-width: 0;
6175   border-top-color: #fff;
6176 }
6177 .popover.right > .arrow {
6178   top: 50%;
6179   left: -11px;
6180   margin-top: -11px;
6181   border-left-width: 0;
6182   border-right-color: #999999;
6183   border-right-color: rgba(0, 0, 0, 0.25);
6184 }
6185 .popover.right > .arrow:after {
6186   content: " ";
6187   left: 1px;
6188   bottom: -10px;
6189   border-left-width: 0;
6190   border-right-color: #fff;
6191 }
6192 .popover.bottom > .arrow {
6193   left: 50%;
6194   margin-left: -11px;
6195   border-top-width: 0;
6196   border-bottom-color: #999999;
6197   border-bottom-color: rgba(0, 0, 0, 0.25);
6198   top: -11px;
6199 }
6200 .popover.bottom > .arrow:after {
6201   content: " ";
6202   top: 1px;
6203   margin-left: -10px;
6204   border-top-width: 0;
6205   border-bottom-color: #fff;
6206 }
6207 .popover.left > .arrow {
6208   top: 50%;
6209   right: -11px;
6210   margin-top: -11px;
6211   border-right-width: 0;
6212   border-left-color: #999999;
6213   border-left-color: rgba(0, 0, 0, 0.25);
6214 }
6215 .popover.left > .arrow:after {
6216   content: " ";
6217   right: 1px;
6218   border-right-width: 0;
6219   border-left-color: #fff;
6220   bottom: -10px;
6221 }
6222 .carousel {
6223   position: relative;
6224 }
6225 .carousel-inner {
6226   position: relative;
6227   overflow: hidden;
6228   width: 100%;
6229 }
6230 .carousel-inner > .item {
6231   display: none;
6232   position: relative;
6233   -webkit-transition: 0.6s ease-in-out left;
6234   -o-transition: 0.6s ease-in-out left;
6235   transition: 0.6s ease-in-out left;
6236 }
6237 .carousel-inner > .item > img,
6238 .carousel-inner > .item > a > img {
6239   line-height: 1;
6240 }
6241 @media all and (transform-3d), (-webkit-transform-3d) {
6242   .carousel-inner > .item {
6243     -webkit-transition: -webkit-transform 0.6s ease-in-out;
6244     -moz-transition: -moz-transform 0.6s ease-in-out;
6245     -o-transition: -o-transform 0.6s ease-in-out;
6246     transition: transform 0.6s ease-in-out;
6247     -webkit-backface-visibility: hidden;
6248     -moz-backface-visibility: hidden;
6249     backface-visibility: hidden;
6250     -webkit-perspective: 1000px;
6251     -moz-perspective: 1000px;
6252     perspective: 1000px;
6253   }
6254   .carousel-inner > .item.next,
6255   .carousel-inner > .item.active.right {
6256     -webkit-transform: translate3d(100%, 0, 0);
6257     transform: translate3d(100%, 0, 0);
6258     left: 0;
6259   }
6260   .carousel-inner > .item.prev,
6261   .carousel-inner > .item.active.left {
6262     -webkit-transform: translate3d(-100%, 0, 0);
6263     transform: translate3d(-100%, 0, 0);
6264     left: 0;
6265   }
6266   .carousel-inner > .item.next.left,
6267   .carousel-inner > .item.prev.right,
6268   .carousel-inner > .item.active {
6269     -webkit-transform: translate3d(0, 0, 0);
6270     transform: translate3d(0, 0, 0);
6271     left: 0;
6272   }
6273 }
6274 .carousel-inner > .active,
6275 .carousel-inner > .next,
6276 .carousel-inner > .prev {
6277   display: block;
6278 }
6279 .carousel-inner > .active {
6280   left: 0;
6281 }
6282 .carousel-inner > .next,
6283 .carousel-inner > .prev {
6284   position: absolute;
6285   top: 0;
6286   width: 100%;
6287 }
6288 .carousel-inner > .next {
6289   left: 100%;
6290 }
6291 .carousel-inner > .prev {
6292   left: -100%;
6293 }
6294 .carousel-inner > .next.left,
6295 .carousel-inner > .prev.right {
6296   left: 0;
6297 }
6298 .carousel-inner > .active.left {
6299   left: -100%;
6300 }
6301 .carousel-inner > .active.right {
6302   left: 100%;
6303 }
6304 .carousel-control {
6305   position: absolute;
6306   top: 0;
6307   left: 0;
6308   bottom: 0;
6309   width: 15%;
6310   opacity: 0.5;
6311   filter: alpha(opacity=50);
6312   font-size: 20px;
6313   color: #fff;
6314   text-align: center;
6315   text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6316   background-color: rgba(0, 0, 0, 0);
6317 }
6318 .carousel-control.left {
6319   background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6320   background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6321   background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6322   background-repeat: repeat-x;
6323   filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
6324 }
6325 .carousel-control.right {
6326   left: auto;
6327   right: 0;
6328   background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6329   background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6330   background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6331   background-repeat: repeat-x;
6332   filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
6333 }
6334 .carousel-control:hover,
6335 .carousel-control:focus {
6336   outline: 0;
6337   color: #fff;
6338   text-decoration: none;
6339   opacity: 0.9;
6340   filter: alpha(opacity=90);
6341 }
6342 .carousel-control .icon-prev,
6343 .carousel-control .icon-next,
6344 .carousel-control .glyphicon-chevron-left,
6345 .carousel-control .glyphicon-chevron-right {
6346   position: absolute;
6347   top: 50%;
6348   margin-top: -10px;
6349   z-index: 5;
6350   display: inline-block;
6351 }
6352 .carousel-control .icon-prev,
6353 .carousel-control .glyphicon-chevron-left {
6354   left: 50%;
6355   margin-left: -10px;
6356 }
6357 .carousel-control .icon-next,
6358 .carousel-control .glyphicon-chevron-right {
6359   right: 50%;
6360   margin-right: -10px;
6361 }
6362 .carousel-control .icon-prev,
6363 .carousel-control .icon-next {
6364   width: 20px;
6365   height: 20px;
6366   line-height: 1;
6367   font-family: serif;
6368 }
6369 .carousel-control .icon-prev:before {
6370   content: '\2039';
6371 }
6372 .carousel-control .icon-next:before {
6373   content: '\203a';
6374 }
6375 .carousel-indicators {
6376   position: absolute;
6377   bottom: 10px;
6378   left: 50%;
6379   z-index: 15;
6380   width: 60%;
6381   margin-left: -30%;
6382   padding-left: 0;
6383   list-style: none;
6384   text-align: center;
6385 }
6386 .carousel-indicators li {
6387   display: inline-block;
6388   width: 10px;
6389   height: 10px;
6390   margin: 1px;
6391   text-indent: -999px;
6392   border: 1px solid #fff;
6393   border-radius: 10px;
6394   cursor: pointer;
6395   background-color: #000 \9;
6396   background-color: rgba(0, 0, 0, 0);
6397 }
6398 .carousel-indicators .active {
6399   margin: 0;
6400   width: 12px;
6401   height: 12px;
6402   background-color: #fff;
6403 }
6404 .carousel-caption {
6405   position: absolute;
6406   left: 15%;
6407   right: 15%;
6408   bottom: 20px;
6409   z-index: 10;
6410   padding-top: 20px;
6411   padding-bottom: 20px;
6412   color: #fff;
6413   text-align: center;
6414   text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6415 }
6416 .carousel-caption .btn {
6417   text-shadow: none;
6418 }
6419 @media screen and (min-width: 768px) {
6420   .carousel-control .glyphicon-chevron-left,
6421   .carousel-control .glyphicon-chevron-right,
6422   .carousel-control .icon-prev,
6423   .carousel-control .icon-next {
6424     width: 30px;
6425     height: 30px;
6426     margin-top: -10px;
6427     font-size: 30px;
6428   }
6429   .carousel-control .glyphicon-chevron-left,
6430   .carousel-control .icon-prev {
6431     margin-left: -10px;
6432   }
6433   .carousel-control .glyphicon-chevron-right,
6434   .carousel-control .icon-next {
6435     margin-right: -10px;
6436   }
6437   .carousel-caption {
6438     left: 20%;
6439     right: 20%;
6440     padding-bottom: 30px;
6441   }
6442   .carousel-indicators {
6443     bottom: 20px;
6444   }
6445 }
6446 .clearfix:before,
6447 .clearfix:after,
6448 .dl-horizontal dd:before,
6449 .dl-horizontal dd:after,
6450 .container:before,
6451 .container:after,
6452 .container-fluid:before,
6453 .container-fluid:after,
6454 .row:before,
6455 .row:after,
6456 .form-horizontal .form-group:before,
6457 .form-horizontal .form-group:after,
6458 .btn-toolbar:before,
6459 .btn-toolbar:after,
6460 .btn-group-vertical > .btn-group:before,
6461 .btn-group-vertical > .btn-group:after,
6462 .nav:before,
6463 .nav:after,
6464 .navbar:before,
6465 .navbar:after,
6466 .navbar-header:before,
6467 .navbar-header:after,
6468 .navbar-collapse:before,
6469 .navbar-collapse:after,
6470 .pager:before,
6471 .pager:after,
6472 .panel-body:before,
6473 .panel-body:after,
6474 .modal-header:before,
6475 .modal-header:after,
6476 .modal-footer:before,
6477 .modal-footer:after,
6478 .item_buttons:before,
6479 .item_buttons:after {
6480   content: " ";
6481   display: table;
6482 }
6483 .clearfix:after,
6484 .dl-horizontal dd:after,
6485 .container:after,
6486 .container-fluid:after,
6487 .row:after,
6488 .form-horizontal .form-group:after,
6489 .btn-toolbar:after,
6490 .btn-group-vertical > .btn-group:after,
6491 .nav:after,
6492 .navbar:after,
6493 .navbar-header:after,
6494 .navbar-collapse:after,
6495 .pager:after,
6496 .panel-body:after,
6497 .modal-header:after,
6498 .modal-footer:after,
6499 .item_buttons:after {
6500   clear: both;
6501 }
6502 .center-block {
6503   display: block;
6504   margin-left: auto;
6505   margin-right: auto;
6506 }
6507 .pull-right {
6508   float: right !important;
6509 }
6510 .pull-left {
6511   float: left !important;
6512 }
6513 .hide {
6514   display: none !important;
6515 }
6516 .show {
6517   display: block !important;
6518 }
6519 .invisible {
6520   visibility: hidden;
6521 }
6522 .text-hide {
6523   font: 0/0 a;
6524   color: transparent;
6525   text-shadow: none;
6526   background-color: transparent;
6527   border: 0;
6528 }
6529 .hidden {
6530   display: none !important;
6531 }
6532 .affix {
6533   position: fixed;
6534 }
6535 @-ms-viewport {
6536   width: device-width;
6537 }
6538 .visible-xs,
6539 .visible-sm,
6540 .visible-md,
6541 .visible-lg {
6542   display: none !important;
6543 }
6544 .visible-xs-block,
6545 .visible-xs-inline,
6546 .visible-xs-inline-block,
6547 .visible-sm-block,
6548 .visible-sm-inline,
6549 .visible-sm-inline-block,
6550 .visible-md-block,
6551 .visible-md-inline,
6552 .visible-md-inline-block,
6553 .visible-lg-block,
6554 .visible-lg-inline,
6555 .visible-lg-inline-block {
6556   display: none !important;
6557 }
6558 @media (max-width: 767px) {
6559   .visible-xs {
6560     display: block !important;
6561   }
6562   table.visible-xs {
6563     display: table !important;
6564   }
6565   tr.visible-xs {
6566     display: table-row !important;
6567   }
6568   th.visible-xs,
6569   td.visible-xs {
6570     display: table-cell !important;
6571   }
6572 }
6573 @media (max-width: 767px) {
6574   .visible-xs-block {
6575     display: block !important;
6576   }
6577 }
6578 @media (max-width: 767px) {
6579   .visible-xs-inline {
6580     display: inline !important;
6581   }
6582 }
6583 @media (max-width: 767px) {
6584   .visible-xs-inline-block {
6585     display: inline-block !important;
6586   }
6587 }
6588 @media (min-width: 768px) and (max-width: 991px) {
6589   .visible-sm {
6590     display: block !important;
6591   }
6592   table.visible-sm {
6593     display: table !important;
6594   }
6595   tr.visible-sm {
6596     display: table-row !important;
6597   }
6598   th.visible-sm,
6599   td.visible-sm {
6600     display: table-cell !important;
6601   }
6602 }
6603 @media (min-width: 768px) and (max-width: 991px) {
6604   .visible-sm-block {
6605     display: block !important;
6606   }
6607 }
6608 @media (min-width: 768px) and (max-width: 991px) {
6609   .visible-sm-inline {
6610     display: inline !important;
6611   }
6612 }
6613 @media (min-width: 768px) and (max-width: 991px) {
6614   .visible-sm-inline-block {
6615     display: inline-block !important;
6616   }
6617 }
6618 @media (min-width: 992px) and (max-width: 1199px) {
6619   .visible-md {
6620     display: block !important;
6621   }
6622   table.visible-md {
6623     display: table !important;
6624   }
6625   tr.visible-md {
6626     display: table-row !important;
6627   }
6628   th.visible-md,
6629   td.visible-md {
6630     display: table-cell !important;
6631   }
6632 }
6633 @media (min-width: 992px) and (max-width: 1199px) {
6634   .visible-md-block {
6635     display: block !important;
6636   }
6637 }
6638 @media (min-width: 992px) and (max-width: 1199px) {
6639   .visible-md-inline {
6640     display: inline !important;
6641   }
6642 }
6643 @media (min-width: 992px) and (max-width: 1199px) {
6644   .visible-md-inline-block {
6645     display: inline-block !important;
6646   }
6647 }
6648 @media (min-width: 1200px) {
6649   .visible-lg {
6650     display: block !important;
6651   }
6652   table.visible-lg {
6653     display: table !important;
6654   }
6655   tr.visible-lg {
6656     display: table-row !important;
6657   }
6658   th.visible-lg,
6659   td.visible-lg {
6660     display: table-cell !important;
6661   }
6662 }
6663 @media (min-width: 1200px) {
6664   .visible-lg-block {
6665     display: block !important;
6666   }
6667 }
6668 @media (min-width: 1200px) {
6669   .visible-lg-inline {
6670     display: inline !important;
6671   }
6672 }
6673 @media (min-width: 1200px) {
6674   .visible-lg-inline-block {
6675     display: inline-block !important;
6676   }
6677 }
6678 @media (max-width: 767px) {
6679   .hidden-xs {
6680     display: none !important;
6681   }
6682 }
6683 @media (min-width: 768px) and (max-width: 991px) {
6684   .hidden-sm {
6685     display: none !important;
6686   }
6687 }
6688 @media (min-width: 992px) and (max-width: 1199px) {
6689   .hidden-md {
6690     display: none !important;
6691   }
6692 }
6693 @media (min-width: 1200px) {
6694   .hidden-lg {
6695     display: none !important;
6696   }
6697 }
6698 .visible-print {
6699   display: none !important;
6700 }
6701 @media print {
6702   .visible-print {
6703     display: block !important;
6704   }
6705   table.visible-print {
6706     display: table !important;
6707   }
6708   tr.visible-print {
6709     display: table-row !important;
6710   }
6711   th.visible-print,
6712   td.visible-print {
6713     display: table-cell !important;
6714   }
6715 }
6716 .visible-print-block {
6717   display: none !important;
6718 }
6719 @media print {
6720   .visible-print-block {
6721     display: block !important;
6722   }
6723 }
6724 .visible-print-inline {
6725   display: none !important;
6726 }
6727 @media print {
6728   .visible-print-inline {
6729     display: inline !important;
6730   }
6731 }
6732 .visible-print-inline-block {
6733   display: none !important;
6734 }
6735 @media print {
6736   .visible-print-inline-block {
6737     display: inline-block !important;
6738   }
6739 }
6740 @media print {
6741   .hidden-print {
6742     display: none !important;
6743   }
6744 }
6745 /*!
6746 *
6747 * Font Awesome
6748 *
6749 */
6750 /*!
6751  *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
6752  *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
6753  */
6754 /* FONT PATH
6755  * -------------------------- */
6756 @font-face {
6757   font-family: 'FontAwesome';
6758   src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0');
6759   src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../components/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../components/font-awesome/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../components/font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
6760   font-weight: normal;
6761   font-style: normal;
6762 }
6763 .fa {
6764   display: inline-block;
6765   font: normal normal normal 14px/1 FontAwesome;
6766   font-size: inherit;
6767   text-rendering: auto;
6768   -webkit-font-smoothing: antialiased;
6769   -moz-osx-font-smoothing: grayscale;
6770 }
6771 /* makes the font 33% larger relative to the icon container */
6772 .fa-lg {
6773   font-size: 1.33333333em;
6774   line-height: 0.75em;
6775   vertical-align: -15%;
6776 }
6777 .fa-2x {
6778   font-size: 2em;
6779 }
6780 .fa-3x {
6781   font-size: 3em;
6782 }
6783 .fa-4x {
6784   font-size: 4em;
6785 }
6786 .fa-5x {
6787   font-size: 5em;
6788 }
6789 .fa-fw {
6790   width: 1.28571429em;
6791   text-align: center;
6792 }
6793 .fa-ul {
6794   padding-left: 0;
6795   margin-left: 2.14285714em;
6796   list-style-type: none;
6797 }
6798 .fa-ul > li {
6799   position: relative;
6800 }
6801 .fa-li {
6802   position: absolute;
6803   left: -2.14285714em;
6804   width: 2.14285714em;
6805   top: 0.14285714em;
6806   text-align: center;
6807 }
6808 .fa-li.fa-lg {
6809   left: -1.85714286em;
6810 }
6811 .fa-border {
6812   padding: .2em .25em .15em;
6813   border: solid 0.08em #eee;
6814   border-radius: .1em;
6815 }
6816 .fa-pull-left {
6817   float: left;
6818 }
6819 .fa-pull-right {
6820   float: right;
6821 }
6822 .fa.fa-pull-left {
6823   margin-right: .3em;
6824 }
6825 .fa.fa-pull-right {
6826   margin-left: .3em;
6827 }
6828 /* Deprecated as of 4.4.0 */
6829 .pull-right {
6830   float: right;
6831 }
6832 .pull-left {
6833   float: left;
6834 }
6835 .fa.pull-left {
6836   margin-right: .3em;
6837 }
6838 .fa.pull-right {
6839   margin-left: .3em;
6840 }
6841 .fa-spin {
6842   -webkit-animation: fa-spin 2s infinite linear;
6843   animation: fa-spin 2s infinite linear;
6844 }
6845 .fa-pulse {
6846   -webkit-animation: fa-spin 1s infinite steps(8);
6847   animation: fa-spin 1s infinite steps(8);
6848 }
6849 @-webkit-keyframes fa-spin {
6850   0% {
6851     -webkit-transform: rotate(0deg);
6852     transform: rotate(0deg);
6853   }
6854   100% {
6855     -webkit-transform: rotate(359deg);
6856     transform: rotate(359deg);
6857   }
6858 }
6859 @keyframes fa-spin {
6860   0% {
6861     -webkit-transform: rotate(0deg);
6862     transform: rotate(0deg);
6863   }
6864   100% {
6865     -webkit-transform: rotate(359deg);
6866     transform: rotate(359deg);
6867   }
6868 }
6869 .fa-rotate-90 {
6870   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
6871   -webkit-transform: rotate(90deg);
6872   -ms-transform: rotate(90deg);
6873   transform: rotate(90deg);
6874 }
6875 .fa-rotate-180 {
6876   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
6877   -webkit-transform: rotate(180deg);
6878   -ms-transform: rotate(180deg);
6879   transform: rotate(180deg);
6880 }
6881 .fa-rotate-270 {
6882   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
6883   -webkit-transform: rotate(270deg);
6884   -ms-transform: rotate(270deg);
6885   transform: rotate(270deg);
6886 }
6887 .fa-flip-horizontal {
6888   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
6889   -webkit-transform: scale(-1, 1);
6890   -ms-transform: scale(-1, 1);
6891   transform: scale(-1, 1);
6892 }
6893 .fa-flip-vertical {
6894   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
6895   -webkit-transform: scale(1, -1);
6896   -ms-transform: scale(1, -1);
6897   transform: scale(1, -1);
6898 }
6899 :root .fa-rotate-90,
6900 :root .fa-rotate-180,
6901 :root .fa-rotate-270,
6902 :root .fa-flip-horizontal,
6903 :root .fa-flip-vertical {
6904   filter: none;
6905 }
6906 .fa-stack {
6907   position: relative;
6908   display: inline-block;
6909   width: 2em;
6910   height: 2em;
6911   line-height: 2em;
6912   vertical-align: middle;
6913 }
6914 .fa-stack-1x,
6915 .fa-stack-2x {
6916   position: absolute;
6917   left: 0;
6918   width: 100%;
6919   text-align: center;
6920 }
6921 .fa-stack-1x {
6922   line-height: inherit;
6923 }
6924 .fa-stack-2x {
6925   font-size: 2em;
6926 }
6927 .fa-inverse {
6928   color: #fff;
6929 }
6930 /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
6931    readers do not read off random characters that represent icons */
6932 .fa-glass:before {
6933   content: "\f000";
6934 }
6935 .fa-music:before {
6936   content: "\f001";
6937 }
6938 .fa-search:before {
6939   content: "\f002";
6940 }
6941 .fa-envelope-o:before {
6942   content: "\f003";
6943 }
6944 .fa-heart:before {
6945   content: "\f004";
6946 }
6947 .fa-star:before {
6948   content: "\f005";
6949 }
6950 .fa-star-o:before {
6951   content: "\f006";
6952 }
6953 .fa-user:before {
6954   content: "\f007";
6955 }
6956 .fa-film:before {
6957   content: "\f008";
6958 }
6959 .fa-th-large:before {
6960   content: "\f009";
6961 }
6962 .fa-th:before {
6963   content: "\f00a";
6964 }
6965 .fa-th-list:before {
6966   content: "\f00b";
6967 }
6968 .fa-check:before {
6969   content: "\f00c";
6970 }
6971 .fa-remove:before,
6972 .fa-close:before,
6973 .fa-times:before {
6974   content: "\f00d";
6975 }
6976 .fa-search-plus:before {
6977   content: "\f00e";
6978 }
6979 .fa-search-minus:before {
6980   content: "\f010";
6981 }
6982 .fa-power-off:before {
6983   content: "\f011";
6984 }
6985 .fa-signal:before {
6986   content: "\f012";
6987 }
6988 .fa-gear:before,
6989 .fa-cog:before {
6990   content: "\f013";
6991 }
6992 .fa-trash-o:before {
6993   content: "\f014";
6994 }
6995 .fa-home:before {
6996   content: "\f015";
6997 }
6998 .fa-file-o:before {
6999   content: "\f016";
7000 }
7001 .fa-clock-o:before {
7002   content: "\f017";
7003 }
7004 .fa-road:before {
7005   content: "\f018";
7006 }
7007 .fa-download:before {
7008   content: "\f019";
7009 }
7010 .fa-arrow-circle-o-down:before {
7011   content: "\f01a";
7012 }
7013 .fa-arrow-circle-o-up:before {
7014   content: "\f01b";
7015 }
7016 .fa-inbox:before {
7017   content: "\f01c";
7018 }
7019 .fa-play-circle-o:before {
7020   content: "\f01d";
7021 }
7022 .fa-rotate-right:before,
7023 .fa-repeat:before {
7024   content: "\f01e";
7025 }
7026 .fa-refresh:before {
7027   content: "\f021";
7028 }
7029 .fa-list-alt:before {
7030   content: "\f022";
7031 }
7032 .fa-lock:before {
7033   content: "\f023";
7034 }
7035 .fa-flag:before {
7036   content: "\f024";
7037 }
7038 .fa-headphones:before {
7039   content: "\f025";
7040 }
7041 .fa-volume-off:before {
7042   content: "\f026";
7043 }
7044 .fa-volume-down:before {
7045   content: "\f027";
7046 }
7047 .fa-volume-up:before {
7048   content: "\f028";
7049 }
7050 .fa-qrcode:before {
7051   content: "\f029";
7052 }
7053 .fa-barcode:before {
7054   content: "\f02a";
7055 }
7056 .fa-tag:before {
7057   content: "\f02b";
7058 }
7059 .fa-tags:before {
7060   content: "\f02c";
7061 }
7062 .fa-book:before {
7063   content: "\f02d";
7064 }
7065 .fa-bookmark:before {
7066   content: "\f02e";
7067 }
7068 .fa-print:before {
7069   content: "\f02f";
7070 }
7071 .fa-camera:before {
7072   content: "\f030";
7073 }
7074 .fa-font:before {
7075   content: "\f031";
7076 }
7077 .fa-bold:before {
7078   content: "\f032";
7079 }
7080 .fa-italic:before {
7081   content: "\f033";
7082 }
7083 .fa-text-height:before {
7084   content: "\f034";
7085 }
7086 .fa-text-width:before {
7087   content: "\f035";
7088 }
7089 .fa-align-left:before {
7090   content: "\f036";
7091 }
7092 .fa-align-center:before {
7093   content: "\f037";
7094 }
7095 .fa-align-right:before {
7096   content: "\f038";
7097 }
7098 .fa-align-justify:before {
7099   content: "\f039";
7100 }
7101 .fa-list:before {
7102   content: "\f03a";
7103 }
7104 .fa-dedent:before,
7105 .fa-outdent:before {
7106   content: "\f03b";
7107 }
7108 .fa-indent:before {
7109   content: "\f03c";
7110 }
7111 .fa-video-camera:before {
7112   content: "\f03d";
7113 }
7114 .fa-photo:before,
7115 .fa-image:before,
7116 .fa-picture-o:before {
7117   content: "\f03e";
7118 }
7119 .fa-pencil:before {
7120   content: "\f040";
7121 }
7122 .fa-map-marker:before {
7123   content: "\f041";
7124 }
7125 .fa-adjust:before {
7126   content: "\f042";
7127 }
7128 .fa-tint:before {
7129   content: "\f043";
7130 }
7131 .fa-edit:before,
7132 .fa-pencil-square-o:before {
7133   content: "\f044";
7134 }
7135 .fa-share-square-o:before {
7136   content: "\f045";
7137 }
7138 .fa-check-square-o:before {
7139   content: "\f046";
7140 }
7141 .fa-arrows:before {
7142   content: "\f047";
7143 }
7144 .fa-step-backward:before {
7145   content: "\f048";
7146 }
7147 .fa-fast-backward:before {
7148   content: "\f049";
7149 }
7150 .fa-backward:before {
7151   content: "\f04a";
7152 }
7153 .fa-play:before {
7154   content: "\f04b";
7155 }
7156 .fa-pause:before {
7157   content: "\f04c";
7158 }
7159 .fa-stop:before {
7160   content: "\f04d";
7161 }
7162 .fa-forward:before {
7163   content: "\f04e";
7164 }
7165 .fa-fast-forward:before {
7166   content: "\f050";
7167 }
7168 .fa-step-forward:before {
7169   content: "\f051";
7170 }
7171 .fa-eject:before {
7172   content: "\f052";
7173 }
7174 .fa-chevron-left:before {
7175   content: "\f053";
7176 }
7177 .fa-chevron-right:before {
7178   content: "\f054";
7179 }
7180 .fa-plus-circle:before {
7181   content: "\f055";
7182 }
7183 .fa-minus-circle:before {
7184   content: "\f056";
7185 }
7186 .fa-times-circle:before {
7187   content: "\f057";
7188 }
7189 .fa-check-circle:before {
7190   content: "\f058";
7191 }
7192 .fa-question-circle:before {
7193   content: "\f059";
7194 }
7195 .fa-info-circle:before {
7196   content: "\f05a";
7197 }
7198 .fa-crosshairs:before {
7199   content: "\f05b";
7200 }
7201 .fa-times-circle-o:before {
7202   content: "\f05c";
7203 }
7204 .fa-check-circle-o:before {
7205   content: "\f05d";
7206 }
7207 .fa-ban:before {
7208   content: "\f05e";
7209 }
7210 .fa-arrow-left:before {
7211   content: "\f060";
7212 }
7213 .fa-arrow-right:before {
7214   content: "\f061";
7215 }
7216 .fa-arrow-up:before {
7217   content: "\f062";
7218 }
7219 .fa-arrow-down:before {
7220   content: "\f063";
7221 }
7222 .fa-mail-forward:before,
7223 .fa-share:before {
7224   content: "\f064";
7225 }
7226 .fa-expand:before {
7227   content: "\f065";
7228 }
7229 .fa-compress:before {
7230   content: "\f066";
7231 }
7232 .fa-plus:before {
7233   content: "\f067";
7234 }
7235 .fa-minus:before {
7236   content: "\f068";
7237 }
7238 .fa-asterisk:before {
7239   content: "\f069";
7240 }
7241 .fa-exclamation-circle:before {
7242   content: "\f06a";
7243 }
7244 .fa-gift:before {
7245   content: "\f06b";
7246 }
7247 .fa-leaf:before {
7248   content: "\f06c";
7249 }
7250 .fa-fire:before {
7251   content: "\f06d";
7252 }
7253 .fa-eye:before {
7254   content: "\f06e";
7255 }
7256 .fa-eye-slash:before {
7257   content: "\f070";
7258 }
7259 .fa-warning:before,
7260 .fa-exclamation-triangle:before {
7261   content: "\f071";
7262 }
7263 .fa-plane:before {
7264   content: "\f072";
7265 }
7266 .fa-calendar:before {
7267   content: "\f073";
7268 }
7269 .fa-random:before {
7270   content: "\f074";
7271 }
7272 .fa-comment:before {
7273   content: "\f075";
7274 }
7275 .fa-magnet:before {
7276   content: "\f076";
7277 }
7278 .fa-chevron-up:before {
7279   content: "\f077";
7280 }
7281 .fa-chevron-down:before {
7282   content: "\f078";
7283 }
7284 .fa-retweet:before {
7285   content: "\f079";
7286 }
7287 .fa-shopping-cart:before {
7288   content: "\f07a";
7289 }
7290 .fa-folder:before {
7291   content: "\f07b";
7292 }
7293 .fa-folder-open:before {
7294   content: "\f07c";
7295 }
7296 .fa-arrows-v:before {
7297   content: "\f07d";
7298 }
7299 .fa-arrows-h:before {
7300   content: "\f07e";
7301 }
7302 .fa-bar-chart-o:before,
7303 .fa-bar-chart:before {
7304   content: "\f080";
7305 }
7306 .fa-twitter-square:before {
7307   content: "\f081";
7308 }
7309 .fa-facebook-square:before {
7310   content: "\f082";
7311 }
7312 .fa-camera-retro:before {
7313   content: "\f083";
7314 }
7315 .fa-key:before {
7316   content: "\f084";
7317 }
7318 .fa-gears:before,
7319 .fa-cogs:before {
7320   content: "\f085";
7321 }
7322 .fa-comments:before {
7323   content: "\f086";
7324 }
7325 .fa-thumbs-o-up:before {
7326   content: "\f087";
7327 }
7328 .fa-thumbs-o-down:before {
7329   content: "\f088";
7330 }
7331 .fa-star-half:before {
7332   content: "\f089";
7333 }
7334 .fa-heart-o:before {
7335   content: "\f08a";
7336 }
7337 .fa-sign-out:before {
7338   content: "\f08b";
7339 }
7340 .fa-linkedin-square:before {
7341   content: "\f08c";
7342 }
7343 .fa-thumb-tack:before {
7344   content: "\f08d";
7345 }
7346 .fa-external-link:before {
7347   content: "\f08e";
7348 }
7349 .fa-sign-in:before {
7350   content: "\f090";
7351 }
7352 .fa-trophy:before {
7353   content: "\f091";
7354 }
7355 .fa-github-square:before {
7356   content: "\f092";
7357 }
7358 .fa-upload:before {
7359   content: "\f093";
7360 }
7361 .fa-lemon-o:before {
7362   content: "\f094";
7363 }
7364 .fa-phone:before {
7365   content: "\f095";
7366 }
7367 .fa-square-o:before {
7368   content: "\f096";
7369 }
7370 .fa-bookmark-o:before {
7371   content: "\f097";
7372 }
7373 .fa-phone-square:before {
7374   content: "\f098";
7375 }
7376 .fa-twitter:before {
7377   content: "\f099";
7378 }
7379 .fa-facebook-f:before,
7380 .fa-facebook:before {
7381   content: "\f09a";
7382 }
7383 .fa-github:before {
7384   content: "\f09b";
7385 }
7386 .fa-unlock:before {
7387   content: "\f09c";
7388 }
7389 .fa-credit-card:before {
7390   content: "\f09d";
7391 }
7392 .fa-feed:before,
7393 .fa-rss:before {
7394   content: "\f09e";
7395 }
7396 .fa-hdd-o:before {
7397   content: "\f0a0";
7398 }
7399 .fa-bullhorn:before {
7400   content: "\f0a1";
7401 }
7402 .fa-bell:before {
7403   content: "\f0f3";
7404 }
7405 .fa-certificate:before {
7406   content: "\f0a3";
7407 }
7408 .fa-hand-o-right:before {
7409   content: "\f0a4";
7410 }
7411 .fa-hand-o-left:before {
7412   content: "\f0a5";
7413 }
7414 .fa-hand-o-up:before {
7415   content: "\f0a6";
7416 }
7417 .fa-hand-o-down:before {
7418   content: "\f0a7";
7419 }
7420 .fa-arrow-circle-left:before {
7421   content: "\f0a8";
7422 }
7423 .fa-arrow-circle-right:before {
7424   content: "\f0a9";
7425 }
7426 .fa-arrow-circle-up:before {
7427   content: "\f0aa";
7428 }
7429 .fa-arrow-circle-down:before {
7430   content: "\f0ab";
7431 }
7432 .fa-globe:before {
7433   content: "\f0ac";
7434 }
7435 .fa-wrench:before {
7436   content: "\f0ad";
7437 }
7438 .fa-tasks:before {
7439   content: "\f0ae";
7440 }
7441 .fa-filter:before {
7442   content: "\f0b0";
7443 }
7444 .fa-briefcase:before {
7445   content: "\f0b1";
7446 }
7447 .fa-arrows-alt:before {
7448   content: "\f0b2";
7449 }
7450 .fa-group:before,
7451 .fa-users:before {
7452   content: "\f0c0";
7453 }
7454 .fa-chain:before,
7455 .fa-link:before {
7456   content: "\f0c1";
7457 }
7458 .fa-cloud:before {
7459   content: "\f0c2";
7460 }
7461 .fa-flask:before {
7462   content: "\f0c3";
7463 }
7464 .fa-cut:before,
7465 .fa-scissors:before {
7466   content: "\f0c4";
7467 }
7468 .fa-copy:before,
7469 .fa-files-o:before {
7470   content: "\f0c5";
7471 }
7472 .fa-paperclip:before {
7473   content: "\f0c6";
7474 }
7475 .fa-save:before,
7476 .fa-floppy-o:before {
7477   content: "\f0c7";
7478 }
7479 .fa-square:before {
7480   content: "\f0c8";
7481 }
7482 .fa-navicon:before,
7483 .fa-reorder:before,
7484 .fa-bars:before {
7485   content: "\f0c9";
7486 }
7487 .fa-list-ul:before {
7488   content: "\f0ca";
7489 }
7490 .fa-list-ol:before {
7491   content: "\f0cb";
7492 }
7493 .fa-strikethrough:before {
7494   content: "\f0cc";
7495 }
7496 .fa-underline:before {
7497   content: "\f0cd";
7498 }
7499 .fa-table:before {
7500   content: "\f0ce";
7501 }
7502 .fa-magic:before {
7503   content: "\f0d0";
7504 }
7505 .fa-truck:before {
7506   content: "\f0d1";
7507 }
7508 .fa-pinterest:before {
7509   content: "\f0d2";
7510 }
7511 .fa-pinterest-square:before {
7512   content: "\f0d3";
7513 }
7514 .fa-google-plus-square:before {
7515   content: "\f0d4";
7516 }
7517 .fa-google-plus:before {
7518   content: "\f0d5";
7519 }
7520 .fa-money:before {
7521   content: "\f0d6";
7522 }
7523 .fa-caret-down:before {
7524   content: "\f0d7";
7525 }
7526 .fa-caret-up:before {
7527   content: "\f0d8";
7528 }
7529 .fa-caret-left:before {
7530   content: "\f0d9";
7531 }
7532 .fa-caret-right:before {
7533   content: "\f0da";
7534 }
7535 .fa-columns:before {
7536   content: "\f0db";
7537 }
7538 .fa-unsorted:before,
7539 .fa-sort:before {
7540   content: "\f0dc";
7541 }
7542 .fa-sort-down:before,
7543 .fa-sort-desc:before {
7544   content: "\f0dd";
7545 }
7546 .fa-sort-up:before,
7547 .fa-sort-asc:before {
7548   content: "\f0de";
7549 }
7550 .fa-envelope:before {
7551   content: "\f0e0";
7552 }
7553 .fa-linkedin:before {
7554   content: "\f0e1";
7555 }
7556 .fa-rotate-left:before,
7557 .fa-undo:before {
7558   content: "\f0e2";
7559 }
7560 .fa-legal:before,
7561 .fa-gavel:before {
7562   content: "\f0e3";
7563 }
7564 .fa-dashboard:before,
7565 .fa-tachometer:before {
7566   content: "\f0e4";
7567 }
7568 .fa-comment-o:before {
7569   content: "\f0e5";
7570 }
7571 .fa-comments-o:before {
7572   content: "\f0e6";
7573 }
7574 .fa-flash:before,
7575 .fa-bolt:before {
7576   content: "\f0e7";
7577 }
7578 .fa-sitemap:before {
7579   content: "\f0e8";
7580 }
7581 .fa-umbrella:before {
7582   content: "\f0e9";
7583 }
7584 .fa-paste:before,
7585 .fa-clipboard:before {
7586   content: "\f0ea";
7587 }
7588 .fa-lightbulb-o:before {
7589   content: "\f0eb";
7590 }
7591 .fa-exchange:before {
7592   content: "\f0ec";
7593 }
7594 .fa-cloud-download:before {
7595   content: "\f0ed";
7596 }
7597 .fa-cloud-upload:before {
7598   content: "\f0ee";
7599 }
7600 .fa-user-md:before {
7601   content: "\f0f0";
7602 }
7603 .fa-stethoscope:before {
7604   content: "\f0f1";
7605 }
7606 .fa-suitcase:before {
7607   content: "\f0f2";
7608 }
7609 .fa-bell-o:before {
7610   content: "\f0a2";
7611 }
7612 .fa-coffee:before {
7613   content: "\f0f4";
7614 }
7615 .fa-cutlery:before {
7616   content: "\f0f5";
7617 }
7618 .fa-file-text-o:before {
7619   content: "\f0f6";
7620 }
7621 .fa-building-o:before {
7622   content: "\f0f7";
7623 }
7624 .fa-hospital-o:before {
7625   content: "\f0f8";
7626 }
7627 .fa-ambulance:before {
7628   content: "\f0f9";
7629 }
7630 .fa-medkit:before {
7631   content: "\f0fa";
7632 }
7633 .fa-fighter-jet:before {
7634   content: "\f0fb";
7635 }
7636 .fa-beer:before {
7637   content: "\f0fc";
7638 }
7639 .fa-h-square:before {
7640   content: "\f0fd";
7641 }
7642 .fa-plus-square:before {
7643   content: "\f0fe";
7644 }
7645 .fa-angle-double-left:before {
7646   content: "\f100";
7647 }
7648 .fa-angle-double-right:before {
7649   content: "\f101";
7650 }
7651 .fa-angle-double-up:before {
7652   content: "\f102";
7653 }
7654 .fa-angle-double-down:before {
7655   content: "\f103";
7656 }
7657 .fa-angle-left:before {
7658   content: "\f104";
7659 }
7660 .fa-angle-right:before {
7661   content: "\f105";
7662 }
7663 .fa-angle-up:before {
7664   content: "\f106";
7665 }
7666 .fa-angle-down:before {
7667   content: "\f107";
7668 }
7669 .fa-desktop:before {
7670   content: "\f108";
7671 }
7672 .fa-laptop:before {
7673   content: "\f109";
7674 }
7675 .fa-tablet:before {
7676   content: "\f10a";
7677 }
7678 .fa-mobile-phone:before,
7679 .fa-mobile:before {
7680   content: "\f10b";
7681 }
7682 .fa-circle-o:before {
7683   content: "\f10c";
7684 }
7685 .fa-quote-left:before {
7686   content: "\f10d";
7687 }
7688 .fa-quote-right:before {
7689   content: "\f10e";
7690 }
7691 .fa-spinner:before {
7692   content: "\f110";
7693 }
7694 .fa-circle:before {
7695   content: "\f111";
7696 }
7697 .fa-mail-reply:before,
7698 .fa-reply:before {
7699   content: "\f112";
7700 }
7701 .fa-github-alt:before {
7702   content: "\f113";
7703 }
7704 .fa-folder-o:before {
7705   content: "\f114";
7706 }
7707 .fa-folder-open-o:before {
7708   content: "\f115";
7709 }
7710 .fa-smile-o:before {
7711   content: "\f118";
7712 }
7713 .fa-frown-o:before {
7714   content: "\f119";
7715 }
7716 .fa-meh-o:before {
7717   content: "\f11a";
7718 }
7719 .fa-gamepad:before {
7720   content: "\f11b";
7721 }
7722 .fa-keyboard-o:before {
7723   content: "\f11c";
7724 }
7725 .fa-flag-o:before {
7726   content: "\f11d";
7727 }
7728 .fa-flag-checkered:before {
7729   content: "\f11e";
7730 }
7731 .fa-terminal:before {
7732   content: "\f120";
7733 }
7734 .fa-code:before {
7735   content: "\f121";
7736 }
7737 .fa-mail-reply-all:before,
7738 .fa-reply-all:before {
7739   content: "\f122";
7740 }
7741 .fa-star-half-empty:before,
7742 .fa-star-half-full:before,
7743 .fa-star-half-o:before {
7744   content: "\f123";
7745 }
7746 .fa-location-arrow:before {
7747   content: "\f124";
7748 }
7749 .fa-crop:before {
7750   content: "\f125";
7751 }
7752 .fa-code-fork:before {
7753   content: "\f126";
7754 }
7755 .fa-unlink:before,
7756 .fa-chain-broken:before {
7757   content: "\f127";
7758 }
7759 .fa-question:before {
7760   content: "\f128";
7761 }
7762 .fa-info:before {
7763   content: "\f129";
7764 }
7765 .fa-exclamation:before {
7766   content: "\f12a";
7767 }
7768 .fa-superscript:before {
7769   content: "\f12b";
7770 }
7771 .fa-subscript:before {
7772   content: "\f12c";
7773 }
7774 .fa-eraser:before {
7775   content: "\f12d";
7776 }
7777 .fa-puzzle-piece:before {
7778   content: "\f12e";
7779 }
7780 .fa-microphone:before {
7781   content: "\f130";
7782 }
7783 .fa-microphone-slash:before {
7784   content: "\f131";
7785 }
7786 .fa-shield:before {
7787   content: "\f132";
7788 }
7789 .fa-calendar-o:before {
7790   content: "\f133";
7791 }
7792 .fa-fire-extinguisher:before {
7793   content: "\f134";
7794 }
7795 .fa-rocket:before {
7796   content: "\f135";
7797 }
7798 .fa-maxcdn:before {
7799   content: "\f136";
7800 }
7801 .fa-chevron-circle-left:before {
7802   content: "\f137";
7803 }
7804 .fa-chevron-circle-right:before {
7805   content: "\f138";
7806 }
7807 .fa-chevron-circle-up:before {
7808   content: "\f139";
7809 }
7810 .fa-chevron-circle-down:before {
7811   content: "\f13a";
7812 }
7813 .fa-html5:before {
7814   content: "\f13b";
7815 }
7816 .fa-css3:before {
7817   content: "\f13c";
7818 }
7819 .fa-anchor:before {
7820   content: "\f13d";
7821 }
7822 .fa-unlock-alt:before {
7823   content: "\f13e";
7824 }
7825 .fa-bullseye:before {
7826   content: "\f140";
7827 }
7828 .fa-ellipsis-h:before {
7829   content: "\f141";
7830 }
7831 .fa-ellipsis-v:before {
7832   content: "\f142";
7833 }
7834 .fa-rss-square:before {
7835   content: "\f143";
7836 }
7837 .fa-play-circle:before {
7838   content: "\f144";
7839 }
7840 .fa-ticket:before {
7841   content: "\f145";
7842 }
7843 .fa-minus-square:before {
7844   content: "\f146";
7845 }
7846 .fa-minus-square-o:before {
7847   content: "\f147";
7848 }
7849 .fa-level-up:before {
7850   content: "\f148";
7851 }
7852 .fa-level-down:before {
7853   content: "\f149";
7854 }
7855 .fa-check-square:before {
7856   content: "\f14a";
7857 }
7858 .fa-pencil-square:before {
7859   content: "\f14b";
7860 }
7861 .fa-external-link-square:before {
7862   content: "\f14c";
7863 }
7864 .fa-share-square:before {
7865   content: "\f14d";
7866 }
7867 .fa-compass:before {
7868   content: "\f14e";
7869 }
7870 .fa-toggle-down:before,
7871 .fa-caret-square-o-down:before {
7872   content: "\f150";
7873 }
7874 .fa-toggle-up:before,
7875 .fa-caret-square-o-up:before {
7876   content: "\f151";
7877 }
7878 .fa-toggle-right:before,
7879 .fa-caret-square-o-right:before {
7880   content: "\f152";
7881 }
7882 .fa-euro:before,
7883 .fa-eur:before {
7884   content: "\f153";
7885 }
7886 .fa-gbp:before {
7887   content: "\f154";
7888 }
7889 .fa-dollar:before,
7890 .fa-usd:before {
7891   content: "\f155";
7892 }
7893 .fa-rupee:before,
7894 .fa-inr:before {
7895   content: "\f156";
7896 }
7897 .fa-cny:before,
7898 .fa-rmb:before,
7899 .fa-yen:before,
7900 .fa-jpy:before {
7901   content: "\f157";
7902 }
7903 .fa-ruble:before,
7904 .fa-rouble:before,
7905 .fa-rub:before {
7906   content: "\f158";
7907 }
7908 .fa-won:before,
7909 .fa-krw:before {
7910   content: "\f159";
7911 }
7912 .fa-bitcoin:before,
7913 .fa-btc:before {
7914   content: "\f15a";
7915 }
7916 .fa-file:before {
7917   content: "\f15b";
7918 }
7919 .fa-file-text:before {
7920   content: "\f15c";
7921 }
7922 .fa-sort-alpha-asc:before {
7923   content: "\f15d";
7924 }
7925 .fa-sort-alpha-desc:before {
7926   content: "\f15e";
7927 }
7928 .fa-sort-amount-asc:before {
7929   content: "\f160";
7930 }
7931 .fa-sort-amount-desc:before {
7932   content: "\f161";
7933 }
7934 .fa-sort-numeric-asc:before {
7935   content: "\f162";
7936 }
7937 .fa-sort-numeric-desc:before {
7938   content: "\f163";
7939 }
7940 .fa-thumbs-up:before {
7941   content: "\f164";
7942 }
7943 .fa-thumbs-down:before {
7944   content: "\f165";
7945 }
7946 .fa-youtube-square:before {
7947   content: "\f166";
7948 }
7949 .fa-youtube:before {
7950   content: "\f167";
7951 }
7952 .fa-xing:before {
7953   content: "\f168";
7954 }
7955 .fa-xing-square:before {
7956   content: "\f169";
7957 }
7958 .fa-youtube-play:before {
7959   content: "\f16a";
7960 }
7961 .fa-dropbox:before {
7962   content: "\f16b";
7963 }
7964 .fa-stack-overflow:before {
7965   content: "\f16c";
7966 }
7967 .fa-instagram:before {
7968   content: "\f16d";
7969 }
7970 .fa-flickr:before {
7971   content: "\f16e";
7972 }
7973 .fa-adn:before {
7974   content: "\f170";
7975 }
7976 .fa-bitbucket:before {
7977   content: "\f171";
7978 }
7979 .fa-bitbucket-square:before {
7980   content: "\f172";
7981 }
7982 .fa-tumblr:before {
7983   content: "\f173";
7984 }
7985 .fa-tumblr-square:before {
7986   content: "\f174";
7987 }
7988 .fa-long-arrow-down:before {
7989   content: "\f175";
7990 }
7991 .fa-long-arrow-up:before {
7992   content: "\f176";
7993 }
7994 .fa-long-arrow-left:before {
7995   content: "\f177";
7996 }
7997 .fa-long-arrow-right:before {
7998   content: "\f178";
7999 }
8000 .fa-apple:before {
8001   content: "\f179";
8002 }
8003 .fa-windows:before {
8004   content: "\f17a";
8005 }
8006 .fa-android:before {
8007   content: "\f17b";
8008 }
8009 .fa-linux:before {
8010   content: "\f17c";
8011 }
8012 .fa-dribbble:before {
8013   content: "\f17d";
8014 }
8015 .fa-skype:before {
8016   content: "\f17e";
8017 }
8018 .fa-foursquare:before {
8019   content: "\f180";
8020 }
8021 .fa-trello:before {
8022   content: "\f181";
8023 }
8024 .fa-female:before {
8025   content: "\f182";
8026 }
8027 .fa-male:before {
8028   content: "\f183";
8029 }
8030 .fa-gittip:before,
8031 .fa-gratipay:before {
8032   content: "\f184";
8033 }
8034 .fa-sun-o:before {
8035   content: "\f185";
8036 }
8037 .fa-moon-o:before {
8038   content: "\f186";
8039 }
8040 .fa-archive:before {
8041   content: "\f187";
8042 }
8043 .fa-bug:before {
8044   content: "\f188";
8045 }
8046 .fa-vk:before {
8047   content: "\f189";
8048 }
8049 .fa-weibo:before {
8050   content: "\f18a";
8051 }
8052 .fa-renren:before {
8053   content: "\f18b";
8054 }
8055 .fa-pagelines:before {
8056   content: "\f18c";
8057 }
8058 .fa-stack-exchange:before {
8059   content: "\f18d";
8060 }
8061 .fa-arrow-circle-o-right:before {
8062   content: "\f18e";
8063 }
8064 .fa-arrow-circle-o-left:before {
8065   content: "\f190";
8066 }
8067 .fa-toggle-left:before,
8068 .fa-caret-square-o-left:before {
8069   content: "\f191";
8070 }
8071 .fa-dot-circle-o:before {
8072   content: "\f192";
8073 }
8074 .fa-wheelchair:before {
8075   content: "\f193";
8076 }
8077 .fa-vimeo-square:before {
8078   content: "\f194";
8079 }
8080 .fa-turkish-lira:before,
8081 .fa-try:before {
8082   content: "\f195";
8083 }
8084 .fa-plus-square-o:before {
8085   content: "\f196";
8086 }
8087 .fa-space-shuttle:before {
8088   content: "\f197";
8089 }
8090 .fa-slack:before {
8091   content: "\f198";
8092 }
8093 .fa-envelope-square:before {
8094   content: "\f199";
8095 }
8096 .fa-wordpress:before {
8097   content: "\f19a";
8098 }
8099 .fa-openid:before {
8100   content: "\f19b";
8101 }
8102 .fa-institution:before,
8103 .fa-bank:before,
8104 .fa-university:before {
8105   content: "\f19c";
8106 }
8107 .fa-mortar-board:before,
8108 .fa-graduation-cap:before {
8109   content: "\f19d";
8110 }
8111 .fa-yahoo:before {
8112   content: "\f19e";
8113 }
8114 .fa-google:before {
8115   content: "\f1a0";
8116 }
8117 .fa-reddit:before {
8118   content: "\f1a1";
8119 }
8120 .fa-reddit-square:before {
8121   content: "\f1a2";
8122 }
8123 .fa-stumbleupon-circle:before {
8124   content: "\f1a3";
8125 }
8126 .fa-stumbleupon:before {
8127   content: "\f1a4";
8128 }
8129 .fa-delicious:before {
8130   content: "\f1a5";
8131 }
8132 .fa-digg:before {
8133   content: "\f1a6";
8134 }
8135 .fa-pied-piper-pp:before {
8136   content: "\f1a7";
8137 }
8138 .fa-pied-piper-alt:before {
8139   content: "\f1a8";
8140 }
8141 .fa-drupal:before {
8142   content: "\f1a9";
8143 }
8144 .fa-joomla:before {
8145   content: "\f1aa";
8146 }
8147 .fa-language:before {
8148   content: "\f1ab";
8149 }
8150 .fa-fax:before {
8151   content: "\f1ac";
8152 }
8153 .fa-building:before {
8154   content: "\f1ad";
8155 }
8156 .fa-child:before {
8157   content: "\f1ae";
8158 }
8159 .fa-paw:before {
8160   content: "\f1b0";
8161 }
8162 .fa-spoon:before {
8163   content: "\f1b1";
8164 }
8165 .fa-cube:before {
8166   content: "\f1b2";
8167 }
8168 .fa-cubes:before {
8169   content: "\f1b3";
8170 }
8171 .fa-behance:before {
8172   content: "\f1b4";
8173 }
8174 .fa-behance-square:before {
8175   content: "\f1b5";
8176 }
8177 .fa-steam:before {
8178   content: "\f1b6";
8179 }
8180 .fa-steam-square:before {
8181   content: "\f1b7";
8182 }
8183 .fa-recycle:before {
8184   content: "\f1b8";
8185 }
8186 .fa-automobile:before,
8187 .fa-car:before {
8188   content: "\f1b9";
8189 }
8190 .fa-cab:before,
8191 .fa-taxi:before {
8192   content: "\f1ba";
8193 }
8194 .fa-tree:before {
8195   content: "\f1bb";
8196 }
8197 .fa-spotify:before {
8198   content: "\f1bc";
8199 }
8200 .fa-deviantart:before {
8201   content: "\f1bd";
8202 }
8203 .fa-soundcloud:before {
8204   content: "\f1be";
8205 }
8206 .fa-database:before {
8207   content: "\f1c0";
8208 }
8209 .fa-file-pdf-o:before {
8210   content: "\f1c1";
8211 }
8212 .fa-file-word-o:before {
8213   content: "\f1c2";
8214 }
8215 .fa-file-excel-o:before {
8216   content: "\f1c3";
8217 }
8218 .fa-file-powerpoint-o:before {
8219   content: "\f1c4";
8220 }
8221 .fa-file-photo-o:before,
8222 .fa-file-picture-o:before,
8223 .fa-file-image-o:before {
8224   content: "\f1c5";
8225 }
8226 .fa-file-zip-o:before,
8227 .fa-file-archive-o:before {
8228   content: "\f1c6";
8229 }
8230 .fa-file-sound-o:before,
8231 .fa-file-audio-o:before {
8232   content: "\f1c7";
8233 }
8234 .fa-file-movie-o:before,
8235 .fa-file-video-o:before {
8236   content: "\f1c8";
8237 }
8238 .fa-file-code-o:before {
8239   content: "\f1c9";
8240 }
8241 .fa-vine:before {
8242   content: "\f1ca";
8243 }
8244 .fa-codepen:before {
8245   content: "\f1cb";
8246 }
8247 .fa-jsfiddle:before {
8248   content: "\f1cc";
8249 }
8250 .fa-life-bouy:before,
8251 .fa-life-buoy:before,
8252 .fa-life-saver:before,
8253 .fa-support:before,
8254 .fa-life-ring:before {
8255   content: "\f1cd";
8256 }
8257 .fa-circle-o-notch:before {
8258   content: "\f1ce";
8259 }
8260 .fa-ra:before,
8261 .fa-resistance:before,
8262 .fa-rebel:before {
8263   content: "\f1d0";
8264 }
8265 .fa-ge:before,
8266 .fa-empire:before {
8267   content: "\f1d1";
8268 }
8269 .fa-git-square:before {
8270   content: "\f1d2";
8271 }
8272 .fa-git:before {
8273   content: "\f1d3";
8274 }
8275 .fa-y-combinator-square:before,
8276 .fa-yc-square:before,
8277 .fa-hacker-news:before {
8278   content: "\f1d4";
8279 }
8280 .fa-tencent-weibo:before {
8281   content: "\f1d5";
8282 }
8283 .fa-qq:before {
8284   content: "\f1d6";
8285 }
8286 .fa-wechat:before,
8287 .fa-weixin:before {
8288   content: "\f1d7";
8289 }
8290 .fa-send:before,
8291 .fa-paper-plane:before {
8292   content: "\f1d8";
8293 }
8294 .fa-send-o:before,
8295 .fa-paper-plane-o:before {
8296   content: "\f1d9";
8297 }
8298 .fa-history:before {
8299   content: "\f1da";
8300 }
8301 .fa-circle-thin:before {
8302   content: "\f1db";
8303 }
8304 .fa-header:before {
8305   content: "\f1dc";
8306 }
8307 .fa-paragraph:before {
8308   content: "\f1dd";
8309 }
8310 .fa-sliders:before {
8311   content: "\f1de";
8312 }
8313 .fa-share-alt:before {
8314   content: "\f1e0";
8315 }
8316 .fa-share-alt-square:before {
8317   content: "\f1e1";
8318 }
8319 .fa-bomb:before {
8320   content: "\f1e2";
8321 }
8322 .fa-soccer-ball-o:before,
8323 .fa-futbol-o:before {
8324   content: "\f1e3";
8325 }
8326 .fa-tty:before {
8327   content: "\f1e4";
8328 }
8329 .fa-binoculars:before {
8330   content: "\f1e5";
8331 }
8332 .fa-plug:before {
8333   content: "\f1e6";
8334 }
8335 .fa-slideshare:before {
8336   content: "\f1e7";
8337 }
8338 .fa-twitch:before {
8339   content: "\f1e8";
8340 }
8341 .fa-yelp:before {
8342   content: "\f1e9";
8343 }
8344 .fa-newspaper-o:before {
8345   content: "\f1ea";
8346 }
8347 .fa-wifi:before {
8348   content: "\f1eb";
8349 }
8350 .fa-calculator:before {
8351   content: "\f1ec";
8352 }
8353 .fa-paypal:before {
8354   content: "\f1ed";
8355 }
8356 .fa-google-wallet:before {
8357   content: "\f1ee";
8358 }
8359 .fa-cc-visa:before {
8360   content: "\f1f0";
8361 }
8362 .fa-cc-mastercard:before {
8363   content: "\f1f1";
8364 }
8365 .fa-cc-discover:before {
8366   content: "\f1f2";
8367 }
8368 .fa-cc-amex:before {
8369   content: "\f1f3";
8370 }
8371 .fa-cc-paypal:before {
8372   content: "\f1f4";
8373 }
8374 .fa-cc-stripe:before {
8375   content: "\f1f5";
8376 }
8377 .fa-bell-slash:before {
8378   content: "\f1f6";
8379 }
8380 .fa-bell-slash-o:before {
8381   content: "\f1f7";
8382 }
8383 .fa-trash:before {
8384   content: "\f1f8";
8385 }
8386 .fa-copyright:before {
8387   content: "\f1f9";
8388 }
8389 .fa-at:before {
8390   content: "\f1fa";
8391 }
8392 .fa-eyedropper:before {
8393   content: "\f1fb";
8394 }
8395 .fa-paint-brush:before {
8396   content: "\f1fc";
8397 }
8398 .fa-birthday-cake:before {
8399   content: "\f1fd";
8400 }
8401 .fa-area-chart:before {
8402   content: "\f1fe";
8403 }
8404 .fa-pie-chart:before {
8405   content: "\f200";
8406 }
8407 .fa-line-chart:before {
8408   content: "\f201";
8409 }
8410 .fa-lastfm:before {
8411   content: "\f202";
8412 }
8413 .fa-lastfm-square:before {
8414   content: "\f203";
8415 }
8416 .fa-toggle-off:before {
8417   content: "\f204";
8418 }
8419 .fa-toggle-on:before {
8420   content: "\f205";
8421 }
8422 .fa-bicycle:before {
8423   content: "\f206";
8424 }
8425 .fa-bus:before {
8426   content: "\f207";
8427 }
8428 .fa-ioxhost:before {
8429   content: "\f208";
8430 }
8431 .fa-angellist:before {
8432   content: "\f209";
8433 }
8434 .fa-cc:before {
8435   content: "\f20a";
8436 }
8437 .fa-shekel:before,
8438 .fa-sheqel:before,
8439 .fa-ils:before {
8440   content: "\f20b";
8441 }
8442 .fa-meanpath:before {
8443   content: "\f20c";
8444 }
8445 .fa-buysellads:before {
8446   content: "\f20d";
8447 }
8448 .fa-connectdevelop:before {
8449   content: "\f20e";
8450 }
8451 .fa-dashcube:before {
8452   content: "\f210";
8453 }
8454 .fa-forumbee:before {
8455   content: "\f211";
8456 }
8457 .fa-leanpub:before {
8458   content: "\f212";
8459 }
8460 .fa-sellsy:before {
8461   content: "\f213";
8462 }
8463 .fa-shirtsinbulk:before {
8464   content: "\f214";
8465 }
8466 .fa-simplybuilt:before {
8467   content: "\f215";
8468 }
8469 .fa-skyatlas:before {
8470   content: "\f216";
8471 }
8472 .fa-cart-plus:before {
8473   content: "\f217";
8474 }
8475 .fa-cart-arrow-down:before {
8476   content: "\f218";
8477 }
8478 .fa-diamond:before {
8479   content: "\f219";
8480 }
8481 .fa-ship:before {
8482   content: "\f21a";
8483 }
8484 .fa-user-secret:before {
8485   content: "\f21b";
8486 }
8487 .fa-motorcycle:before {
8488   content: "\f21c";
8489 }
8490 .fa-street-view:before {
8491   content: "\f21d";
8492 }
8493 .fa-heartbeat:before {
8494   content: "\f21e";
8495 }
8496 .fa-venus:before {
8497   content: "\f221";
8498 }
8499 .fa-mars:before {
8500   content: "\f222";
8501 }
8502 .fa-mercury:before {
8503   content: "\f223";
8504 }
8505 .fa-intersex:before,
8506 .fa-transgender:before {
8507   content: "\f224";
8508 }
8509 .fa-transgender-alt:before {
8510   content: "\f225";
8511 }
8512 .fa-venus-double:before {
8513   content: "\f226";
8514 }
8515 .fa-mars-double:before {
8516   content: "\f227";
8517 }
8518 .fa-venus-mars:before {
8519   content: "\f228";
8520 }
8521 .fa-mars-stroke:before {
8522   content: "\f229";
8523 }
8524 .fa-mars-stroke-v:before {
8525   content: "\f22a";
8526 }
8527 .fa-mars-stroke-h:before {
8528   content: "\f22b";
8529 }
8530 .fa-neuter:before {
8531   content: "\f22c";
8532 }
8533 .fa-genderless:before {
8534   content: "\f22d";
8535 }
8536 .fa-facebook-official:before {
8537   content: "\f230";
8538 }
8539 .fa-pinterest-p:before {
8540   content: "\f231";
8541 }
8542 .fa-whatsapp:before {
8543   content: "\f232";
8544 }
8545 .fa-server:before {
8546   content: "\f233";
8547 }
8548 .fa-user-plus:before {
8549   content: "\f234";
8550 }
8551 .fa-user-times:before {
8552   content: "\f235";
8553 }
8554 .fa-hotel:before,
8555 .fa-bed:before {
8556   content: "\f236";
8557 }
8558 .fa-viacoin:before {
8559   content: "\f237";
8560 }
8561 .fa-train:before {
8562   content: "\f238";
8563 }
8564 .fa-subway:before {
8565   content: "\f239";
8566 }
8567 .fa-medium:before {
8568   content: "\f23a";
8569 }
8570 .fa-yc:before,
8571 .fa-y-combinator:before {
8572   content: "\f23b";
8573 }
8574 .fa-optin-monster:before {
8575   content: "\f23c";
8576 }
8577 .fa-opencart:before {
8578   content: "\f23d";
8579 }
8580 .fa-expeditedssl:before {
8581   content: "\f23e";
8582 }
8583 .fa-battery-4:before,
8584 .fa-battery:before,
8585 .fa-battery-full:before {
8586   content: "\f240";
8587 }
8588 .fa-battery-3:before,
8589 .fa-battery-three-quarters:before {
8590   content: "\f241";
8591 }
8592 .fa-battery-2:before,
8593 .fa-battery-half:before {
8594   content: "\f242";
8595 }
8596 .fa-battery-1:before,
8597 .fa-battery-quarter:before {
8598   content: "\f243";
8599 }
8600 .fa-battery-0:before,
8601 .fa-battery-empty:before {
8602   content: "\f244";
8603 }
8604 .fa-mouse-pointer:before {
8605   content: "\f245";
8606 }
8607 .fa-i-cursor:before {
8608   content: "\f246";
8609 }
8610 .fa-object-group:before {
8611   content: "\f247";
8612 }
8613 .fa-object-ungroup:before {
8614   content: "\f248";
8615 }
8616 .fa-sticky-note:before {
8617   content: "\f249";
8618 }
8619 .fa-sticky-note-o:before {
8620   content: "\f24a";
8621 }
8622 .fa-cc-jcb:before {
8623   content: "\f24b";
8624 }
8625 .fa-cc-diners-club:before {
8626   content: "\f24c";
8627 }
8628 .fa-clone:before {
8629   content: "\f24d";
8630 }
8631 .fa-balance-scale:before {
8632   content: "\f24e";
8633 }
8634 .fa-hourglass-o:before {
8635   content: "\f250";
8636 }
8637 .fa-hourglass-1:before,
8638 .fa-hourglass-start:before {
8639   content: "\f251";
8640 }
8641 .fa-hourglass-2:before,
8642 .fa-hourglass-half:before {
8643   content: "\f252";
8644 }
8645 .fa-hourglass-3:before,
8646 .fa-hourglass-end:before {
8647   content: "\f253";
8648 }
8649 .fa-hourglass:before {
8650   content: "\f254";
8651 }
8652 .fa-hand-grab-o:before,
8653 .fa-hand-rock-o:before {
8654   content: "\f255";
8655 }
8656 .fa-hand-stop-o:before,
8657 .fa-hand-paper-o:before {
8658   content: "\f256";
8659 }
8660 .fa-hand-scissors-o:before {
8661   content: "\f257";
8662 }
8663 .fa-hand-lizard-o:before {
8664   content: "\f258";
8665 }
8666 .fa-hand-spock-o:before {
8667   content: "\f259";
8668 }
8669 .fa-hand-pointer-o:before {
8670   content: "\f25a";
8671 }
8672 .fa-hand-peace-o:before {
8673   content: "\f25b";
8674 }
8675 .fa-trademark:before {
8676   content: "\f25c";
8677 }
8678 .fa-registered:before {
8679   content: "\f25d";
8680 }
8681 .fa-creative-commons:before {
8682   content: "\f25e";
8683 }
8684 .fa-gg:before {
8685   content: "\f260";
8686 }
8687 .fa-gg-circle:before {
8688   content: "\f261";
8689 }
8690 .fa-tripadvisor:before {
8691   content: "\f262";
8692 }
8693 .fa-odnoklassniki:before {
8694   content: "\f263";
8695 }
8696 .fa-odnoklassniki-square:before {
8697   content: "\f264";
8698 }
8699 .fa-get-pocket:before {
8700   content: "\f265";
8701 }
8702 .fa-wikipedia-w:before {
8703   content: "\f266";
8704 }
8705 .fa-safari:before {
8706   content: "\f267";
8707 }
8708 .fa-chrome:before {
8709   content: "\f268";
8710 }
8711 .fa-firefox:before {
8712   content: "\f269";
8713 }
8714 .fa-opera:before {
8715   content: "\f26a";
8716 }
8717 .fa-internet-explorer:before {
8718   content: "\f26b";
8719 }
8720 .fa-tv:before,
8721 .fa-television:before {
8722   content: "\f26c";
8723 }
8724 .fa-contao:before {
8725   content: "\f26d";
8726 }
8727 .fa-500px:before {
8728   content: "\f26e";
8729 }
8730 .fa-amazon:before {
8731   content: "\f270";
8732 }
8733 .fa-calendar-plus-o:before {
8734   content: "\f271";
8735 }
8736 .fa-calendar-minus-o:before {
8737   content: "\f272";
8738 }
8739 .fa-calendar-times-o:before {
8740   content: "\f273";
8741 }
8742 .fa-calendar-check-o:before {
8743   content: "\f274";
8744 }
8745 .fa-industry:before {
8746   content: "\f275";
8747 }
8748 .fa-map-pin:before {
8749   content: "\f276";
8750 }
8751 .fa-map-signs:before {
8752   content: "\f277";
8753 }
8754 .fa-map-o:before {
8755   content: "\f278";
8756 }
8757 .fa-map:before {
8758   content: "\f279";
8759 }
8760 .fa-commenting:before {
8761   content: "\f27a";
8762 }
8763 .fa-commenting-o:before {
8764   content: "\f27b";
8765 }
8766 .fa-houzz:before {
8767   content: "\f27c";
8768 }
8769 .fa-vimeo:before {
8770   content: "\f27d";
8771 }
8772 .fa-black-tie:before {
8773   content: "\f27e";
8774 }
8775 .fa-fonticons:before {
8776   content: "\f280";
8777 }
8778 .fa-reddit-alien:before {
8779   content: "\f281";
8780 }
8781 .fa-edge:before {
8782   content: "\f282";
8783 }
8784 .fa-credit-card-alt:before {
8785   content: "\f283";
8786 }
8787 .fa-codiepie:before {
8788   content: "\f284";
8789 }
8790 .fa-modx:before {
8791   content: "\f285";
8792 }
8793 .fa-fort-awesome:before {
8794   content: "\f286";
8795 }
8796 .fa-usb:before {
8797   content: "\f287";
8798 }
8799 .fa-product-hunt:before {
8800   content: "\f288";
8801 }
8802 .fa-mixcloud:before {
8803   content: "\f289";
8804 }
8805 .fa-scribd:before {
8806   content: "\f28a";
8807 }
8808 .fa-pause-circle:before {
8809   content: "\f28b";
8810 }
8811 .fa-pause-circle-o:before {
8812   content: "\f28c";
8813 }
8814 .fa-stop-circle:before {
8815   content: "\f28d";
8816 }
8817 .fa-stop-circle-o:before {
8818   content: "\f28e";
8819 }
8820 .fa-shopping-bag:before {
8821   content: "\f290";
8822 }
8823 .fa-shopping-basket:before {
8824   content: "\f291";
8825 }
8826 .fa-hashtag:before {
8827   content: "\f292";
8828 }
8829 .fa-bluetooth:before {
8830   content: "\f293";
8831 }
8832 .fa-bluetooth-b:before {
8833   content: "\f294";
8834 }
8835 .fa-percent:before {
8836   content: "\f295";
8837 }
8838 .fa-gitlab:before {
8839   content: "\f296";
8840 }
8841 .fa-wpbeginner:before {
8842   content: "\f297";
8843 }
8844 .fa-wpforms:before {
8845   content: "\f298";
8846 }
8847 .fa-envira:before {
8848   content: "\f299";
8849 }
8850 .fa-universal-access:before {
8851   content: "\f29a";
8852 }
8853 .fa-wheelchair-alt:before {
8854   content: "\f29b";
8855 }
8856 .fa-question-circle-o:before {
8857   content: "\f29c";
8858 }
8859 .fa-blind:before {
8860   content: "\f29d";
8861 }
8862 .fa-audio-description:before {
8863   content: "\f29e";
8864 }
8865 .fa-volume-control-phone:before {
8866   content: "\f2a0";
8867 }
8868 .fa-braille:before {
8869   content: "\f2a1";
8870 }
8871 .fa-assistive-listening-systems:before {
8872   content: "\f2a2";
8873 }
8874 .fa-asl-interpreting:before,
8875 .fa-american-sign-language-interpreting:before {
8876   content: "\f2a3";
8877 }
8878 .fa-deafness:before,
8879 .fa-hard-of-hearing:before,
8880 .fa-deaf:before {
8881   content: "\f2a4";
8882 }
8883 .fa-glide:before {
8884   content: "\f2a5";
8885 }
8886 .fa-glide-g:before {
8887   content: "\f2a6";
8888 }
8889 .fa-signing:before,
8890 .fa-sign-language:before {
8891   content: "\f2a7";
8892 }
8893 .fa-low-vision:before {
8894   content: "\f2a8";
8895 }
8896 .fa-viadeo:before {
8897   content: "\f2a9";
8898 }
8899 .fa-viadeo-square:before {
8900   content: "\f2aa";
8901 }
8902 .fa-snapchat:before {
8903   content: "\f2ab";
8904 }
8905 .fa-snapchat-ghost:before {
8906   content: "\f2ac";
8907 }
8908 .fa-snapchat-square:before {
8909   content: "\f2ad";
8910 }
8911 .fa-pied-piper:before {
8912   content: "\f2ae";
8913 }
8914 .fa-first-order:before {
8915   content: "\f2b0";
8916 }
8917 .fa-yoast:before {
8918   content: "\f2b1";
8919 }
8920 .fa-themeisle:before {
8921   content: "\f2b2";
8922 }
8923 .fa-google-plus-circle:before,
8924 .fa-google-plus-official:before {
8925   content: "\f2b3";
8926 }
8927 .fa-fa:before,
8928 .fa-font-awesome:before {
8929   content: "\f2b4";
8930 }
8931 .fa-handshake-o:before {
8932   content: "\f2b5";
8933 }
8934 .fa-envelope-open:before {
8935   content: "\f2b6";
8936 }
8937 .fa-envelope-open-o:before {
8938   content: "\f2b7";
8939 }
8940 .fa-linode:before {
8941   content: "\f2b8";
8942 }
8943 .fa-address-book:before {
8944   content: "\f2b9";
8945 }
8946 .fa-address-book-o:before {
8947   content: "\f2ba";
8948 }
8949 .fa-vcard:before,
8950 .fa-address-card:before {
8951   content: "\f2bb";
8952 }
8953 .fa-vcard-o:before,
8954 .fa-address-card-o:before {
8955   content: "\f2bc";
8956 }
8957 .fa-user-circle:before {
8958   content: "\f2bd";
8959 }
8960 .fa-user-circle-o:before {
8961   content: "\f2be";
8962 }
8963 .fa-user-o:before {
8964   content: "\f2c0";
8965 }
8966 .fa-id-badge:before {
8967   content: "\f2c1";
8968 }
8969 .fa-drivers-license:before,
8970 .fa-id-card:before {
8971   content: "\f2c2";
8972 }
8973 .fa-drivers-license-o:before,
8974 .fa-id-card-o:before {
8975   content: "\f2c3";
8976 }
8977 .fa-quora:before {
8978   content: "\f2c4";
8979 }
8980 .fa-free-code-camp:before {
8981   content: "\f2c5";
8982 }
8983 .fa-telegram:before {
8984   content: "\f2c6";
8985 }
8986 .fa-thermometer-4:before,
8987 .fa-thermometer:before,
8988 .fa-thermometer-full:before {
8989   content: "\f2c7";
8990 }
8991 .fa-thermometer-3:before,
8992 .fa-thermometer-three-quarters:before {
8993   content: "\f2c8";
8994 }
8995 .fa-thermometer-2:before,
8996 .fa-thermometer-half:before {
8997   content: "\f2c9";
8998 }
8999 .fa-thermometer-1:before,
9000 .fa-thermometer-quarter:before {
9001   content: "\f2ca";
9002 }
9003 .fa-thermometer-0:before,
9004 .fa-thermometer-empty:before {
9005   content: "\f2cb";
9006 }
9007 .fa-shower:before {
9008   content: "\f2cc";
9009 }
9010 .fa-bathtub:before,
9011 .fa-s15:before,
9012 .fa-bath:before {
9013   content: "\f2cd";
9014 }
9015 .fa-podcast:before {
9016   content: "\f2ce";
9017 }
9018 .fa-window-maximize:before {
9019   content: "\f2d0";
9020 }
9021 .fa-window-minimize:before {
9022   content: "\f2d1";
9023 }
9024 .fa-window-restore:before {
9025   content: "\f2d2";
9026 }
9027 .fa-times-rectangle:before,
9028 .fa-window-close:before {
9029   content: "\f2d3";
9030 }
9031 .fa-times-rectangle-o:before,
9032 .fa-window-close-o:before {
9033   content: "\f2d4";
9034 }
9035 .fa-bandcamp:before {
9036   content: "\f2d5";
9037 }
9038 .fa-grav:before {
9039   content: "\f2d6";
9040 }
9041 .fa-etsy:before {
9042   content: "\f2d7";
9043 }
9044 .fa-imdb:before {
9045   content: "\f2d8";
9046 }
9047 .fa-ravelry:before {
9048   content: "\f2d9";
9049 }
9050 .fa-eercast:before {
9051   content: "\f2da";
9052 }
9053 .fa-microchip:before {
9054   content: "\f2db";
9055 }
9056 .fa-snowflake-o:before {
9057   content: "\f2dc";
9058 }
9059 .fa-superpowers:before {
9060   content: "\f2dd";
9061 }
9062 .fa-wpexplorer:before {
9063   content: "\f2de";
9064 }
9065 .fa-meetup:before {
9066   content: "\f2e0";
9067 }
9068 .sr-only {
9069   position: absolute;
9070   width: 1px;
9071   height: 1px;
9072   padding: 0;
9073   margin: -1px;
9074   overflow: hidden;
9075   clip: rect(0, 0, 0, 0);
9076   border: 0;
9077 }
9078 .sr-only-focusable:active,
9079 .sr-only-focusable:focus {
9080   position: static;
9081   width: auto;
9082   height: auto;
9083   margin: 0;
9084   overflow: visible;
9085   clip: auto;
9086 }
9087 .sr-only-focusable:active,
9088 .sr-only-focusable:focus {
9089   position: static;
9090   width: auto;
9091   height: auto;
9092   margin: 0;
9093   overflow: visible;
9094   clip: auto;
9095 }
9096 /*!
9097 *
9098 * IPython base
9099 *
9100 */
9101 .modal.fade .modal-dialog {
9102   -webkit-transform: translate(0, 0);
9103   -ms-transform: translate(0, 0);
9104   -o-transform: translate(0, 0);
9105   transform: translate(0, 0);
9106 }
9107 code {
9108   color: #000;
9109 }
9110 pre {
9111   font-size: inherit;
9112   line-height: inherit;
9113 }
9114 label {
9115   font-weight: normal;
9116 }
9117 /* Make the page background atleast 100% the height of the view port */
9118 /* Make the page itself atleast 70% the height of the view port */
9119 .border-box-sizing {
9120   box-sizing: border-box;
9121   -moz-box-sizing: border-box;
9122   -webkit-box-sizing: border-box;
9123 }
9124 .corner-all {
9125   border-radius: 2px;
9126 }
9127 .no-padding {
9128   padding: 0px;
9129 }
9130 /* Flexible box model classes */
9131 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
9132 /* This file is a compatability layer.  It allows the usage of flexible box 
9133 model layouts accross multiple browsers, including older browsers.  The newest,
9134 universal implementation of the flexible box model is used when available (see
9135 `Modern browsers` comments below).  Browsers that are known to implement this 
9136 new spec completely include:
9137
9138     Firefox 28.0+
9139     Chrome 29.0+
9140     Internet Explorer 11+ 
9141     Opera 17.0+
9142
9143 Browsers not listed, including Safari, are supported via the styling under the
9144 `Old browsers` comments below.
9145 */
9146 .hbox {
9147   /* Old browsers */
9148   display: -webkit-box;
9149   -webkit-box-orient: horizontal;
9150   -webkit-box-align: stretch;
9151   display: -moz-box;
9152   -moz-box-orient: horizontal;
9153   -moz-box-align: stretch;
9154   display: box;
9155   box-orient: horizontal;
9156   box-align: stretch;
9157   /* Modern browsers */
9158   display: flex;
9159   flex-direction: row;
9160   align-items: stretch;
9161 }
9162 .hbox > * {
9163   /* Old browsers */
9164   -webkit-box-flex: 0;
9165   -moz-box-flex: 0;
9166   box-flex: 0;
9167   /* Modern browsers */
9168   flex: none;
9169 }
9170 .vbox {
9171   /* Old browsers */
9172   display: -webkit-box;
9173   -webkit-box-orient: vertical;
9174   -webkit-box-align: stretch;
9175   display: -moz-box;
9176   -moz-box-orient: vertical;
9177   -moz-box-align: stretch;
9178   display: box;
9179   box-orient: vertical;
9180   box-align: stretch;
9181   /* Modern browsers */
9182   display: flex;
9183   flex-direction: column;
9184   align-items: stretch;
9185 }
9186 .vbox > * {
9187   /* Old browsers */
9188   -webkit-box-flex: 0;
9189   -moz-box-flex: 0;
9190   box-flex: 0;
9191   /* Modern browsers */
9192   flex: none;
9193 }
9194 .hbox.reverse,
9195 .vbox.reverse,
9196 .reverse {
9197   /* Old browsers */
9198   -webkit-box-direction: reverse;
9199   -moz-box-direction: reverse;
9200   box-direction: reverse;
9201   /* Modern browsers */
9202   flex-direction: row-reverse;
9203 }
9204 .hbox.box-flex0,
9205 .vbox.box-flex0,
9206 .box-flex0 {
9207   /* Old browsers */
9208   -webkit-box-flex: 0;
9209   -moz-box-flex: 0;
9210   box-flex: 0;
9211   /* Modern browsers */
9212   flex: none;
9213   width: auto;
9214 }
9215 .hbox.box-flex1,
9216 .vbox.box-flex1,
9217 .box-flex1 {
9218   /* Old browsers */
9219   -webkit-box-flex: 1;
9220   -moz-box-flex: 1;
9221   box-flex: 1;
9222   /* Modern browsers */
9223   flex: 1;
9224 }
9225 .hbox.box-flex,
9226 .vbox.box-flex,
9227 .box-flex {
9228   /* Old browsers */
9229   /* Old browsers */
9230   -webkit-box-flex: 1;
9231   -moz-box-flex: 1;
9232   box-flex: 1;
9233   /* Modern browsers */
9234   flex: 1;
9235 }
9236 .hbox.box-flex2,
9237 .vbox.box-flex2,
9238 .box-flex2 {
9239   /* Old browsers */
9240   -webkit-box-flex: 2;
9241   -moz-box-flex: 2;
9242   box-flex: 2;
9243   /* Modern browsers */
9244   flex: 2;
9245 }
9246 .box-group1 {
9247   /*  Deprecated */
9248   -webkit-box-flex-group: 1;
9249   -moz-box-flex-group: 1;
9250   box-flex-group: 1;
9251 }
9252 .box-group2 {
9253   /* Deprecated */
9254   -webkit-box-flex-group: 2;
9255   -moz-box-flex-group: 2;
9256   box-flex-group: 2;
9257 }
9258 .hbox.start,
9259 .vbox.start,
9260 .start {
9261   /* Old browsers */
9262   -webkit-box-pack: start;
9263   -moz-box-pack: start;
9264   box-pack: start;
9265   /* Modern browsers */
9266   justify-content: flex-start;
9267 }
9268 .hbox.end,
9269 .vbox.end,
9270 .end {
9271   /* Old browsers */
9272   -webkit-box-pack: end;
9273   -moz-box-pack: end;
9274   box-pack: end;
9275   /* Modern browsers */
9276   justify-content: flex-end;
9277 }
9278 .hbox.center,
9279 .vbox.center,
9280 .center {
9281   /* Old browsers */
9282   -webkit-box-pack: center;
9283   -moz-box-pack: center;
9284   box-pack: center;
9285   /* Modern browsers */
9286   justify-content: center;
9287 }
9288 .hbox.baseline,
9289 .vbox.baseline,
9290 .baseline {
9291   /* Old browsers */
9292   -webkit-box-pack: baseline;
9293   -moz-box-pack: baseline;
9294   box-pack: baseline;
9295   /* Modern browsers */
9296   justify-content: baseline;
9297 }
9298 .hbox.stretch,
9299 .vbox.stretch,
9300 .stretch {
9301   /* Old browsers */
9302   -webkit-box-pack: stretch;
9303   -moz-box-pack: stretch;
9304   box-pack: stretch;
9305   /* Modern browsers */
9306   justify-content: stretch;
9307 }
9308 .hbox.align-start,
9309 .vbox.align-start,
9310 .align-start {
9311   /* Old browsers */
9312   -webkit-box-align: start;
9313   -moz-box-align: start;
9314   box-align: start;
9315   /* Modern browsers */
9316   align-items: flex-start;
9317 }
9318 .hbox.align-end,
9319 .vbox.align-end,
9320 .align-end {
9321   /* Old browsers */
9322   -webkit-box-align: end;
9323   -moz-box-align: end;
9324   box-align: end;
9325   /* Modern browsers */
9326   align-items: flex-end;
9327 }
9328 .hbox.align-center,
9329 .vbox.align-center,
9330 .align-center {
9331   /* Old browsers */
9332   -webkit-box-align: center;
9333   -moz-box-align: center;
9334   box-align: center;
9335   /* Modern browsers */
9336   align-items: center;
9337 }
9338 .hbox.align-baseline,
9339 .vbox.align-baseline,
9340 .align-baseline {
9341   /* Old browsers */
9342   -webkit-box-align: baseline;
9343   -moz-box-align: baseline;
9344   box-align: baseline;
9345   /* Modern browsers */
9346   align-items: baseline;
9347 }
9348 .hbox.align-stretch,
9349 .vbox.align-stretch,
9350 .align-stretch {
9351   /* Old browsers */
9352   -webkit-box-align: stretch;
9353   -moz-box-align: stretch;
9354   box-align: stretch;
9355   /* Modern browsers */
9356   align-items: stretch;
9357 }
9358 div.error {
9359   margin: 2em;
9360   text-align: center;
9361 }
9362 div.error > h1 {
9363   font-size: 500%;
9364   line-height: normal;
9365 }
9366 div.error > p {
9367   font-size: 200%;
9368   line-height: normal;
9369 }
9370 div.traceback-wrapper {
9371   text-align: left;
9372   max-width: 800px;
9373   margin: auto;
9374 }
9375 div.traceback-wrapper pre.traceback {
9376   max-height: 600px;
9377   overflow: auto;
9378 }
9379 /**
9380  * Primary styles
9381  *
9382  * Author: Jupyter Development Team
9383  */
9384 body {
9385   background-color: #fff;
9386   /* This makes sure that the body covers the entire window and needs to
9387        be in a different element than the display: box in wrapper below */
9388   position: absolute;
9389   left: 0px;
9390   right: 0px;
9391   top: 0px;
9392   bottom: 0px;
9393   overflow: visible;
9394 }
9395 body > #header {
9396   /* Initially hidden to prevent FLOUC */
9397   display: none;
9398   background-color: #fff;
9399   /* Display over codemirror */
9400   position: relative;
9401   z-index: 100;
9402 }
9403 body > #header #header-container {
9404   display: flex;
9405   flex-direction: row;
9406   justify-content: space-between;
9407   padding: 5px;
9408   padding-bottom: 5px;
9409   padding-top: 5px;
9410   box-sizing: border-box;
9411   -moz-box-sizing: border-box;
9412   -webkit-box-sizing: border-box;
9413 }
9414 body > #header .header-bar {
9415   width: 100%;
9416   height: 1px;
9417   background: #e7e7e7;
9418   margin-bottom: -1px;
9419 }
9420 @media print {
9421   body > #header {
9422     display: none !important;
9423   }
9424 }
9425 #header-spacer {
9426   width: 100%;
9427   visibility: hidden;
9428 }
9429 @media print {
9430   #header-spacer {
9431     display: none;
9432   }
9433 }
9434 #ipython_notebook {
9435   padding-left: 0px;
9436   padding-top: 1px;
9437   padding-bottom: 1px;
9438 }
9439 [dir="rtl"] #ipython_notebook {
9440   margin-right: 10px;
9441   margin-left: 0;
9442 }
9443 [dir="rtl"] #ipython_notebook.pull-left {
9444   float: right !important;
9445   float: right;
9446 }
9447 .flex-spacer {
9448   flex: 1;
9449 }
9450 #noscript {
9451   width: auto;
9452   padding-top: 16px;
9453   padding-bottom: 16px;
9454   text-align: center;
9455   font-size: 22px;
9456   color: red;
9457   font-weight: bold;
9458 }
9459 #ipython_notebook img {
9460   height: 28px;
9461 }
9462 #site {
9463   width: 100%;
9464   display: none;
9465   box-sizing: border-box;
9466   -moz-box-sizing: border-box;
9467   -webkit-box-sizing: border-box;
9468   overflow: auto;
9469 }
9470 @media print {
9471   #site {
9472     height: auto !important;
9473   }
9474 }
9475 /* Smaller buttons */
9476 .ui-button .ui-button-text {
9477   padding: 0.2em 0.8em;
9478   font-size: 77%;
9479 }
9480 input.ui-button {
9481   padding: 0.3em 0.9em;
9482 }
9483 span#kernel_logo_widget {
9484   margin: 0 10px;
9485 }
9486 span#login_widget {
9487   float: right;
9488 }
9489 [dir="rtl"] span#login_widget {
9490   float: left;
9491 }
9492 span#login_widget > .button,
9493 #logout {
9494   color: #333;
9495   background-color: #fff;
9496   border-color: #ccc;
9497 }
9498 span#login_widget > .button:focus,
9499 #logout:focus,
9500 span#login_widget > .button.focus,
9501 #logout.focus {
9502   color: #333;
9503   background-color: #e6e6e6;
9504   border-color: #8c8c8c;
9505 }
9506 span#login_widget > .button:hover,
9507 #logout:hover {
9508   color: #333;
9509   background-color: #e6e6e6;
9510   border-color: #adadad;
9511 }
9512 span#login_widget > .button:active,
9513 #logout:active,
9514 span#login_widget > .button.active,
9515 #logout.active,
9516 .open > .dropdown-togglespan#login_widget > .button,
9517 .open > .dropdown-toggle#logout {
9518   color: #333;
9519   background-color: #e6e6e6;
9520   border-color: #adadad;
9521 }
9522 span#login_widget > .button:active:hover,
9523 #logout:active:hover,
9524 span#login_widget > .button.active:hover,
9525 #logout.active:hover,
9526 .open > .dropdown-togglespan#login_widget > .button:hover,
9527 .open > .dropdown-toggle#logout:hover,
9528 span#login_widget > .button:active:focus,
9529 #logout:active:focus,
9530 span#login_widget > .button.active:focus,
9531 #logout.active:focus,
9532 .open > .dropdown-togglespan#login_widget > .button:focus,
9533 .open > .dropdown-toggle#logout:focus,
9534 span#login_widget > .button:active.focus,
9535 #logout:active.focus,
9536 span#login_widget > .button.active.focus,
9537 #logout.active.focus,
9538 .open > .dropdown-togglespan#login_widget > .button.focus,
9539 .open > .dropdown-toggle#logout.focus {
9540   color: #333;
9541   background-color: #d4d4d4;
9542   border-color: #8c8c8c;
9543 }
9544 span#login_widget > .button:active,
9545 #logout:active,
9546 span#login_widget > .button.active,
9547 #logout.active,
9548 .open > .dropdown-togglespan#login_widget > .button,
9549 .open > .dropdown-toggle#logout {
9550   background-image: none;
9551 }
9552 span#login_widget > .button.disabled:hover,
9553 #logout.disabled:hover,
9554 span#login_widget > .button[disabled]:hover,
9555 #logout[disabled]:hover,
9556 fieldset[disabled] span#login_widget > .button:hover,
9557 fieldset[disabled] #logout:hover,
9558 span#login_widget > .button.disabled:focus,
9559 #logout.disabled:focus,
9560 span#login_widget > .button[disabled]:focus,
9561 #logout[disabled]:focus,
9562 fieldset[disabled] span#login_widget > .button:focus,
9563 fieldset[disabled] #logout:focus,
9564 span#login_widget > .button.disabled.focus,
9565 #logout.disabled.focus,
9566 span#login_widget > .button[disabled].focus,
9567 #logout[disabled].focus,
9568 fieldset[disabled] span#login_widget > .button.focus,
9569 fieldset[disabled] #logout.focus {
9570   background-color: #fff;
9571   border-color: #ccc;
9572 }
9573 span#login_widget > .button .badge,
9574 #logout .badge {
9575   color: #fff;
9576   background-color: #333;
9577 }
9578 .nav-header {
9579   text-transform: none;
9580 }
9581 #header > span {
9582   margin-top: 10px;
9583 }
9584 .modal_stretch .modal-dialog {
9585   /* Old browsers */
9586   display: -webkit-box;
9587   -webkit-box-orient: vertical;
9588   -webkit-box-align: stretch;
9589   display: -moz-box;
9590   -moz-box-orient: vertical;
9591   -moz-box-align: stretch;
9592   display: box;
9593   box-orient: vertical;
9594   box-align: stretch;
9595   /* Modern browsers */
9596   display: flex;
9597   flex-direction: column;
9598   align-items: stretch;
9599   min-height: 80vh;
9600 }
9601 .modal_stretch .modal-dialog .modal-body {
9602   max-height: calc(100vh - 200px);
9603   overflow: auto;
9604   flex: 1;
9605 }
9606 .modal-header {
9607   cursor: move;
9608 }
9609 @media (min-width: 768px) {
9610   .modal .modal-dialog {
9611     width: 700px;
9612   }
9613 }
9614 @media (min-width: 768px) {
9615   select.form-control {
9616     margin-left: 12px;
9617     margin-right: 12px;
9618   }
9619 }
9620 /*!
9621 *
9622 * IPython auth
9623 *
9624 */
9625 .center-nav {
9626   display: inline-block;
9627   margin-bottom: -4px;
9628 }
9629 [dir="rtl"] .center-nav form.pull-left {
9630   float: right !important;
9631   float: right;
9632 }
9633 [dir="rtl"] .center-nav .navbar-text {
9634   float: right;
9635 }
9636 [dir="rtl"] .navbar-inner {
9637   text-align: right;
9638 }
9639 [dir="rtl"] div.text-left {
9640   text-align: right;
9641 }
9642 /*!
9643 *
9644 * IPython tree view
9645 *
9646 */
9647 /* We need an invisible input field on top of the sentense*/
9648 /* "Drag file onto the list ..." */
9649 .alternate_upload {
9650   background-color: none;
9651   display: inline;
9652 }
9653 .alternate_upload.form {
9654   padding: 0;
9655   margin: 0;
9656 }
9657 .alternate_upload input.fileinput {
9658   position: absolute;
9659   display: block;
9660   width: 100%;
9661   height: 100%;
9662   overflow: hidden;
9663   cursor: pointer;
9664   opacity: 0;
9665   z-index: 2;
9666 }
9667 .alternate_upload .btn-xs > input.fileinput {
9668   margin: -1px -5px;
9669 }
9670 .alternate_upload .btn-upload {
9671   position: relative;
9672   height: 22px;
9673 }
9674 ::-webkit-file-upload-button {
9675   cursor: pointer;
9676 }
9677 /**
9678  * Primary styles
9679  *
9680  * Author: Jupyter Development Team
9681  */
9682 ul#tabs {
9683   margin-bottom: 4px;
9684 }
9685 ul#tabs a {
9686   padding-top: 6px;
9687   padding-bottom: 4px;
9688 }
9689 [dir="rtl"] ul#tabs.nav-tabs > li {
9690   float: right;
9691 }
9692 [dir="rtl"] ul#tabs.nav.nav-tabs {
9693   padding-right: 0;
9694 }
9695 ul.breadcrumb a:focus,
9696 ul.breadcrumb a:hover {
9697   text-decoration: none;
9698 }
9699 ul.breadcrumb i.icon-home {
9700   font-size: 16px;
9701   margin-right: 4px;
9702 }
9703 ul.breadcrumb span {
9704   color: #5e5e5e;
9705 }
9706 .list_toolbar {
9707   padding: 4px 0 4px 0;
9708   vertical-align: middle;
9709 }
9710 .list_toolbar .tree-buttons {
9711   padding-top: 1px;
9712 }
9713 [dir="rtl"] .list_toolbar .tree-buttons .pull-right {
9714   float: left !important;
9715   float: left;
9716 }
9717 [dir="rtl"] .list_toolbar .col-sm-4,
9718 [dir="rtl"] .list_toolbar .col-sm-8 {
9719   float: right;
9720 }
9721 .dynamic-buttons {
9722   padding-top: 3px;
9723   display: inline-block;
9724 }
9725 .list_toolbar [class*="span"] {
9726   min-height: 24px;
9727 }
9728 .list_header {
9729   font-weight: bold;
9730   background-color: #EEE;
9731 }
9732 .list_placeholder {
9733   font-weight: bold;
9734   padding-top: 4px;
9735   padding-bottom: 4px;
9736   padding-left: 7px;
9737   padding-right: 7px;
9738 }
9739 .list_container {
9740   margin-top: 4px;
9741   margin-bottom: 20px;
9742   border: 1px solid #ddd;
9743   border-radius: 2px;
9744 }
9745 .list_container > div {
9746   border-bottom: 1px solid #ddd;
9747 }
9748 .list_container > div:hover .list-item {
9749   background-color: red;
9750 }
9751 .list_container > div:last-child {
9752   border: none;
9753 }
9754 .list_item:hover .list_item {
9755   background-color: #ddd;
9756 }
9757 .list_item a {
9758   text-decoration: none;
9759 }
9760 .list_item:hover {
9761   background-color: #fafafa;
9762 }
9763 .list_header > div,
9764 .list_item > div {
9765   padding-top: 4px;
9766   padding-bottom: 4px;
9767   padding-left: 7px;
9768   padding-right: 7px;
9769   line-height: 22px;
9770 }
9771 .list_header > div input,
9772 .list_item > div input {
9773   margin-right: 7px;
9774   margin-left: 14px;
9775   vertical-align: text-bottom;
9776   line-height: 22px;
9777   position: relative;
9778   top: -1px;
9779 }
9780 .list_header > div .item_link,
9781 .list_item > div .item_link {
9782   margin-left: -1px;
9783   vertical-align: baseline;
9784   line-height: 22px;
9785 }
9786 [dir="rtl"] .list_item > div input {
9787   margin-right: 0;
9788 }
9789 .new-file input[type=checkbox] {
9790   visibility: hidden;
9791 }
9792 .item_name {
9793   line-height: 22px;
9794   height: 24px;
9795 }
9796 .item_icon {
9797   font-size: 14px;
9798   color: #5e5e5e;
9799   margin-right: 7px;
9800   margin-left: 7px;
9801   line-height: 22px;
9802   vertical-align: baseline;
9803 }
9804 .item_modified {
9805   margin-right: 7px;
9806   margin-left: 7px;
9807 }
9808 [dir="rtl"] .item_modified.pull-right {
9809   float: left !important;
9810   float: left;
9811 }
9812 .item_buttons {
9813   line-height: 1em;
9814   margin-left: -5px;
9815 }
9816 .item_buttons .btn,
9817 .item_buttons .btn-group,
9818 .item_buttons .input-group {
9819   float: left;
9820 }
9821 .item_buttons > .btn,
9822 .item_buttons > .btn-group,
9823 .item_buttons > .input-group {
9824   margin-left: 5px;
9825 }
9826 .item_buttons .btn {
9827   min-width: 13ex;
9828 }
9829 .item_buttons .running-indicator {
9830   padding-top: 4px;
9831   color: #5cb85c;
9832 }
9833 .item_buttons .kernel-name {
9834   padding-top: 4px;
9835   color: #5bc0de;
9836   margin-right: 7px;
9837   float: left;
9838 }
9839 [dir="rtl"] .item_buttons.pull-right {
9840   float: left !important;
9841   float: left;
9842 }
9843 [dir="rtl"] .item_buttons .kernel-name {
9844   margin-left: 7px;
9845   float: right;
9846 }
9847 .toolbar_info {
9848   height: 24px;
9849   line-height: 24px;
9850 }
9851 .list_item input:not([type=checkbox]) {
9852   padding-top: 3px;
9853   padding-bottom: 3px;
9854   height: 22px;
9855   line-height: 14px;
9856   margin: 0px;
9857 }
9858 .highlight_text {
9859   color: blue;
9860 }
9861 #project_name {
9862   display: inline-block;
9863   padding-left: 7px;
9864   margin-left: -2px;
9865 }
9866 #project_name > .breadcrumb {
9867   padding: 0px;
9868   margin-bottom: 0px;
9869   background-color: transparent;
9870   font-weight: bold;
9871 }
9872 .sort_button {
9873   display: inline-block;
9874   padding-left: 7px;
9875 }
9876 [dir="rtl"] .sort_button.pull-right {
9877   float: left !important;
9878   float: left;
9879 }
9880 #tree-selector {
9881   padding-right: 0px;
9882 }
9883 #button-select-all {
9884   min-width: 50px;
9885 }
9886 [dir="rtl"] #button-select-all.btn {
9887   float: right ;
9888 }
9889 #select-all {
9890   margin-left: 7px;
9891   margin-right: 2px;
9892   margin-top: 2px;
9893   height: 16px;
9894 }
9895 [dir="rtl"] #select-all.pull-left {
9896   float: right !important;
9897   float: right;
9898 }
9899 .menu_icon {
9900   margin-right: 2px;
9901 }
9902 .tab-content .row {
9903   margin-left: 0px;
9904   margin-right: 0px;
9905 }
9906 .folder_icon:before {
9907   display: inline-block;
9908   font: normal normal normal 14px/1 FontAwesome;
9909   font-size: inherit;
9910   text-rendering: auto;
9911   -webkit-font-smoothing: antialiased;
9912   -moz-osx-font-smoothing: grayscale;
9913   content: "\f114";
9914 }
9915 .folder_icon:before.fa-pull-left {
9916   margin-right: .3em;
9917 }
9918 .folder_icon:before.fa-pull-right {
9919   margin-left: .3em;
9920 }
9921 .folder_icon:before.pull-left {
9922   margin-right: .3em;
9923 }
9924 .folder_icon:before.pull-right {
9925   margin-left: .3em;
9926 }
9927 .notebook_icon:before {
9928   display: inline-block;
9929   font: normal normal normal 14px/1 FontAwesome;
9930   font-size: inherit;
9931   text-rendering: auto;
9932   -webkit-font-smoothing: antialiased;
9933   -moz-osx-font-smoothing: grayscale;
9934   content: "\f02d";
9935   position: relative;
9936   top: -1px;
9937 }
9938 .notebook_icon:before.fa-pull-left {
9939   margin-right: .3em;
9940 }
9941 .notebook_icon:before.fa-pull-right {
9942   margin-left: .3em;
9943 }
9944 .notebook_icon:before.pull-left {
9945   margin-right: .3em;
9946 }
9947 .notebook_icon:before.pull-right {
9948   margin-left: .3em;
9949 }
9950 .running_notebook_icon:before {
9951   display: inline-block;
9952   font: normal normal normal 14px/1 FontAwesome;
9953   font-size: inherit;
9954   text-rendering: auto;
9955   -webkit-font-smoothing: antialiased;
9956   -moz-osx-font-smoothing: grayscale;
9957   content: "\f02d";
9958   position: relative;
9959   top: -1px;
9960   color: #5cb85c;
9961 }
9962 .running_notebook_icon:before.fa-pull-left {
9963   margin-right: .3em;
9964 }
9965 .running_notebook_icon:before.fa-pull-right {
9966   margin-left: .3em;
9967 }
9968 .running_notebook_icon:before.pull-left {
9969   margin-right: .3em;
9970 }
9971 .running_notebook_icon:before.pull-right {
9972   margin-left: .3em;
9973 }
9974 .file_icon:before {
9975   display: inline-block;
9976   font: normal normal normal 14px/1 FontAwesome;
9977   font-size: inherit;
9978   text-rendering: auto;
9979   -webkit-font-smoothing: antialiased;
9980   -moz-osx-font-smoothing: grayscale;
9981   content: "\f016";
9982   position: relative;
9983   top: -2px;
9984 }
9985 .file_icon:before.fa-pull-left {
9986   margin-right: .3em;
9987 }
9988 .file_icon:before.fa-pull-right {
9989   margin-left: .3em;
9990 }
9991 .file_icon:before.pull-left {
9992   margin-right: .3em;
9993 }
9994 .file_icon:before.pull-right {
9995   margin-left: .3em;
9996 }
9997 #notebook_toolbar .pull-right {
9998   padding-top: 0px;
9999   margin-right: -1px;
10000 }
10001 ul#new-menu {
10002   left: auto;
10003   right: 0;
10004 }
10005 #new-menu .dropdown-header {
10006   font-size: 10px;
10007   border-bottom: 1px solid #e5e5e5;
10008   padding: 0 0 3px;
10009   margin: -3px 20px 0;
10010 }
10011 .kernel-menu-icon {
10012   padding-right: 12px;
10013   width: 24px;
10014   content: "\f096";
10015 }
10016 .kernel-menu-icon:before {
10017   content: "\f096";
10018 }
10019 .kernel-menu-icon-current:before {
10020   content: "\f00c";
10021 }
10022 #tab_content {
10023   padding-top: 20px;
10024 }
10025 #running .panel-group .panel {
10026   margin-top: 3px;
10027   margin-bottom: 1em;
10028 }
10029 #running .panel-group .panel .panel-heading {
10030   background-color: #EEE;
10031   padding-top: 4px;
10032   padding-bottom: 4px;
10033   padding-left: 7px;
10034   padding-right: 7px;
10035   line-height: 22px;
10036 }
10037 #running .panel-group .panel .panel-heading a:focus,
10038 #running .panel-group .panel .panel-heading a:hover {
10039   text-decoration: none;
10040 }
10041 #running .panel-group .panel .panel-body {
10042   padding: 0px;
10043 }
10044 #running .panel-group .panel .panel-body .list_container {
10045   margin-top: 0px;
10046   margin-bottom: 0px;
10047   border: 0px;
10048   border-radius: 0px;
10049 }
10050 #running .panel-group .panel .panel-body .list_container .list_item {
10051   border-bottom: 1px solid #ddd;
10052 }
10053 #running .panel-group .panel .panel-body .list_container .list_item:last-child {
10054   border-bottom: 0px;
10055 }
10056 .delete-button {
10057   display: none;
10058 }
10059 .duplicate-button {
10060   display: none;
10061 }
10062 .rename-button {
10063   display: none;
10064 }
10065 .move-button {
10066   display: none;
10067 }
10068 .download-button {
10069   display: none;
10070 }
10071 .shutdown-button {
10072   display: none;
10073 }
10074 .dynamic-instructions {
10075   display: inline-block;
10076   padding-top: 4px;
10077 }
10078 /*!
10079 *
10080 * IPython text editor webapp
10081 *
10082 */
10083 .selected-keymap i.fa {
10084   padding: 0px 5px;
10085 }
10086 .selected-keymap i.fa:before {
10087   content: "\f00c";
10088 }
10089 #mode-menu {
10090   overflow: auto;
10091   max-height: 20em;
10092 }
10093 .edit_app #header {
10094   -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10095   box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10096 }
10097 .edit_app #menubar .navbar {
10098   /* Use a negative 1 bottom margin, so the border overlaps the border of the
10099     header */
10100   margin-bottom: -1px;
10101 }
10102 .dirty-indicator {
10103   display: inline-block;
10104   font: normal normal normal 14px/1 FontAwesome;
10105   font-size: inherit;
10106   text-rendering: auto;
10107   -webkit-font-smoothing: antialiased;
10108   -moz-osx-font-smoothing: grayscale;
10109   width: 20px;
10110 }
10111 .dirty-indicator.fa-pull-left {
10112   margin-right: .3em;
10113 }
10114 .dirty-indicator.fa-pull-right {
10115   margin-left: .3em;
10116 }
10117 .dirty-indicator.pull-left {
10118   margin-right: .3em;
10119 }
10120 .dirty-indicator.pull-right {
10121   margin-left: .3em;
10122 }
10123 .dirty-indicator-dirty {
10124   display: inline-block;
10125   font: normal normal normal 14px/1 FontAwesome;
10126   font-size: inherit;
10127   text-rendering: auto;
10128   -webkit-font-smoothing: antialiased;
10129   -moz-osx-font-smoothing: grayscale;
10130   width: 20px;
10131 }
10132 .dirty-indicator-dirty.fa-pull-left {
10133   margin-right: .3em;
10134 }
10135 .dirty-indicator-dirty.fa-pull-right {
10136   margin-left: .3em;
10137 }
10138 .dirty-indicator-dirty.pull-left {
10139   margin-right: .3em;
10140 }
10141 .dirty-indicator-dirty.pull-right {
10142   margin-left: .3em;
10143 }
10144 .dirty-indicator-clean {
10145   display: inline-block;
10146   font: normal normal normal 14px/1 FontAwesome;
10147   font-size: inherit;
10148   text-rendering: auto;
10149   -webkit-font-smoothing: antialiased;
10150   -moz-osx-font-smoothing: grayscale;
10151   width: 20px;
10152 }
10153 .dirty-indicator-clean.fa-pull-left {
10154   margin-right: .3em;
10155 }
10156 .dirty-indicator-clean.fa-pull-right {
10157   margin-left: .3em;
10158 }
10159 .dirty-indicator-clean.pull-left {
10160   margin-right: .3em;
10161 }
10162 .dirty-indicator-clean.pull-right {
10163   margin-left: .3em;
10164 }
10165 .dirty-indicator-clean:before {
10166   display: inline-block;
10167   font: normal normal normal 14px/1 FontAwesome;
10168   font-size: inherit;
10169   text-rendering: auto;
10170   -webkit-font-smoothing: antialiased;
10171   -moz-osx-font-smoothing: grayscale;
10172   content: "\f00c";
10173 }
10174 .dirty-indicator-clean:before.fa-pull-left {
10175   margin-right: .3em;
10176 }
10177 .dirty-indicator-clean:before.fa-pull-right {
10178   margin-left: .3em;
10179 }
10180 .dirty-indicator-clean:before.pull-left {
10181   margin-right: .3em;
10182 }
10183 .dirty-indicator-clean:before.pull-right {
10184   margin-left: .3em;
10185 }
10186 #filename {
10187   font-size: 16pt;
10188   display: table;
10189   padding: 0px 5px;
10190 }
10191 #current-mode {
10192   padding-left: 5px;
10193   padding-right: 5px;
10194 }
10195 #texteditor-backdrop {
10196   padding-top: 20px;
10197   padding-bottom: 20px;
10198 }
10199 @media not print {
10200   #texteditor-backdrop {
10201     background-color: #EEE;
10202   }
10203 }
10204 @media print {
10205   #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
10206   #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
10207     background-color: #fff;
10208   }
10209 }
10210 @media not print {
10211   #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
10212   #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
10213     background-color: #fff;
10214   }
10215 }
10216 @media not print {
10217   #texteditor-backdrop #texteditor-container {
10218     padding: 0px;
10219     background-color: #fff;
10220     -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10221     box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10222   }
10223 }
10224 .CodeMirror-dialog {
10225   background-color: #fff;
10226 }
10227 /*!
10228 *
10229 * IPython notebook
10230 *
10231 */
10232 /* CSS font colors for translated ANSI escape sequences */
10233 /* The color values are a mix of
10234    http://www.xcolors.net/dl/baskerville-ivorylight and
10235    http://www.xcolors.net/dl/euphrasia */
10236 .ansi-black-fg {
10237   color: #3E424D;
10238 }
10239 .ansi-black-bg {
10240   background-color: #3E424D;
10241 }
10242 .ansi-black-intense-fg {
10243   color: #282C36;
10244 }
10245 .ansi-black-intense-bg {
10246   background-color: #282C36;
10247 }
10248 .ansi-red-fg {
10249   color: #E75C58;
10250 }
10251 .ansi-red-bg {
10252   background-color: #E75C58;
10253 }
10254 .ansi-red-intense-fg {
10255   color: #B22B31;
10256 }
10257 .ansi-red-intense-bg {
10258   background-color: #B22B31;
10259 }
10260 .ansi-green-fg {
10261   color: #00A250;
10262 }
10263 .ansi-green-bg {
10264   background-color: #00A250;
10265 }
10266 .ansi-green-intense-fg {
10267   color: #007427;
10268 }
10269 .ansi-green-intense-bg {
10270   background-color: #007427;
10271 }
10272 .ansi-yellow-fg {
10273   color: #DDB62B;
10274 }
10275 .ansi-yellow-bg {
10276   background-color: #DDB62B;
10277 }
10278 .ansi-yellow-intense-fg {
10279   color: #B27D12;
10280 }
10281 .ansi-yellow-intense-bg {
10282   background-color: #B27D12;
10283 }
10284 .ansi-blue-fg {
10285   color: #208FFB;
10286 }
10287 .ansi-blue-bg {
10288   background-color: #208FFB;
10289 }
10290 .ansi-blue-intense-fg {
10291   color: #0065CA;
10292 }
10293 .ansi-blue-intense-bg {
10294   background-color: #0065CA;
10295 }
10296 .ansi-magenta-fg {
10297   color: #D160C4;
10298 }
10299 .ansi-magenta-bg {
10300   background-color: #D160C4;
10301 }
10302 .ansi-magenta-intense-fg {
10303   color: #A03196;
10304 }
10305 .ansi-magenta-intense-bg {
10306   background-color: #A03196;
10307 }
10308 .ansi-cyan-fg {
10309   color: #60C6C8;
10310 }
10311 .ansi-cyan-bg {
10312   background-color: #60C6C8;
10313 }
10314 .ansi-cyan-intense-fg {
10315   color: #258F8F;
10316 }
10317 .ansi-cyan-intense-bg {
10318   background-color: #258F8F;
10319 }
10320 .ansi-white-fg {
10321   color: #C5C1B4;
10322 }
10323 .ansi-white-bg {
10324   background-color: #C5C1B4;
10325 }
10326 .ansi-white-intense-fg {
10327   color: #A1A6B2;
10328 }
10329 .ansi-white-intense-bg {
10330   background-color: #A1A6B2;
10331 }
10332 .ansi-default-inverse-fg {
10333   color: #FFFFFF;
10334 }
10335 .ansi-default-inverse-bg {
10336   background-color: #000000;
10337 }
10338 .ansi-bold {
10339   font-weight: bold;
10340 }
10341 .ansi-underline {
10342   text-decoration: underline;
10343 }
10344 /* The following styles are deprecated an will be removed in a future version */
10345 .ansibold {
10346   font-weight: bold;
10347 }
10348 .ansi-inverse {
10349   outline: 0.5px dotted;
10350 }
10351 /* use dark versions for foreground, to improve visibility */
10352 .ansiblack {
10353   color: black;
10354 }
10355 .ansired {
10356   color: darkred;
10357 }
10358 .ansigreen {
10359   color: darkgreen;
10360 }
10361 .ansiyellow {
10362   color: #c4a000;
10363 }
10364 .ansiblue {
10365   color: darkblue;
10366 }
10367 .ansipurple {
10368   color: darkviolet;
10369 }
10370 .ansicyan {
10371   color: steelblue;
10372 }
10373 .ansigray {
10374   color: gray;
10375 }
10376 /* and light for background, for the same reason */
10377 .ansibgblack {
10378   background-color: black;
10379 }
10380 .ansibgred {
10381   background-color: red;
10382 }
10383 .ansibggreen {
10384   background-color: green;
10385 }
10386 .ansibgyellow {
10387   background-color: yellow;
10388 }
10389 .ansibgblue {
10390   background-color: blue;
10391 }
10392 .ansibgpurple {
10393   background-color: magenta;
10394 }
10395 .ansibgcyan {
10396   background-color: cyan;
10397 }
10398 .ansibggray {
10399   background-color: gray;
10400 }
10401 div.cell {
10402   /* Old browsers */
10403   display: -webkit-box;
10404   -webkit-box-orient: vertical;
10405   -webkit-box-align: stretch;
10406   display: -moz-box;
10407   -moz-box-orient: vertical;
10408   -moz-box-align: stretch;
10409   display: box;
10410   box-orient: vertical;
10411   box-align: stretch;
10412   /* Modern browsers */
10413   display: flex;
10414   flex-direction: column;
10415   align-items: stretch;
10416   border-radius: 2px;
10417   box-sizing: border-box;
10418   -moz-box-sizing: border-box;
10419   -webkit-box-sizing: border-box;
10420   border-width: 1px;
10421   border-style: solid;
10422   border-color: transparent;
10423   width: 100%;
10424   padding: 5px;
10425   /* This acts as a spacer between cells, that is outside the border */
10426   margin: 0px;
10427   outline: none;
10428   position: relative;
10429   overflow: visible;
10430 }
10431 div.cell:before {
10432   position: absolute;
10433   display: block;
10434   top: -1px;
10435   left: -1px;
10436   width: 5px;
10437   height: calc(100% +  2px);
10438   content: '';
10439   background: transparent;
10440 }
10441 div.cell.jupyter-soft-selected {
10442   border-left-color: #E3F2FD;
10443   border-left-width: 1px;
10444   padding-left: 5px;
10445   border-right-color: #E3F2FD;
10446   border-right-width: 1px;
10447   background: #E3F2FD;
10448 }
10449 @media print {
10450   div.cell.jupyter-soft-selected {
10451     border-color: transparent;
10452   }
10453 }
10454 div.cell.selected,
10455 div.cell.selected.jupyter-soft-selected {
10456   border-color: #ababab;
10457 }
10458 div.cell.selected:before,
10459 div.cell.selected.jupyter-soft-selected:before {
10460   position: absolute;
10461   display: block;
10462   top: -1px;
10463   left: -1px;
10464   width: 5px;
10465   height: calc(100% +  2px);
10466   content: '';
10467   background: #42A5F5;
10468 }
10469 @media print {
10470   div.cell.selected,
10471   div.cell.selected.jupyter-soft-selected {
10472     border-color: transparent;
10473   }
10474 }
10475 .edit_mode div.cell.selected {
10476   border-color: #66BB6A;
10477 }
10478 .edit_mode div.cell.selected:before {
10479   position: absolute;
10480   display: block;
10481   top: -1px;
10482   left: -1px;
10483   width: 5px;
10484   height: calc(100% +  2px);
10485   content: '';
10486   background: #66BB6A;
10487 }
10488 @media print {
10489   .edit_mode div.cell.selected {
10490     border-color: transparent;
10491   }
10492 }
10493 .prompt {
10494   /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
10495   min-width: 14ex;
10496   /* This padding is tuned to match the padding on the CodeMirror editor. */
10497   padding: 0.4em;
10498   margin: 0px;
10499   font-family: monospace;
10500   text-align: right;
10501   /* This has to match that of the the CodeMirror class line-height below */
10502   line-height: 1.21429em;
10503   /* Don't highlight prompt number selection */
10504   -webkit-touch-callout: none;
10505   -webkit-user-select: none;
10506   -khtml-user-select: none;
10507   -moz-user-select: none;
10508   -ms-user-select: none;
10509   user-select: none;
10510   /* Use default cursor */
10511   cursor: default;
10512 }
10513 @media (max-width: 540px) {
10514   .prompt {
10515     text-align: left;
10516   }
10517 }
10518 div.inner_cell {
10519   min-width: 0;
10520   /* Old browsers */
10521   display: -webkit-box;
10522   -webkit-box-orient: vertical;
10523   -webkit-box-align: stretch;
10524   display: -moz-box;
10525   -moz-box-orient: vertical;
10526   -moz-box-align: stretch;
10527   display: box;
10528   box-orient: vertical;
10529   box-align: stretch;
10530   /* Modern browsers */
10531   display: flex;
10532   flex-direction: column;
10533   align-items: stretch;
10534   /* Old browsers */
10535   -webkit-box-flex: 1;
10536   -moz-box-flex: 1;
10537   box-flex: 1;
10538   /* Modern browsers */
10539   flex: 1;
10540 }
10541 /* input_area and input_prompt must match in top border and margin for alignment */
10542 div.input_area {
10543   border: 1px solid #cfcfcf;
10544   border-radius: 2px;
10545   background: #f7f7f7;
10546   line-height: 1.21429em;
10547 }
10548 /* This is needed so that empty prompt areas can collapse to zero height when there
10549    is no content in the output_subarea and the prompt. The main purpose of this is
10550    to make sure that empty JavaScript output_subareas have no height. */
10551 div.prompt:empty {
10552   padding-top: 0;
10553   padding-bottom: 0;
10554 }
10555 div.unrecognized_cell {
10556   padding: 5px 5px 5px 0px;
10557   /* Old browsers */
10558   display: -webkit-box;
10559   -webkit-box-orient: horizontal;
10560   -webkit-box-align: stretch;
10561   display: -moz-box;
10562   -moz-box-orient: horizontal;
10563   -moz-box-align: stretch;
10564   display: box;
10565   box-orient: horizontal;
10566   box-align: stretch;
10567   /* Modern browsers */
10568   display: flex;
10569   flex-direction: row;
10570   align-items: stretch;
10571 }
10572 div.unrecognized_cell .inner_cell {
10573   border-radius: 2px;
10574   padding: 5px;
10575   font-weight: bold;
10576   color: red;
10577   border: 1px solid #cfcfcf;
10578   background: #eaeaea;
10579 }
10580 div.unrecognized_cell .inner_cell a {
10581   color: inherit;
10582   text-decoration: none;
10583 }
10584 div.unrecognized_cell .inner_cell a:hover {
10585   color: inherit;
10586   text-decoration: none;
10587 }
10588 @media (max-width: 540px) {
10589   div.unrecognized_cell > div.prompt {
10590     display: none;
10591   }
10592 }
10593 div.code_cell {
10594   /* avoid page breaking on code cells when printing */
10595 }
10596 @media print {
10597   div.code_cell {
10598     page-break-inside: avoid;
10599   }
10600 }
10601 /* any special styling for code cells that are currently running goes here */
10602 div.input {
10603   page-break-inside: avoid;
10604   /* Old browsers */
10605   display: -webkit-box;
10606   -webkit-box-orient: horizontal;
10607   -webkit-box-align: stretch;
10608   display: -moz-box;
10609   -moz-box-orient: horizontal;
10610   -moz-box-align: stretch;
10611   display: box;
10612   box-orient: horizontal;
10613   box-align: stretch;
10614   /* Modern browsers */
10615   display: flex;
10616   flex-direction: row;
10617   align-items: stretch;
10618 }
10619 @media (max-width: 540px) {
10620   div.input {
10621     /* Old browsers */
10622     display: -webkit-box;
10623     -webkit-box-orient: vertical;
10624     -webkit-box-align: stretch;
10625     display: -moz-box;
10626     -moz-box-orient: vertical;
10627     -moz-box-align: stretch;
10628     display: box;
10629     box-orient: vertical;
10630     box-align: stretch;
10631     /* Modern browsers */
10632     display: flex;
10633     flex-direction: column;
10634     align-items: stretch;
10635   }
10636 }
10637 /* input_area and input_prompt must match in top border and margin for alignment */
10638 div.input_prompt {
10639   color: #303F9F;
10640   border-top: 1px solid transparent;
10641 }
10642 div.input_area > div.highlight {
10643   margin: 0.4em;
10644   border: none;
10645   padding: 0px;
10646   background-color: transparent;
10647 }
10648 div.input_area > div.highlight > pre {
10649   margin: 0px;
10650   border: none;
10651   padding: 0px;
10652   background-color: transparent;
10653 }
10654 /* The following gets added to the <head> if it is detected that the user has a
10655  * monospace font with inconsistent normal/bold/italic height.  See
10656  * notebookmain.js.  Such fonts will have keywords vertically offset with
10657  * respect to the rest of the text.  The user should select a better font.
10658  * See: https://github.com/ipython/ipython/issues/1503
10659  *
10660  * .CodeMirror span {
10661  *      vertical-align: bottom;
10662  * }
10663  */
10664 .CodeMirror {
10665   line-height: 1.21429em;
10666   /* Changed from 1em to our global default */
10667   font-size: 14px;
10668   height: auto;
10669   /* Changed to auto to autogrow */
10670   background: none;
10671   /* Changed from white to allow our bg to show through */
10672 }
10673 .CodeMirror-scroll {
10674   /*  The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
10675   /*  We have found that if it is visible, vertical scrollbars appear with font size changes.*/
10676   overflow-y: hidden;
10677   overflow-x: auto;
10678 }
10679 .CodeMirror-lines {
10680   /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
10681   /* we have set a different line-height and want this to scale with that. */
10682   /* Note that this should set vertical padding only, since CodeMirror assumes
10683        that horizontal padding will be set on CodeMirror pre */
10684   padding: 0.4em 0;
10685 }
10686 .CodeMirror-linenumber {
10687   padding: 0 8px 0 4px;
10688 }
10689 .CodeMirror-gutters {
10690   border-bottom-left-radius: 2px;
10691   border-top-left-radius: 2px;
10692 }
10693 .CodeMirror pre {
10694   /* In CM3 this went to 4px from 0 in CM2. This sets horizontal padding only,
10695     use .CodeMirror-lines for vertical */
10696   padding: 0 0.4em;
10697   border: 0;
10698   border-radius: 0;
10699 }
10700 .CodeMirror-cursor {
10701   border-left: 1.4px solid black;
10702 }
10703 @media screen and (min-width: 2138px) and (max-width: 4319px) {
10704   .CodeMirror-cursor {
10705     border-left: 2px solid black;
10706   }
10707 }
10708 @media screen and (min-width: 4320px) {
10709   .CodeMirror-cursor {
10710     border-left: 4px solid black;
10711   }
10712 }
10713 /*
10714
10715 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
10716 Adapted from GitHub theme
10717
10718 */
10719 .highlight-base {
10720   color: #000;
10721 }
10722 .highlight-variable {
10723   color: #000;
10724 }
10725 .highlight-variable-2 {
10726   color: #1a1a1a;
10727 }
10728 .highlight-variable-3 {
10729   color: #333333;
10730 }
10731 .highlight-string {
10732   color: #BA2121;
10733 }
10734 .highlight-comment {
10735   color: #408080;
10736   font-style: italic;
10737 }
10738 .highlight-number {
10739   color: #080;
10740 }
10741 .highlight-atom {
10742   color: #88F;
10743 }
10744 .highlight-keyword {
10745   color: #008000;
10746   font-weight: bold;
10747 }
10748 .highlight-builtin {
10749   color: #008000;
10750 }
10751 .highlight-error {
10752   color: #f00;
10753 }
10754 .highlight-operator {
10755   color: #AA22FF;
10756   font-weight: bold;
10757 }
10758 .highlight-meta {
10759   color: #AA22FF;
10760 }
10761 /* previously not defined, copying from default codemirror */
10762 .highlight-def {
10763   color: #00f;
10764 }
10765 .highlight-string-2 {
10766   color: #f50;
10767 }
10768 .highlight-qualifier {
10769   color: #555;
10770 }
10771 .highlight-bracket {
10772   color: #997;
10773 }
10774 .highlight-tag {
10775   color: #170;
10776 }
10777 .highlight-attribute {
10778   color: #00c;
10779 }
10780 .highlight-header {
10781   color: blue;
10782 }
10783 .highlight-quote {
10784   color: #090;
10785 }
10786 .highlight-link {
10787   color: #00c;
10788 }
10789 /* apply the same style to codemirror */
10790 .cm-s-ipython span.cm-keyword {
10791   color: #008000;
10792   font-weight: bold;
10793 }
10794 .cm-s-ipython span.cm-atom {
10795   color: #88F;
10796 }
10797 .cm-s-ipython span.cm-number {
10798   color: #080;
10799 }
10800 .cm-s-ipython span.cm-def {
10801   color: #00f;
10802 }
10803 .cm-s-ipython span.cm-variable {
10804   color: #000;
10805 }
10806 .cm-s-ipython span.cm-operator {
10807   color: #AA22FF;
10808   font-weight: bold;
10809 }
10810 .cm-s-ipython span.cm-variable-2 {
10811   color: #1a1a1a;
10812 }
10813 .cm-s-ipython span.cm-variable-3 {
10814   color: #333333;
10815 }
10816 .cm-s-ipython span.cm-comment {
10817   color: #408080;
10818   font-style: italic;
10819 }
10820 .cm-s-ipython span.cm-string {
10821   color: #BA2121;
10822 }
10823 .cm-s-ipython span.cm-string-2 {
10824   color: #f50;
10825 }
10826 .cm-s-ipython span.cm-meta {
10827   color: #AA22FF;
10828 }
10829 .cm-s-ipython span.cm-qualifier {
10830   color: #555;
10831 }
10832 .cm-s-ipython span.cm-builtin {
10833   color: #008000;
10834 }
10835 .cm-s-ipython span.cm-bracket {
10836   color: #997;
10837 }
10838 .cm-s-ipython span.cm-tag {
10839   color: #170;
10840 }
10841 .cm-s-ipython span.cm-attribute {
10842   color: #00c;
10843 }
10844 .cm-s-ipython span.cm-header {
10845   color: blue;
10846 }
10847 .cm-s-ipython span.cm-quote {
10848   color: #090;
10849 }
10850 .cm-s-ipython span.cm-link {
10851   color: #00c;
10852 }
10853 .cm-s-ipython span.cm-error {
10854   color: #f00;
10855 }
10856 .cm-s-ipython span.cm-tab {
10857   background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
10858   background-position: right;
10859   background-repeat: no-repeat;
10860 }
10861 div.output_wrapper {
10862   /* this position must be relative to enable descendents to be absolute within it */
10863   position: relative;
10864   /* Old browsers */
10865   display: -webkit-box;
10866   -webkit-box-orient: vertical;
10867   -webkit-box-align: stretch;
10868   display: -moz-box;
10869   -moz-box-orient: vertical;
10870   -moz-box-align: stretch;
10871   display: box;
10872   box-orient: vertical;
10873   box-align: stretch;
10874   /* Modern browsers */
10875   display: flex;
10876   flex-direction: column;
10877   align-items: stretch;
10878   z-index: 1;
10879 }
10880 /* class for the output area when it should be height-limited */
10881 div.output_scroll {
10882   /* ideally, this would be max-height, but FF barfs all over that */
10883   height: 24em;
10884   /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
10885   width: 100%;
10886   overflow: auto;
10887   border-radius: 2px;
10888   -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
10889   box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
10890   display: block;
10891 }
10892 /* output div while it is collapsed */
10893 div.output_collapsed {
10894   margin: 0px;
10895   padding: 0px;
10896   /* Old browsers */
10897   display: -webkit-box;
10898   -webkit-box-orient: vertical;
10899   -webkit-box-align: stretch;
10900   display: -moz-box;
10901   -moz-box-orient: vertical;
10902   -moz-box-align: stretch;
10903   display: box;
10904   box-orient: vertical;
10905   box-align: stretch;
10906   /* Modern browsers */
10907   display: flex;
10908   flex-direction: column;
10909   align-items: stretch;
10910 }
10911 div.out_prompt_overlay {
10912   height: 100%;
10913   padding: 0px 0.4em;
10914   position: absolute;
10915   border-radius: 2px;
10916 }
10917 div.out_prompt_overlay:hover {
10918   /* use inner shadow to get border that is computed the same on WebKit/FF */
10919   -webkit-box-shadow: inset 0 0 1px #000;
10920   box-shadow: inset 0 0 1px #000;
10921   background: rgba(240, 240, 240, 0.5);
10922 }
10923 div.output_prompt {
10924   color: #D84315;
10925 }
10926 /* This class is the outer container of all output sections. */
10927 div.output_area {
10928   padding: 0px;
10929   page-break-inside: avoid;
10930   /* Old browsers */
10931   display: -webkit-box;
10932   -webkit-box-orient: horizontal;
10933   -webkit-box-align: stretch;
10934   display: -moz-box;
10935   -moz-box-orient: horizontal;
10936   -moz-box-align: stretch;
10937   display: box;
10938   box-orient: horizontal;
10939   box-align: stretch;
10940   /* Modern browsers */
10941   display: flex;
10942   flex-direction: row;
10943   align-items: stretch;
10944 }
10945 div.output_area .MathJax_Display {
10946   text-align: left !important;
10947 }
10948 div.output_area .rendered_html table {
10949   margin-left: 0;
10950   margin-right: 0;
10951 }
10952 div.output_area .rendered_html img {
10953   margin-left: 0;
10954   margin-right: 0;
10955 }
10956 div.output_area img,
10957 div.output_area svg {
10958   max-width: 100%;
10959   height: auto;
10960 }
10961 div.output_area img.unconfined,
10962 div.output_area svg.unconfined {
10963   max-width: none;
10964 }
10965 div.output_area .mglyph > img {
10966   max-width: none;
10967 }
10968 /* This is needed to protect the pre formating from global settings such
10969    as that of bootstrap */
10970 .output {
10971   /* Old browsers */
10972   display: -webkit-box;
10973   -webkit-box-orient: vertical;
10974   -webkit-box-align: stretch;
10975   display: -moz-box;
10976   -moz-box-orient: vertical;
10977   -moz-box-align: stretch;
10978   display: box;
10979   box-orient: vertical;
10980   box-align: stretch;
10981   /* Modern browsers */
10982   display: flex;
10983   flex-direction: column;
10984   align-items: stretch;
10985 }
10986 @media (max-width: 540px) {
10987   div.output_area {
10988     /* Old browsers */
10989     display: -webkit-box;
10990     -webkit-box-orient: vertical;
10991     -webkit-box-align: stretch;
10992     display: -moz-box;
10993     -moz-box-orient: vertical;
10994     -moz-box-align: stretch;
10995     display: box;
10996     box-orient: vertical;
10997     box-align: stretch;
10998     /* Modern browsers */
10999     display: flex;
11000     flex-direction: column;
11001     align-items: stretch;
11002   }
11003 }
11004 div.output_area pre {
11005   margin: 0;
11006   padding: 1px 0 1px 0;
11007   border: 0;
11008   vertical-align: baseline;
11009   color: black;
11010   background-color: transparent;
11011   border-radius: 0;
11012 }
11013 /* This class is for the output subarea inside the output_area and after
11014    the prompt div. */
11015 div.output_subarea {
11016   overflow-x: auto;
11017   padding: 0.4em;
11018   /* Old browsers */
11019   -webkit-box-flex: 1;
11020   -moz-box-flex: 1;
11021   box-flex: 1;
11022   /* Modern browsers */
11023   flex: 1;
11024   max-width: calc(100% - 14ex);
11025 }
11026 div.output_scroll div.output_subarea {
11027   overflow-x: visible;
11028 }
11029 /* The rest of the output_* classes are for special styling of the different
11030    output types */
11031 /* all text output has this class: */
11032 div.output_text {
11033   text-align: left;
11034   color: #000;
11035   /* This has to match that of the the CodeMirror class line-height below */
11036   line-height: 1.21429em;
11037 }
11038 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
11039 div.output_stderr {
11040   background: #fdd;
11041   /* very light red background for stderr */
11042 }
11043 div.output_latex {
11044   text-align: left;
11045 }
11046 /* Empty output_javascript divs should have no height */
11047 div.output_javascript:empty {
11048   padding: 0;
11049 }
11050 .js-error {
11051   color: darkred;
11052 }
11053 /* raw_input styles */
11054 div.raw_input_container {
11055   line-height: 1.21429em;
11056   padding-top: 5px;
11057 }
11058 pre.raw_input_prompt {
11059   /* nothing needed here. */
11060 }
11061 input.raw_input {
11062   font-family: monospace;
11063   font-size: inherit;
11064   color: inherit;
11065   width: auto;
11066   /* make sure input baseline aligns with prompt */
11067   vertical-align: baseline;
11068   /* padding + margin = 0.5em between prompt and cursor */
11069   padding: 0em 0.25em;
11070   margin: 0em 0.25em;
11071 }
11072 input.raw_input:focus {
11073   box-shadow: none;
11074 }
11075 p.p-space {
11076   margin-bottom: 10px;
11077 }
11078 div.output_unrecognized {
11079   padding: 5px;
11080   font-weight: bold;
11081   color: red;
11082 }
11083 div.output_unrecognized a {
11084   color: inherit;
11085   text-decoration: none;
11086 }
11087 div.output_unrecognized a:hover {
11088   color: inherit;
11089   text-decoration: none;
11090 }
11091 .rendered_html {
11092   color: #000;
11093   /* any extras will just be numbers: */
11094 }
11095 .rendered_html em {
11096   font-style: italic;
11097 }
11098 .rendered_html strong {
11099   font-weight: bold;
11100 }
11101 .rendered_html u {
11102   text-decoration: underline;
11103 }
11104 .rendered_html :link {
11105   text-decoration: underline;
11106 }
11107 .rendered_html :visited {
11108   text-decoration: underline;
11109 }
11110 .rendered_html h1 {
11111   font-size: 185.7%;
11112   margin: 1.08em 0 0 0;
11113   font-weight: bold;
11114   line-height: 1.0;
11115 }
11116 .rendered_html h2 {
11117   font-size: 157.1%;
11118   margin: 1.27em 0 0 0;
11119   font-weight: bold;
11120   line-height: 1.0;
11121 }
11122 .rendered_html h3 {
11123   font-size: 128.6%;
11124   margin: 1.55em 0 0 0;
11125   font-weight: bold;
11126   line-height: 1.0;
11127 }
11128 .rendered_html h4 {
11129   font-size: 100%;
11130   margin: 2em 0 0 0;
11131   font-weight: bold;
11132   line-height: 1.0;
11133 }
11134 .rendered_html h5 {
11135   font-size: 100%;
11136   margin: 2em 0 0 0;
11137   font-weight: bold;
11138   line-height: 1.0;
11139   font-style: italic;
11140 }
11141 .rendered_html h6 {
11142   font-size: 100%;
11143   margin: 2em 0 0 0;
11144   font-weight: bold;
11145   line-height: 1.0;
11146   font-style: italic;
11147 }
11148 .rendered_html h1:first-child {
11149   margin-top: 0.538em;
11150 }
11151 .rendered_html h2:first-child {
11152   margin-top: 0.636em;
11153 }
11154 .rendered_html h3:first-child {
11155   margin-top: 0.777em;
11156 }
11157 .rendered_html h4:first-child {
11158   margin-top: 1em;
11159 }
11160 .rendered_html h5:first-child {
11161   margin-top: 1em;
11162 }
11163 .rendered_html h6:first-child {
11164   margin-top: 1em;
11165 }
11166 .rendered_html ul:not(.list-inline),
11167 .rendered_html ol:not(.list-inline) {
11168   padding-left: 2em;
11169 }
11170 .rendered_html ul {
11171   list-style: disc;
11172 }
11173 .rendered_html ul ul {
11174   list-style: square;
11175   margin-top: 0;
11176 }
11177 .rendered_html ul ul ul {
11178   list-style: circle;
11179 }
11180 .rendered_html ol {
11181   list-style: decimal;
11182 }
11183 .rendered_html ol ol {
11184   list-style: upper-alpha;
11185   margin-top: 0;
11186 }
11187 .rendered_html ol ol ol {
11188   list-style: lower-alpha;
11189 }
11190 .rendered_html ol ol ol ol {
11191   list-style: lower-roman;
11192 }
11193 .rendered_html ol ol ol ol ol {
11194   list-style: decimal;
11195 }
11196 .rendered_html * + ul {
11197   margin-top: 1em;
11198 }
11199 .rendered_html * + ol {
11200   margin-top: 1em;
11201 }
11202 .rendered_html hr {
11203   color: black;
11204   background-color: black;
11205 }
11206 .rendered_html pre {
11207   margin: 1em 2em;
11208   padding: 0px;
11209   background-color: #fff;
11210 }
11211 .rendered_html code {
11212   background-color: #eff0f1;
11213 }
11214 .rendered_html p code {
11215   padding: 1px 5px;
11216 }
11217 .rendered_html pre code {
11218   background-color: #fff;
11219 }
11220 .rendered_html pre,
11221 .rendered_html code {
11222   border: 0;
11223   color: #000;
11224   font-size: 100%;
11225 }
11226 .rendered_html blockquote {
11227   margin: 1em 2em;
11228 }
11229 .rendered_html table {
11230   margin-left: auto;
11231   margin-right: auto;
11232   border: none;
11233   border-collapse: collapse;
11234   border-spacing: 0;
11235   color: black;
11236   font-size: 12px;
11237   table-layout: fixed;
11238 }
11239 .rendered_html thead {
11240   border-bottom: 1px solid black;
11241   vertical-align: bottom;
11242 }
11243 .rendered_html tr,
11244 .rendered_html th,
11245 .rendered_html td {
11246   text-align: right;
11247   vertical-align: middle;
11248   padding: 0.5em 0.5em;
11249   line-height: normal;
11250   white-space: normal;
11251   max-width: none;
11252   border: none;
11253 }
11254 .rendered_html th {
11255   font-weight: bold;
11256 }
11257 .rendered_html tbody tr:nth-child(odd) {
11258   background: #f5f5f5;
11259 }
11260 .rendered_html tbody tr:hover {
11261   background: rgba(66, 165, 245, 0.2);
11262 }
11263 .rendered_html * + table {
11264   margin-top: 1em;
11265 }
11266 .rendered_html p {
11267   text-align: left;
11268 }
11269 .rendered_html * + p {
11270   margin-top: 1em;
11271 }
11272 .rendered_html img {
11273   display: block;
11274   margin-left: auto;
11275   margin-right: auto;
11276 }
11277 .rendered_html * + img {
11278   margin-top: 1em;
11279 }
11280 .rendered_html img,
11281 .rendered_html svg {
11282   max-width: 100%;
11283   height: auto;
11284 }
11285 .rendered_html img.unconfined,
11286 .rendered_html svg.unconfined {
11287   max-width: none;
11288 }
11289 .rendered_html .alert {
11290   margin-bottom: initial;
11291 }
11292 .rendered_html * + .alert {
11293   margin-top: 1em;
11294 }
11295 [dir="rtl"] .rendered_html p {
11296   text-align: right;
11297 }
11298 div.text_cell {
11299   /* Old browsers */
11300   display: -webkit-box;
11301   -webkit-box-orient: horizontal;
11302   -webkit-box-align: stretch;
11303   display: -moz-box;
11304   -moz-box-orient: horizontal;
11305   -moz-box-align: stretch;
11306   display: box;
11307   box-orient: horizontal;
11308   box-align: stretch;
11309   /* Modern browsers */
11310   display: flex;
11311   flex-direction: row;
11312   align-items: stretch;
11313 }
11314 @media (max-width: 540px) {
11315   div.text_cell > div.prompt {
11316     display: none;
11317   }
11318 }
11319 div.text_cell_render {
11320   /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
11321   outline: none;
11322   resize: none;
11323   width: inherit;
11324   border-style: none;
11325   padding: 0.5em 0.5em 0.5em 0.4em;
11326   color: #000;
11327   box-sizing: border-box;
11328   -moz-box-sizing: border-box;
11329   -webkit-box-sizing: border-box;
11330 }
11331 a.anchor-link:link {
11332   text-decoration: none;
11333   padding: 0px 20px;
11334   visibility: hidden;
11335 }
11336 h1:hover .anchor-link,
11337 h2:hover .anchor-link,
11338 h3:hover .anchor-link,
11339 h4:hover .anchor-link,
11340 h5:hover .anchor-link,
11341 h6:hover .anchor-link {
11342   visibility: visible;
11343 }
11344 .text_cell.rendered .input_area {
11345   display: none;
11346 }
11347 .text_cell.rendered .rendered_html {
11348   overflow-x: auto;
11349   overflow-y: hidden;
11350 }
11351 .text_cell.rendered .rendered_html tr,
11352 .text_cell.rendered .rendered_html th,
11353 .text_cell.rendered .rendered_html td {
11354   max-width: none;
11355 }
11356 .text_cell.unrendered .text_cell_render {
11357   display: none;
11358 }
11359 .text_cell .dropzone .input_area {
11360   border: 2px dashed #bababa;
11361   margin: -1px;
11362 }
11363 .cm-header-1,
11364 .cm-header-2,
11365 .cm-header-3,
11366 .cm-header-4,
11367 .cm-header-5,
11368 .cm-header-6 {
11369   font-weight: bold;
11370   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
11371 }
11372 .cm-header-1 {
11373   font-size: 185.7%;
11374 }
11375 .cm-header-2 {
11376   font-size: 157.1%;
11377 }
11378 .cm-header-3 {
11379   font-size: 128.6%;
11380 }
11381 .cm-header-4 {
11382   font-size: 110%;
11383 }
11384 .cm-header-5 {
11385   font-size: 100%;
11386   font-style: italic;
11387 }
11388 .cm-header-6 {
11389   font-size: 100%;
11390   font-style: italic;
11391 }
11392 /*!
11393 *
11394 * IPython notebook webapp
11395 *
11396 */
11397 @media (max-width: 767px) {
11398   .notebook_app {
11399     padding-left: 0px;
11400     padding-right: 0px;
11401   }
11402 }
11403 #ipython-main-app {
11404   box-sizing: border-box;
11405   -moz-box-sizing: border-box;
11406   -webkit-box-sizing: border-box;
11407   height: 100%;
11408 }
11409 div#notebook_panel {
11410   margin: 0px;
11411   padding: 0px;
11412   box-sizing: border-box;
11413   -moz-box-sizing: border-box;
11414   -webkit-box-sizing: border-box;
11415   height: 100%;
11416 }
11417 div#notebook {
11418   font-size: 14px;
11419   line-height: 20px;
11420   overflow-y: hidden;
11421   overflow-x: auto;
11422   width: 100%;
11423   /* This spaces the page away from the edge of the notebook area */
11424   padding-top: 20px;
11425   margin: 0px;
11426   outline: none;
11427   box-sizing: border-box;
11428   -moz-box-sizing: border-box;
11429   -webkit-box-sizing: border-box;
11430   min-height: 100%;
11431 }
11432 @media not print {
11433   #notebook-container {
11434     padding: 15px;
11435     background-color: #fff;
11436     min-height: 0;
11437     -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11438     box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11439   }
11440 }
11441 @media print {
11442   #notebook-container {
11443     width: 100%;
11444   }
11445 }
11446 div.ui-widget-content {
11447   border: 1px solid #ababab;
11448   outline: none;
11449 }
11450 pre.dialog {
11451   background-color: #f7f7f7;
11452   border: 1px solid #ddd;
11453   border-radius: 2px;
11454   padding: 0.4em;
11455   padding-left: 2em;
11456 }
11457 p.dialog {
11458   padding: 0.2em;
11459 }
11460 /* Word-wrap output correctly.  This is the CSS3 spelling, though Firefox seems
11461    to not honor it correctly.  Webkit browsers (Chrome, rekonq, Safari) do.
11462  */
11463 pre,
11464 code,
11465 kbd,
11466 samp {
11467   white-space: pre-wrap;
11468 }
11469 #fonttest {
11470   font-family: monospace;
11471 }
11472 p {
11473   margin-bottom: 0;
11474 }
11475 .end_space {
11476   min-height: 100px;
11477   transition: height .2s ease;
11478 }
11479 .notebook_app > #header {
11480   -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11481   box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11482 }
11483 @media not print {
11484   .notebook_app {
11485     background-color: #EEE;
11486   }
11487 }
11488 kbd {
11489   border-style: solid;
11490   border-width: 1px;
11491   box-shadow: none;
11492   margin: 2px;
11493   padding-left: 2px;
11494   padding-right: 2px;
11495   padding-top: 1px;
11496   padding-bottom: 1px;
11497 }
11498 .jupyter-keybindings {
11499   padding: 1px;
11500   line-height: 24px;
11501   border-bottom: 1px solid gray;
11502 }
11503 .jupyter-keybindings input {
11504   margin: 0;
11505   padding: 0;
11506   border: none;
11507 }
11508 .jupyter-keybindings i {
11509   padding: 6px;
11510 }
11511 .well code {
11512   background-color: #ffffff;
11513   border-color: #ababab;
11514   border-width: 1px;
11515   border-style: solid;
11516   padding: 2px;
11517   padding-top: 1px;
11518   padding-bottom: 1px;
11519 }
11520 /* CSS for the cell toolbar */
11521 .celltoolbar {
11522   border: thin solid #CFCFCF;
11523   border-bottom: none;
11524   background: #EEE;
11525   border-radius: 2px 2px 0px 0px;
11526   width: 100%;
11527   height: 29px;
11528   padding-right: 4px;
11529   /* Old browsers */
11530   display: -webkit-box;
11531   -webkit-box-orient: horizontal;
11532   -webkit-box-align: stretch;
11533   display: -moz-box;
11534   -moz-box-orient: horizontal;
11535   -moz-box-align: stretch;
11536   display: box;
11537   box-orient: horizontal;
11538   box-align: stretch;
11539   /* Modern browsers */
11540   display: flex;
11541   flex-direction: row;
11542   align-items: stretch;
11543   /* Old browsers */
11544   -webkit-box-pack: end;
11545   -moz-box-pack: end;
11546   box-pack: end;
11547   /* Modern browsers */
11548   justify-content: flex-end;
11549   display: -webkit-flex;
11550 }
11551 @media print {
11552   .celltoolbar {
11553     display: none;
11554   }
11555 }
11556 .ctb_hideshow {
11557   display: none;
11558   vertical-align: bottom;
11559 }
11560 /* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
11561    Cell toolbars are only shown when the ctb_global_show class is also set.
11562 */
11563 .ctb_global_show .ctb_show.ctb_hideshow {
11564   display: block;
11565 }
11566 .ctb_global_show .ctb_show + .input_area,
11567 .ctb_global_show .ctb_show + div.text_cell_input,
11568 .ctb_global_show .ctb_show ~ div.text_cell_render {
11569   border-top-right-radius: 0px;
11570   border-top-left-radius: 0px;
11571 }
11572 .ctb_global_show .ctb_show ~ div.text_cell_render {
11573   border: 1px solid #cfcfcf;
11574 }
11575 .celltoolbar {
11576   font-size: 87%;
11577   padding-top: 3px;
11578 }
11579 .celltoolbar select {
11580   display: block;
11581   width: 100%;
11582   height: 32px;
11583   padding: 6px 12px;
11584   font-size: 13px;
11585   line-height: 1.42857143;
11586   color: #555555;
11587   background-color: #fff;
11588   background-image: none;
11589   border: 1px solid #ccc;
11590   border-radius: 2px;
11591   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11592   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11593   -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11594   -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11595   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11596   height: 30px;
11597   padding: 5px 10px;
11598   font-size: 12px;
11599   line-height: 1.5;
11600   border-radius: 1px;
11601   width: inherit;
11602   font-size: inherit;
11603   height: 22px;
11604   padding: 0px;
11605   display: inline-block;
11606 }
11607 .celltoolbar select:focus {
11608   border-color: #66afe9;
11609   outline: 0;
11610   -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11611   box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11612 }
11613 .celltoolbar select::-moz-placeholder {
11614   color: #999;
11615   opacity: 1;
11616 }
11617 .celltoolbar select:-ms-input-placeholder {
11618   color: #999;
11619 }
11620 .celltoolbar select::-webkit-input-placeholder {
11621   color: #999;
11622 }
11623 .celltoolbar select::-ms-expand {
11624   border: 0;
11625   background-color: transparent;
11626 }
11627 .celltoolbar select[disabled],
11628 .celltoolbar select[readonly],
11629 fieldset[disabled] .celltoolbar select {
11630   background-color: #eeeeee;
11631   opacity: 1;
11632 }
11633 .celltoolbar select[disabled],
11634 fieldset[disabled] .celltoolbar select {
11635   cursor: not-allowed;
11636 }
11637 textarea.celltoolbar select {
11638   height: auto;
11639 }
11640 select.celltoolbar select {
11641   height: 30px;
11642   line-height: 30px;
11643 }
11644 textarea.celltoolbar select,
11645 select[multiple].celltoolbar select {
11646   height: auto;
11647 }
11648 .celltoolbar label {
11649   margin-left: 5px;
11650   margin-right: 5px;
11651 }
11652 .tags_button_container {
11653   width: 100%;
11654   display: flex;
11655 }
11656 .tag-container {
11657   display: flex;
11658   flex-direction: row;
11659   flex-grow: 1;
11660   overflow: hidden;
11661   position: relative;
11662 }
11663 .tag-container > * {
11664   margin: 0 4px;
11665 }
11666 .remove-tag-btn {
11667   margin-left: 4px;
11668 }
11669 .tags-input {
11670   display: flex;
11671 }
11672 .cell-tag:last-child:after {
11673   content: "";
11674   position: absolute;
11675   right: 0;
11676   width: 40px;
11677   height: 100%;
11678   /* Fade to background color of cell toolbar */
11679   background: linear-gradient(to right, rgba(0, 0, 0, 0), #EEE);
11680 }
11681 .tags-input > * {
11682   margin-left: 4px;
11683 }
11684 .cell-tag,
11685 .tags-input input,
11686 .tags-input button {
11687   display: block;
11688   width: 100%;
11689   height: 32px;
11690   padding: 6px 12px;
11691   font-size: 13px;
11692   line-height: 1.42857143;
11693   color: #555555;
11694   background-color: #fff;
11695   background-image: none;
11696   border: 1px solid #ccc;
11697   border-radius: 2px;
11698   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11699   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11700   -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11701   -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11702   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11703   height: 30px;
11704   padding: 5px 10px;
11705   font-size: 12px;
11706   line-height: 1.5;
11707   border-radius: 1px;
11708   box-shadow: none;
11709   width: inherit;
11710   font-size: inherit;
11711   height: 22px;
11712   line-height: 22px;
11713   padding: 0px 4px;
11714   display: inline-block;
11715 }
11716 .cell-tag:focus,
11717 .tags-input input:focus,
11718 .tags-input button:focus {
11719   border-color: #66afe9;
11720   outline: 0;
11721   -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11722   box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11723 }
11724 .cell-tag::-moz-placeholder,
11725 .tags-input input::-moz-placeholder,
11726 .tags-input button::-moz-placeholder {
11727   color: #999;
11728   opacity: 1;
11729 }
11730 .cell-tag:-ms-input-placeholder,
11731 .tags-input input:-ms-input-placeholder,
11732 .tags-input button:-ms-input-placeholder {
11733   color: #999;
11734 }
11735 .cell-tag::-webkit-input-placeholder,
11736 .tags-input input::-webkit-input-placeholder,
11737 .tags-input button::-webkit-input-placeholder {
11738   color: #999;
11739 }
11740 .cell-tag::-ms-expand,
11741 .tags-input input::-ms-expand,
11742 .tags-input button::-ms-expand {
11743   border: 0;
11744   background-color: transparent;
11745 }
11746 .cell-tag[disabled],
11747 .tags-input input[disabled],
11748 .tags-input button[disabled],
11749 .cell-tag[readonly],
11750 .tags-input input[readonly],
11751 .tags-input button[readonly],
11752 fieldset[disabled] .cell-tag,
11753 fieldset[disabled] .tags-input input,
11754 fieldset[disabled] .tags-input button {
11755   background-color: #eeeeee;
11756   opacity: 1;
11757 }
11758 .cell-tag[disabled],
11759 .tags-input input[disabled],
11760 .tags-input button[disabled],
11761 fieldset[disabled] .cell-tag,
11762 fieldset[disabled] .tags-input input,
11763 fieldset[disabled] .tags-input button {
11764   cursor: not-allowed;
11765 }
11766 textarea.cell-tag,
11767 textarea.tags-input input,
11768 textarea.tags-input button {
11769   height: auto;
11770 }
11771 select.cell-tag,
11772 select.tags-input input,
11773 select.tags-input button {
11774   height: 30px;
11775   line-height: 30px;
11776 }
11777 textarea.cell-tag,
11778 textarea.tags-input input,
11779 textarea.tags-input button,
11780 select[multiple].cell-tag,
11781 select[multiple].tags-input input,
11782 select[multiple].tags-input button {
11783   height: auto;
11784 }
11785 .cell-tag,
11786 .tags-input button {
11787   padding: 0px 4px;
11788 }
11789 .cell-tag {
11790   background-color: #fff;
11791   white-space: nowrap;
11792 }
11793 .tags-input input[type=text]:focus {
11794   outline: none;
11795   box-shadow: none;
11796   border-color: #ccc;
11797 }
11798 .completions {
11799   position: absolute;
11800   z-index: 110;
11801   overflow: hidden;
11802   border: 1px solid #ababab;
11803   border-radius: 2px;
11804   -webkit-box-shadow: 0px 6px 10px -1px #adadad;
11805   box-shadow: 0px 6px 10px -1px #adadad;
11806   line-height: 1;
11807 }
11808 .completions select {
11809   background: white;
11810   outline: none;
11811   border: none;
11812   padding: 0px;
11813   margin: 0px;
11814   overflow: auto;
11815   font-family: monospace;
11816   font-size: 110%;
11817   color: #000;
11818   width: auto;
11819 }
11820 .completions select option.context {
11821   color: #286090;
11822 }
11823 #kernel_logo_widget .current_kernel_logo {
11824   display: none;
11825   margin-top: -1px;
11826   margin-bottom: -1px;
11827   width: 32px;
11828   height: 32px;
11829 }
11830 [dir="rtl"] #kernel_logo_widget {
11831   float: left !important;
11832   float: left;
11833 }
11834 .modal .modal-body .move-path {
11835   display: flex;
11836   flex-direction: row;
11837   justify-content: space;
11838   align-items: center;
11839 }
11840 .modal .modal-body .move-path .server-root {
11841   padding-right: 20px;
11842 }
11843 .modal .modal-body .move-path .path-input {
11844   flex: 1;
11845 }
11846 #menubar {
11847   box-sizing: border-box;
11848   -moz-box-sizing: border-box;
11849   -webkit-box-sizing: border-box;
11850   margin-top: 1px;
11851 }
11852 #menubar .navbar {
11853   border-top: 1px;
11854   border-radius: 0px 0px 2px 2px;
11855   margin-bottom: 0px;
11856 }
11857 #menubar .navbar-toggle {
11858   float: left;
11859   padding-top: 7px;
11860   padding-bottom: 7px;
11861   border: none;
11862 }
11863 #menubar .navbar-collapse {
11864   clear: left;
11865 }
11866 [dir="rtl"] #menubar .navbar-toggle {
11867   float: right;
11868 }
11869 [dir="rtl"] #menubar .navbar-collapse {
11870   clear: right;
11871 }
11872 [dir="rtl"] #menubar .navbar-nav {
11873   float: right;
11874 }
11875 [dir="rtl"] #menubar .nav {
11876   padding-right: 0px;
11877 }
11878 [dir="rtl"] #menubar .navbar-nav > li {
11879   float: right;
11880 }
11881 [dir="rtl"] #menubar .navbar-right {
11882   float: left !important;
11883 }
11884 [dir="rtl"] ul.dropdown-menu {
11885   text-align: right;
11886   left: auto;
11887 }
11888 [dir="rtl"] ul#new-menu.dropdown-menu {
11889   right: auto;
11890   left: 0;
11891 }
11892 .nav-wrapper {
11893   border-bottom: 1px solid #e7e7e7;
11894 }
11895 i.menu-icon {
11896   padding-top: 4px;
11897 }
11898 [dir="rtl"] i.menu-icon.pull-right {
11899   float: left !important;
11900   float: left;
11901 }
11902 ul#help_menu li a {
11903   overflow: hidden;
11904   padding-right: 2.2em;
11905 }
11906 ul#help_menu li a i {
11907   margin-right: -1.2em;
11908 }
11909 [dir="rtl"] ul#help_menu li a {
11910   padding-left: 2.2em;
11911 }
11912 [dir="rtl"] ul#help_menu li a i {
11913   margin-right: 0;
11914   margin-left: -1.2em;
11915 }
11916 [dir="rtl"] ul#help_menu li a i.pull-right {
11917   float: left !important;
11918   float: left;
11919 }
11920 .dropdown-submenu {
11921   position: relative;
11922 }
11923 .dropdown-submenu > .dropdown-menu {
11924   top: 0;
11925   left: 100%;
11926   margin-top: -6px;
11927   margin-left: -1px;
11928 }
11929 [dir="rtl"] .dropdown-submenu > .dropdown-menu {
11930   right: 100%;
11931   margin-right: -1px;
11932 }
11933 .dropdown-submenu:hover > .dropdown-menu {
11934   display: block;
11935 }
11936 .dropdown-submenu > a:after {
11937   display: inline-block;
11938   font: normal normal normal 14px/1 FontAwesome;
11939   font-size: inherit;
11940   text-rendering: auto;
11941   -webkit-font-smoothing: antialiased;
11942   -moz-osx-font-smoothing: grayscale;
11943   display: block;
11944   content: "\f0da";
11945   float: right;
11946   color: #333333;
11947   margin-top: 2px;
11948   margin-right: -10px;
11949 }
11950 .dropdown-submenu > a:after.fa-pull-left {
11951   margin-right: .3em;
11952 }
11953 .dropdown-submenu > a:after.fa-pull-right {
11954   margin-left: .3em;
11955 }
11956 .dropdown-submenu > a:after.pull-left {
11957   margin-right: .3em;
11958 }
11959 .dropdown-submenu > a:after.pull-right {
11960   margin-left: .3em;
11961 }
11962 [dir="rtl"] .dropdown-submenu > a:after {
11963   float: left;
11964   content: "\f0d9";
11965   margin-right: 0;
11966   margin-left: -10px;
11967 }
11968 .dropdown-submenu:hover > a:after {
11969   color: #262626;
11970 }
11971 .dropdown-submenu.pull-left {
11972   float: none;
11973 }
11974 .dropdown-submenu.pull-left > .dropdown-menu {
11975   left: -100%;
11976   margin-left: 10px;
11977 }
11978 #notification_area {
11979   float: right !important;
11980   float: right;
11981   z-index: 10;
11982 }
11983 [dir="rtl"] #notification_area {
11984   float: left !important;
11985   float: left;
11986 }
11987 .indicator_area {
11988   float: right !important;
11989   float: right;
11990   color: #777;
11991   margin-left: 5px;
11992   margin-right: 5px;
11993   width: 11px;
11994   z-index: 10;
11995   text-align: center;
11996   width: auto;
11997 }
11998 [dir="rtl"] .indicator_area {
11999   float: left !important;
12000   float: left;
12001 }
12002 #kernel_indicator {
12003   float: right !important;
12004   float: right;
12005   color: #777;
12006   margin-left: 5px;
12007   margin-right: 5px;
12008   width: 11px;
12009   z-index: 10;
12010   text-align: center;
12011   width: auto;
12012   border-left: 1px solid;
12013 }
12014 #kernel_indicator .kernel_indicator_name {
12015   padding-left: 5px;
12016   padding-right: 5px;
12017 }
12018 [dir="rtl"] #kernel_indicator {
12019   float: left !important;
12020   float: left;
12021   border-left: 0;
12022   border-right: 1px solid;
12023 }
12024 #modal_indicator {
12025   float: right !important;
12026   float: right;
12027   color: #777;
12028   margin-left: 5px;
12029   margin-right: 5px;
12030   width: 11px;
12031   z-index: 10;
12032   text-align: center;
12033   width: auto;
12034 }
12035 [dir="rtl"] #modal_indicator {
12036   float: left !important;
12037   float: left;
12038 }
12039 #readonly-indicator {
12040   float: right !important;
12041   float: right;
12042   color: #777;
12043   margin-left: 5px;
12044   margin-right: 5px;
12045   width: 11px;
12046   z-index: 10;
12047   text-align: center;
12048   width: auto;
12049   margin-top: 2px;
12050   margin-bottom: 0px;
12051   margin-left: 0px;
12052   margin-right: 0px;
12053   display: none;
12054 }
12055 .modal_indicator:before {
12056   width: 1.28571429em;
12057   text-align: center;
12058 }
12059 .edit_mode .modal_indicator:before {
12060   display: inline-block;
12061   font: normal normal normal 14px/1 FontAwesome;
12062   font-size: inherit;
12063   text-rendering: auto;
12064   -webkit-font-smoothing: antialiased;
12065   -moz-osx-font-smoothing: grayscale;
12066   content: "\f040";
12067 }
12068 .edit_mode .modal_indicator:before.fa-pull-left {
12069   margin-right: .3em;
12070 }
12071 .edit_mode .modal_indicator:before.fa-pull-right {
12072   margin-left: .3em;
12073 }
12074 .edit_mode .modal_indicator:before.pull-left {
12075   margin-right: .3em;
12076 }
12077 .edit_mode .modal_indicator:before.pull-right {
12078   margin-left: .3em;
12079 }
12080 .command_mode .modal_indicator:before {
12081   display: inline-block;
12082   font: normal normal normal 14px/1 FontAwesome;
12083   font-size: inherit;
12084   text-rendering: auto;
12085   -webkit-font-smoothing: antialiased;
12086   -moz-osx-font-smoothing: grayscale;
12087   content: ' ';
12088 }
12089 .command_mode .modal_indicator:before.fa-pull-left {
12090   margin-right: .3em;
12091 }
12092 .command_mode .modal_indicator:before.fa-pull-right {
12093   margin-left: .3em;
12094 }
12095 .command_mode .modal_indicator:before.pull-left {
12096   margin-right: .3em;
12097 }
12098 .command_mode .modal_indicator:before.pull-right {
12099   margin-left: .3em;
12100 }
12101 .kernel_idle_icon:before {
12102   display: inline-block;
12103   font: normal normal normal 14px/1 FontAwesome;
12104   font-size: inherit;
12105   text-rendering: auto;
12106   -webkit-font-smoothing: antialiased;
12107   -moz-osx-font-smoothing: grayscale;
12108   content: "\f10c";
12109 }
12110 .kernel_idle_icon:before.fa-pull-left {
12111   margin-right: .3em;
12112 }
12113 .kernel_idle_icon:before.fa-pull-right {
12114   margin-left: .3em;
12115 }
12116 .kernel_idle_icon:before.pull-left {
12117   margin-right: .3em;
12118 }
12119 .kernel_idle_icon:before.pull-right {
12120   margin-left: .3em;
12121 }
12122 .kernel_busy_icon:before {
12123   display: inline-block;
12124   font: normal normal normal 14px/1 FontAwesome;
12125   font-size: inherit;
12126   text-rendering: auto;
12127   -webkit-font-smoothing: antialiased;
12128   -moz-osx-font-smoothing: grayscale;
12129   content: "\f111";
12130 }
12131 .kernel_busy_icon:before.fa-pull-left {
12132   margin-right: .3em;
12133 }
12134 .kernel_busy_icon:before.fa-pull-right {
12135   margin-left: .3em;
12136 }
12137 .kernel_busy_icon:before.pull-left {
12138   margin-right: .3em;
12139 }
12140 .kernel_busy_icon:before.pull-right {
12141   margin-left: .3em;
12142 }
12143 .kernel_dead_icon:before {
12144   display: inline-block;
12145   font: normal normal normal 14px/1 FontAwesome;
12146   font-size: inherit;
12147   text-rendering: auto;
12148   -webkit-font-smoothing: antialiased;
12149   -moz-osx-font-smoothing: grayscale;
12150   content: "\f1e2";
12151 }
12152 .kernel_dead_icon:before.fa-pull-left {
12153   margin-right: .3em;
12154 }
12155 .kernel_dead_icon:before.fa-pull-right {
12156   margin-left: .3em;
12157 }
12158 .kernel_dead_icon:before.pull-left {
12159   margin-right: .3em;
12160 }
12161 .kernel_dead_icon:before.pull-right {
12162   margin-left: .3em;
12163 }
12164 .kernel_disconnected_icon:before {
12165   display: inline-block;
12166   font: normal normal normal 14px/1 FontAwesome;
12167   font-size: inherit;
12168   text-rendering: auto;
12169   -webkit-font-smoothing: antialiased;
12170   -moz-osx-font-smoothing: grayscale;
12171   content: "\f127";
12172 }
12173 .kernel_disconnected_icon:before.fa-pull-left {
12174   margin-right: .3em;
12175 }
12176 .kernel_disconnected_icon:before.fa-pull-right {
12177   margin-left: .3em;
12178 }
12179 .kernel_disconnected_icon:before.pull-left {
12180   margin-right: .3em;
12181 }
12182 .kernel_disconnected_icon:before.pull-right {
12183   margin-left: .3em;
12184 }
12185 .notification_widget {
12186   color: #777;
12187   z-index: 10;
12188   background: rgba(240, 240, 240, 0.5);
12189   margin-right: 4px;
12190   color: #333;
12191   background-color: #fff;
12192   border-color: #ccc;
12193 }
12194 .notification_widget:focus,
12195 .notification_widget.focus {
12196   color: #333;
12197   background-color: #e6e6e6;
12198   border-color: #8c8c8c;
12199 }
12200 .notification_widget:hover {
12201   color: #333;
12202   background-color: #e6e6e6;
12203   border-color: #adadad;
12204 }
12205 .notification_widget:active,
12206 .notification_widget.active,
12207 .open > .dropdown-toggle.notification_widget {
12208   color: #333;
12209   background-color: #e6e6e6;
12210   border-color: #adadad;
12211 }
12212 .notification_widget:active:hover,
12213 .notification_widget.active:hover,
12214 .open > .dropdown-toggle.notification_widget:hover,
12215 .notification_widget:active:focus,
12216 .notification_widget.active:focus,
12217 .open > .dropdown-toggle.notification_widget:focus,
12218 .notification_widget:active.focus,
12219 .notification_widget.active.focus,
12220 .open > .dropdown-toggle.notification_widget.focus {
12221   color: #333;
12222   background-color: #d4d4d4;
12223   border-color: #8c8c8c;
12224 }
12225 .notification_widget:active,
12226 .notification_widget.active,
12227 .open > .dropdown-toggle.notification_widget {
12228   background-image: none;
12229 }
12230 .notification_widget.disabled:hover,
12231 .notification_widget[disabled]:hover,
12232 fieldset[disabled] .notification_widget:hover,
12233 .notification_widget.disabled:focus,
12234 .notification_widget[disabled]:focus,
12235 fieldset[disabled] .notification_widget:focus,
12236 .notification_widget.disabled.focus,
12237 .notification_widget[disabled].focus,
12238 fieldset[disabled] .notification_widget.focus {
12239   background-color: #fff;
12240   border-color: #ccc;
12241 }
12242 .notification_widget .badge {
12243   color: #fff;
12244   background-color: #333;
12245 }
12246 .notification_widget.warning {
12247   color: #fff;
12248   background-color: #f0ad4e;
12249   border-color: #eea236;
12250 }
12251 .notification_widget.warning:focus,
12252 .notification_widget.warning.focus {
12253   color: #fff;
12254   background-color: #ec971f;
12255   border-color: #985f0d;
12256 }
12257 .notification_widget.warning:hover {
12258   color: #fff;
12259   background-color: #ec971f;
12260   border-color: #d58512;
12261 }
12262 .notification_widget.warning:active,
12263 .notification_widget.warning.active,
12264 .open > .dropdown-toggle.notification_widget.warning {
12265   color: #fff;
12266   background-color: #ec971f;
12267   border-color: #d58512;
12268 }
12269 .notification_widget.warning:active:hover,
12270 .notification_widget.warning.active:hover,
12271 .open > .dropdown-toggle.notification_widget.warning:hover,
12272 .notification_widget.warning:active:focus,
12273 .notification_widget.warning.active:focus,
12274 .open > .dropdown-toggle.notification_widget.warning:focus,
12275 .notification_widget.warning:active.focus,
12276 .notification_widget.warning.active.focus,
12277 .open > .dropdown-toggle.notification_widget.warning.focus {
12278   color: #fff;
12279   background-color: #d58512;
12280   border-color: #985f0d;
12281 }
12282 .notification_widget.warning:active,
12283 .notification_widget.warning.active,
12284 .open > .dropdown-toggle.notification_widget.warning {
12285   background-image: none;
12286 }
12287 .notification_widget.warning.disabled:hover,
12288 .notification_widget.warning[disabled]:hover,
12289 fieldset[disabled] .notification_widget.warning:hover,
12290 .notification_widget.warning.disabled:focus,
12291 .notification_widget.warning[disabled]:focus,
12292 fieldset[disabled] .notification_widget.warning:focus,
12293 .notification_widget.warning.disabled.focus,
12294 .notification_widget.warning[disabled].focus,
12295 fieldset[disabled] .notification_widget.warning.focus {
12296   background-color: #f0ad4e;
12297   border-color: #eea236;
12298 }
12299 .notification_widget.warning .badge {
12300   color: #f0ad4e;
12301   background-color: #fff;
12302 }
12303 .notification_widget.success {
12304   color: #fff;
12305   background-color: #5cb85c;
12306   border-color: #4cae4c;
12307 }
12308 .notification_widget.success:focus,
12309 .notification_widget.success.focus {
12310   color: #fff;
12311   background-color: #449d44;
12312   border-color: #255625;
12313 }
12314 .notification_widget.success:hover {
12315   color: #fff;
12316   background-color: #449d44;
12317   border-color: #398439;
12318 }
12319 .notification_widget.success:active,
12320 .notification_widget.success.active,
12321 .open > .dropdown-toggle.notification_widget.success {
12322   color: #fff;
12323   background-color: #449d44;
12324   border-color: #398439;
12325 }
12326 .notification_widget.success:active:hover,
12327 .notification_widget.success.active:hover,
12328 .open > .dropdown-toggle.notification_widget.success:hover,
12329 .notification_widget.success:active:focus,
12330 .notification_widget.success.active:focus,
12331 .open > .dropdown-toggle.notification_widget.success:focus,
12332 .notification_widget.success:active.focus,
12333 .notification_widget.success.active.focus,
12334 .open > .dropdown-toggle.notification_widget.success.focus {
12335   color: #fff;
12336   background-color: #398439;
12337   border-color: #255625;
12338 }
12339 .notification_widget.success:active,
12340 .notification_widget.success.active,
12341 .open > .dropdown-toggle.notification_widget.success {
12342   background-image: none;
12343 }
12344 .notification_widget.success.disabled:hover,
12345 .notification_widget.success[disabled]:hover,
12346 fieldset[disabled] .notification_widget.success:hover,
12347 .notification_widget.success.disabled:focus,
12348 .notification_widget.success[disabled]:focus,
12349 fieldset[disabled] .notification_widget.success:focus,
12350 .notification_widget.success.disabled.focus,
12351 .notification_widget.success[disabled].focus,
12352 fieldset[disabled] .notification_widget.success.focus {
12353   background-color: #5cb85c;
12354   border-color: #4cae4c;
12355 }
12356 .notification_widget.success .badge {
12357   color: #5cb85c;
12358   background-color: #fff;
12359 }
12360 .notification_widget.info {
12361   color: #fff;
12362   background-color: #5bc0de;
12363   border-color: #46b8da;
12364 }
12365 .notification_widget.info:focus,
12366 .notification_widget.info.focus {
12367   color: #fff;
12368   background-color: #31b0d5;
12369   border-color: #1b6d85;
12370 }
12371 .notification_widget.info:hover {
12372   color: #fff;
12373   background-color: #31b0d5;
12374   border-color: #269abc;
12375 }
12376 .notification_widget.info:active,
12377 .notification_widget.info.active,
12378 .open > .dropdown-toggle.notification_widget.info {
12379   color: #fff;
12380   background-color: #31b0d5;
12381   border-color: #269abc;
12382 }
12383 .notification_widget.info:active:hover,
12384 .notification_widget.info.active:hover,
12385 .open > .dropdown-toggle.notification_widget.info:hover,
12386 .notification_widget.info:active:focus,
12387 .notification_widget.info.active:focus,
12388 .open > .dropdown-toggle.notification_widget.info:focus,
12389 .notification_widget.info:active.focus,
12390 .notification_widget.info.active.focus,
12391 .open > .dropdown-toggle.notification_widget.info.focus {
12392   color: #fff;
12393   background-color: #269abc;
12394   border-color: #1b6d85;
12395 }
12396 .notification_widget.info:active,
12397 .notification_widget.info.active,
12398 .open > .dropdown-toggle.notification_widget.info {
12399   background-image: none;
12400 }
12401 .notification_widget.info.disabled:hover,
12402 .notification_widget.info[disabled]:hover,
12403 fieldset[disabled] .notification_widget.info:hover,
12404 .notification_widget.info.disabled:focus,
12405 .notification_widget.info[disabled]:focus,
12406 fieldset[disabled] .notification_widget.info:focus,
12407 .notification_widget.info.disabled.focus,
12408 .notification_widget.info[disabled].focus,
12409 fieldset[disabled] .notification_widget.info.focus {
12410   background-color: #5bc0de;
12411   border-color: #46b8da;
12412 }
12413 .notification_widget.info .badge {
12414   color: #5bc0de;
12415   background-color: #fff;
12416 }
12417 .notification_widget.danger {
12418   color: #fff;
12419   background-color: #d9534f;
12420   border-color: #d43f3a;
12421 }
12422 .notification_widget.danger:focus,
12423 .notification_widget.danger.focus {
12424   color: #fff;
12425   background-color: #c9302c;
12426   border-color: #761c19;
12427 }
12428 .notification_widget.danger:hover {
12429   color: #fff;
12430   background-color: #c9302c;
12431   border-color: #ac2925;
12432 }
12433 .notification_widget.danger:active,
12434 .notification_widget.danger.active,
12435 .open > .dropdown-toggle.notification_widget.danger {
12436   color: #fff;
12437   background-color: #c9302c;
12438   border-color: #ac2925;
12439 }
12440 .notification_widget.danger:active:hover,
12441 .notification_widget.danger.active:hover,
12442 .open > .dropdown-toggle.notification_widget.danger:hover,
12443 .notification_widget.danger:active:focus,
12444 .notification_widget.danger.active:focus,
12445 .open > .dropdown-toggle.notification_widget.danger:focus,
12446 .notification_widget.danger:active.focus,
12447 .notification_widget.danger.active.focus,
12448 .open > .dropdown-toggle.notification_widget.danger.focus {
12449   color: #fff;
12450   background-color: #ac2925;
12451   border-color: #761c19;
12452 }
12453 .notification_widget.danger:active,
12454 .notification_widget.danger.active,
12455 .open > .dropdown-toggle.notification_widget.danger {
12456   background-image: none;
12457 }
12458 .notification_widget.danger.disabled:hover,
12459 .notification_widget.danger[disabled]:hover,
12460 fieldset[disabled] .notification_widget.danger:hover,
12461 .notification_widget.danger.disabled:focus,
12462 .notification_widget.danger[disabled]:focus,
12463 fieldset[disabled] .notification_widget.danger:focus,
12464 .notification_widget.danger.disabled.focus,
12465 .notification_widget.danger[disabled].focus,
12466 fieldset[disabled] .notification_widget.danger.focus {
12467   background-color: #d9534f;
12468   border-color: #d43f3a;
12469 }
12470 .notification_widget.danger .badge {
12471   color: #d9534f;
12472   background-color: #fff;
12473 }
12474 div#pager {
12475   background-color: #fff;
12476   font-size: 14px;
12477   line-height: 20px;
12478   overflow: hidden;
12479   display: none;
12480   position: fixed;
12481   bottom: 0px;
12482   width: 100%;
12483   max-height: 50%;
12484   padding-top: 8px;
12485   -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12486   box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12487   /* Display over codemirror */
12488   z-index: 100;
12489   /* Hack which prevents jquery ui resizable from changing top. */
12490   top: auto !important;
12491 }
12492 div#pager pre {
12493   line-height: 1.21429em;
12494   color: #000;
12495   background-color: #f7f7f7;
12496   padding: 0.4em;
12497 }
12498 div#pager #pager-button-area {
12499   position: absolute;
12500   top: 8px;
12501   right: 20px;
12502 }
12503 div#pager #pager-contents {
12504   position: relative;
12505   overflow: auto;
12506   width: 100%;
12507   height: 100%;
12508 }
12509 div#pager #pager-contents #pager-container {
12510   position: relative;
12511   padding: 15px 0px;
12512   box-sizing: border-box;
12513   -moz-box-sizing: border-box;
12514   -webkit-box-sizing: border-box;
12515 }
12516 div#pager .ui-resizable-handle {
12517   top: 0px;
12518   height: 8px;
12519   background: #f7f7f7;
12520   border-top: 1px solid #cfcfcf;
12521   border-bottom: 1px solid #cfcfcf;
12522   /* This injects handle bars (a short, wide = symbol) for 
12523         the resize handle. */
12524 }
12525 div#pager .ui-resizable-handle::after {
12526   content: '';
12527   top: 2px;
12528   left: 50%;
12529   height: 3px;
12530   width: 30px;
12531   margin-left: -15px;
12532   position: absolute;
12533   border-top: 1px solid #cfcfcf;
12534 }
12535 .quickhelp {
12536   /* Old browsers */
12537   display: -webkit-box;
12538   -webkit-box-orient: horizontal;
12539   -webkit-box-align: stretch;
12540   display: -moz-box;
12541   -moz-box-orient: horizontal;
12542   -moz-box-align: stretch;
12543   display: box;
12544   box-orient: horizontal;
12545   box-align: stretch;
12546   /* Modern browsers */
12547   display: flex;
12548   flex-direction: row;
12549   align-items: stretch;
12550   line-height: 1.8em;
12551 }
12552 .shortcut_key {
12553   display: inline-block;
12554   width: 21ex;
12555   text-align: right;
12556   font-family: monospace;
12557 }
12558 .shortcut_descr {
12559   display: inline-block;
12560   /* Old browsers */
12561   -webkit-box-flex: 1;
12562   -moz-box-flex: 1;
12563   box-flex: 1;
12564   /* Modern browsers */
12565   flex: 1;
12566 }
12567 span.save_widget {
12568   height: 30px;
12569   margin-top: 4px;
12570   display: flex;
12571   justify-content: flex-start;
12572   align-items: baseline;
12573   width: 50%;
12574   flex: 1;
12575 }
12576 span.save_widget span.filename {
12577   height: 100%;
12578   line-height: 1em;
12579   margin-left: 16px;
12580   border: none;
12581   font-size: 146.5%;
12582   text-overflow: ellipsis;
12583   overflow: hidden;
12584   white-space: nowrap;
12585   border-radius: 2px;
12586 }
12587 span.save_widget span.filename:hover {
12588   background-color: #e6e6e6;
12589 }
12590 [dir="rtl"] span.save_widget.pull-left {
12591   float: right !important;
12592   float: right;
12593 }
12594 [dir="rtl"] span.save_widget span.filename {
12595   margin-left: 0;
12596   margin-right: 16px;
12597 }
12598 span.checkpoint_status,
12599 span.autosave_status {
12600   font-size: small;
12601   white-space: nowrap;
12602   padding: 0 5px;
12603 }
12604 @media (max-width: 767px) {
12605   span.save_widget {
12606     font-size: small;
12607     padding: 0 0 0 5px;
12608   }
12609   span.checkpoint_status,
12610   span.autosave_status {
12611     display: none;
12612   }
12613 }
12614 @media (min-width: 768px) and (max-width: 991px) {
12615   span.checkpoint_status {
12616     display: none;
12617   }
12618   span.autosave_status {
12619     font-size: x-small;
12620   }
12621 }
12622 .toolbar {
12623   padding: 0px;
12624   margin-left: -5px;
12625   margin-top: 2px;
12626   margin-bottom: 5px;
12627   box-sizing: border-box;
12628   -moz-box-sizing: border-box;
12629   -webkit-box-sizing: border-box;
12630 }
12631 .toolbar select,
12632 .toolbar label {
12633   width: auto;
12634   vertical-align: middle;
12635   margin-right: 2px;
12636   margin-bottom: 0px;
12637   display: inline;
12638   font-size: 92%;
12639   margin-left: 0.3em;
12640   margin-right: 0.3em;
12641   padding: 0px;
12642   padding-top: 3px;
12643 }
12644 .toolbar .btn {
12645   padding: 2px 8px;
12646 }
12647 .toolbar .btn-group {
12648   margin-top: 0px;
12649   margin-left: 5px;
12650 }
12651 .toolbar-btn-label {
12652   margin-left: 6px;
12653 }
12654 #maintoolbar {
12655   margin-bottom: -3px;
12656   margin-top: -8px;
12657   border: 0px;
12658   min-height: 27px;
12659   margin-left: 0px;
12660   padding-top: 11px;
12661   padding-bottom: 3px;
12662 }
12663 #maintoolbar .navbar-text {
12664   float: none;
12665   vertical-align: middle;
12666   text-align: right;
12667   margin-left: 5px;
12668   margin-right: 0px;
12669   margin-top: 0px;
12670 }
12671 .select-xs {
12672   height: 24px;
12673 }
12674 [dir="rtl"] .btn-group > .btn,
12675 .btn-group-vertical > .btn {
12676   float: right;
12677 }
12678 .pulse,
12679 .dropdown-menu > li > a.pulse,
12680 li.pulse > a.dropdown-toggle,
12681 li.pulse.open > a.dropdown-toggle {
12682   background-color: #F37626;
12683   color: white;
12684 }
12685 /**
12686  * Primary styles
12687  *
12688  * Author: Jupyter Development Team
12689  */
12690 /** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
12691  * of chance of beeing generated from the ../less/[samename].less file, you can
12692  * try to get back the less file by reverting somme commit in history
12693  **/
12694 /*
12695  * We'll try to get something pretty, so we
12696  * have some strange css to have the scroll bar on
12697  * the left with fix button on the top right of the tooltip
12698  */
12699 @-moz-keyframes fadeOut {
12700   from {
12701     opacity: 1;
12702   }
12703   to {
12704     opacity: 0;
12705   }
12706 }
12707 @-webkit-keyframes fadeOut {
12708   from {
12709     opacity: 1;
12710   }
12711   to {
12712     opacity: 0;
12713   }
12714 }
12715 @-moz-keyframes fadeIn {
12716   from {
12717     opacity: 0;
12718   }
12719   to {
12720     opacity: 1;
12721   }
12722 }
12723 @-webkit-keyframes fadeIn {
12724   from {
12725     opacity: 0;
12726   }
12727   to {
12728     opacity: 1;
12729   }
12730 }
12731 /*properties of tooltip after "expand"*/
12732 .bigtooltip {
12733   overflow: auto;
12734   height: 200px;
12735   -webkit-transition-property: height;
12736   -webkit-transition-duration: 500ms;
12737   -moz-transition-property: height;
12738   -moz-transition-duration: 500ms;
12739   transition-property: height;
12740   transition-duration: 500ms;
12741 }
12742 /*properties of tooltip before "expand"*/
12743 .smalltooltip {
12744   -webkit-transition-property: height;
12745   -webkit-transition-duration: 500ms;
12746   -moz-transition-property: height;
12747   -moz-transition-duration: 500ms;
12748   transition-property: height;
12749   transition-duration: 500ms;
12750   text-overflow: ellipsis;
12751   overflow: hidden;
12752   height: 80px;
12753 }
12754 .tooltipbuttons {
12755   position: absolute;
12756   padding-right: 15px;
12757   top: 0px;
12758   right: 0px;
12759 }
12760 .tooltiptext {
12761   /*avoid the button to overlap on some docstring*/
12762   padding-right: 30px;
12763 }
12764 .ipython_tooltip {
12765   max-width: 700px;
12766   /*fade-in animation when inserted*/
12767   -webkit-animation: fadeOut 400ms;
12768   -moz-animation: fadeOut 400ms;
12769   animation: fadeOut 400ms;
12770   -webkit-animation: fadeIn 400ms;
12771   -moz-animation: fadeIn 400ms;
12772   animation: fadeIn 400ms;
12773   vertical-align: middle;
12774   background-color: #f7f7f7;
12775   overflow: visible;
12776   border: #ababab 1px solid;
12777   outline: none;
12778   padding: 3px;
12779   margin: 0px;
12780   padding-left: 7px;
12781   font-family: monospace;
12782   min-height: 50px;
12783   -moz-box-shadow: 0px 6px 10px -1px #adadad;
12784   -webkit-box-shadow: 0px 6px 10px -1px #adadad;
12785   box-shadow: 0px 6px 10px -1px #adadad;
12786   border-radius: 2px;
12787   position: absolute;
12788   z-index: 1000;
12789 }
12790 .ipython_tooltip a {
12791   float: right;
12792 }
12793 .ipython_tooltip .tooltiptext pre {
12794   border: 0;
12795   border-radius: 0;
12796   font-size: 100%;
12797   background-color: #f7f7f7;
12798 }
12799 .pretooltiparrow {
12800   left: 0px;
12801   margin: 0px;
12802   top: -16px;
12803   width: 40px;
12804   height: 16px;
12805   overflow: hidden;
12806   position: absolute;
12807 }
12808 .pretooltiparrow:before {
12809   background-color: #f7f7f7;
12810   border: 1px #ababab solid;
12811   z-index: 11;
12812   content: "";
12813   position: absolute;
12814   left: 15px;
12815   top: 10px;
12816   width: 25px;
12817   height: 25px;
12818   -webkit-transform: rotate(45deg);
12819   -moz-transform: rotate(45deg);
12820   -ms-transform: rotate(45deg);
12821   -o-transform: rotate(45deg);
12822 }
12823 ul.typeahead-list i {
12824   margin-left: -10px;
12825   width: 18px;
12826 }
12827 [dir="rtl"] ul.typeahead-list i {
12828   margin-left: 0;
12829   margin-right: -10px;
12830 }
12831 ul.typeahead-list {
12832   max-height: 80vh;
12833   overflow: auto;
12834 }
12835 ul.typeahead-list > li > a {
12836   /** Firefox bug **/
12837   /* see https://github.com/jupyter/notebook/issues/559 */
12838   white-space: normal;
12839 }
12840 ul.typeahead-list  > li > a.pull-right {
12841   float: left !important;
12842   float: left;
12843 }
12844 [dir="rtl"] .typeahead-list {
12845   text-align: right;
12846 }
12847 .cmd-palette .modal-body {
12848   padding: 7px;
12849 }
12850 .cmd-palette form {
12851   background: white;
12852 }
12853 .cmd-palette input {
12854   outline: none;
12855 }
12856 .no-shortcut {
12857   min-width: 20px;
12858   color: transparent;
12859 }
12860 [dir="rtl"] .no-shortcut.pull-right {
12861   float: left !important;
12862   float: left;
12863 }
12864 [dir="rtl"] .command-shortcut.pull-right {
12865   float: left !important;
12866   float: left;
12867 }
12868 .command-shortcut:before {
12869   content: "(command mode)";
12870   padding-right: 3px;
12871   color: #777777;
12872 }
12873 .edit-shortcut:before {
12874   content: "(edit)";
12875   padding-right: 3px;
12876   color: #777777;
12877 }
12878 [dir="rtl"] .edit-shortcut.pull-right {
12879   float: left !important;
12880   float: left;
12881 }
12882 #find-and-replace #replace-preview .match,
12883 #find-and-replace #replace-preview .insert {
12884   background-color: #BBDEFB;
12885   border-color: #90CAF9;
12886   border-style: solid;
12887   border-width: 1px;
12888   border-radius: 0px;
12889 }
12890 [dir="ltr"] #find-and-replace .input-group-btn + .form-control {
12891   border-left: none;
12892 }
12893 [dir="rtl"] #find-and-replace .input-group-btn + .form-control {
12894   border-right: none;
12895 }
12896 #find-and-replace #replace-preview .replace .match {
12897   background-color: #FFCDD2;
12898   border-color: #EF9A9A;
12899   border-radius: 0px;
12900 }
12901 #find-and-replace #replace-preview .replace .insert {
12902   background-color: #C8E6C9;
12903   border-color: #A5D6A7;
12904   border-radius: 0px;
12905 }
12906 #find-and-replace #replace-preview {
12907   max-height: 60vh;
12908   overflow: auto;
12909 }
12910 #find-and-replace #replace-preview pre {
12911   padding: 5px 10px;
12912 }
12913 .terminal-app {
12914   background: #EEE;
12915 }
12916 .terminal-app #header {
12917   background: #fff;
12918   -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12919   box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12920 }
12921 .terminal-app .terminal {
12922   width: 100%;
12923   float: left;
12924   font-family: monospace;
12925   color: white;
12926   background: black;
12927   padding: 0.4em;
12928   border-radius: 2px;
12929   -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
12930   box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
12931 }
12932 .terminal-app .terminal,
12933 .terminal-app .terminal dummy-screen {
12934   line-height: 1em;
12935   font-size: 14px;
12936 }
12937 .terminal-app .terminal .xterm-rows {
12938   padding: 10px;
12939 }
12940 .terminal-app .terminal-cursor {
12941   color: black;
12942   background: white;
12943 }
12944 .terminal-app #terminado-container {
12945   margin-top: 20px;
12946 }
12947 /*# sourceMappingURL=style.min.css.map */
12948     </style>
12949 <style type="text/css">
12950     .highlight .hll { background-color: #ffffcc }
12951 .highlight  { background: #f8f8f8; }
12952 .highlight .c { color: #408080; font-style: italic } /* Comment */
12953 .highlight .err { border: 1px solid #FF0000 } /* Error */
12954 .highlight .k { color: #008000; font-weight: bold } /* Keyword */
12955 .highlight .o { color: #666666 } /* Operator */
12956 .highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
12957 .highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
12958 .highlight .cp { color: #BC7A00 } /* Comment.Preproc */
12959 .highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
12960 .highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
12961 .highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
12962 .highlight .gd { color: #A00000 } /* Generic.Deleted */
12963 .highlight .ge { font-style: italic } /* Generic.Emph */
12964 .highlight .gr { color: #FF0000 } /* Generic.Error */
12965 .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
12966 .highlight .gi { color: #00A000 } /* Generic.Inserted */
12967 .highlight .go { color: #888888 } /* Generic.Output */
12968 .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
12969 .highlight .gs { font-weight: bold } /* Generic.Strong */
12970 .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
12971 .highlight .gt { color: #0044DD } /* Generic.Traceback */
12972 .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
12973 .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
12974 .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
12975 .highlight .kp { color: #008000 } /* Keyword.Pseudo */
12976 .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
12977 .highlight .kt { color: #B00040 } /* Keyword.Type */
12978 .highlight .m { color: #666666 } /* Literal.Number */
12979 .highlight .s { color: #BA2121 } /* Literal.String */
12980 .highlight .na { color: #7D9029 } /* Name.Attribute */
12981 .highlight .nb { color: #008000 } /* Name.Builtin */
12982 .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
12983 .highlight .no { color: #880000 } /* Name.Constant */
12984 .highlight .nd { color: #AA22FF } /* Name.Decorator */
12985 .highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
12986 .highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
12987 .highlight .nf { color: #0000FF } /* Name.Function */
12988 .highlight .nl { color: #A0A000 } /* Name.Label */
12989 .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
12990 .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
12991 .highlight .nv { color: #19177C } /* Name.Variable */
12992 .highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
12993 .highlight .w { color: #bbbbbb } /* Text.Whitespace */
12994 .highlight .mb { color: #666666 } /* Literal.Number.Bin */
12995 .highlight .mf { color: #666666 } /* Literal.Number.Float */
12996 .highlight .mh { color: #666666 } /* Literal.Number.Hex */
12997 .highlight .mi { color: #666666 } /* Literal.Number.Integer */
12998 .highlight .mo { color: #666666 } /* Literal.Number.Oct */
12999 .highlight .sa { color: #BA2121 } /* Literal.String.Affix */
13000 .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
13001 .highlight .sc { color: #BA2121 } /* Literal.String.Char */
13002 .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
13003 .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
13004 .highlight .s2 { color: #BA2121 } /* Literal.String.Double */
13005 .highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
13006 .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
13007 .highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
13008 .highlight .sx { color: #008000 } /* Literal.String.Other */
13009 .highlight .sr { color: #BB6688 } /* Literal.String.Regex */
13010 .highlight .s1 { color: #BA2121 } /* Literal.String.Single */
13011 .highlight .ss { color: #19177C } /* Literal.String.Symbol */
13012 .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
13013 .highlight .fm { color: #0000FF } /* Name.Function.Magic */
13014 .highlight .vc { color: #19177C } /* Name.Variable.Class */
13015 .highlight .vg { color: #19177C } /* Name.Variable.Global */
13016 .highlight .vi { color: #19177C } /* Name.Variable.Instance */
13017 .highlight .vm { color: #19177C } /* Name.Variable.Magic */
13018 .highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
13019     </style>
13020
13021
13022 <style type="text/css">
13023 /* Overrides of notebook CSS for static HTML export */
13024 body {
13025   overflow: visible;
13026   padding: 8px;
13027 }
13028
13029 div#notebook {
13030   overflow: visible;
13031   border-top: none;
13032 }@media print {
13033   div.cell {
13034     display: block;
13035     page-break-inside: avoid;
13036   } 
13037   div.output_wrapper { 
13038     display: block;
13039     page-break-inside: avoid; 
13040   }
13041   div.output { 
13042     display: block;
13043     page-break-inside: avoid; 
13044   }
13045 }
13046 </style>
13047
13048 <!-- Custom stylesheet, it must be in the same directory as the html file -->
13049 <link rel="stylesheet" href="custom.css">
13050
13051 <!-- Loading mathjax macro -->
13052 <!-- Load mathjax -->
13053     <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS_HTML"></script>
13054     <!-- MathJax configuration -->
13055     <script type="text/x-mathjax-config">
13056     MathJax.Hub.Config({
13057         tex2jax: {
13058             inlineMath: [ ['$','$'], ["\\(","\\)"] ],
13059             displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
13060             processEscapes: true,
13061             processEnvironments: true
13062         },
13063         // Center justify equations in code and markdown cells. Elsewhere
13064         // we use CSS to left justify single line equations in code cells.
13065         displayAlign: 'center',
13066         "HTML-CSS": {
13067             styles: {'.MathJax_Display': {"margin": 0}},
13068             linebreaks: { automatic: true }
13069         }
13070     });
13071     </script>
13072     <!-- End of mathjax configuration --></head>
13073 <body>
13074   <div tabindex="-1" id="notebook" class="border-box-sizing">
13075     <div class="container" id="notebook-container">
13076
13077 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13078 </div><div class="inner_cell">
13079 <div class="text_cell_render border-box-sizing rendered_html">
13080 <h1 id="The-Blissful-Elegance-of-Typing-Joy">The Blissful Elegance of Typing Joy<a class="anchor-link" href="#The-Blissful-Elegance-of-Typing-Joy">&#182;</a></h1><p>This notebook presents a simple type inferencer for Joy code.  It can infer the stack effect of most Joy expressions.  It's built largely by means of existing ideas and research.  (A great overview of the existing knowledge is a talk <a href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">"Type Inference in Stack-Based Programming Languages"</a> given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.)</p>
13081 <p>The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics.  Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.  (Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves.)</p>
13082
13083 </div>
13084 </div>
13085 </div>
13086 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13087 </div><div class="inner_cell">
13088 <div class="text_cell_render border-box-sizing rendered_html">
13089 <h2 id="Part-I:-P&#246;ial's-Rules">Part I: P&#246;ial's Rules<a class="anchor-link" href="#Part-I:-P&#246;ial's-Rules">&#182;</a></h2><p><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026">"Typing Tools for Typeless Stack Languages" by Jaanus Pöial</a></p>
13090
13091 <pre><code>@INPROCEEDINGS{Pöial06typingtools,
13092     author = {Jaanus Pöial},
13093     title = {Typing tools for typeless stack languages},
13094     booktitle = {In 23rd Euro-Forth Conference},
13095     year = {2006},
13096     pages = {40--46}
13097 }</code></pre>
13098
13099 </div>
13100 </div>
13101 </div>
13102 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13103 </div><div class="inner_cell">
13104 <div class="text_cell_render border-box-sizing rendered_html">
13105 <h3 id="First-Rule">First Rule<a class="anchor-link" href="#First-Rule">&#182;</a></h3><p>This rule deals with functions (and literals) that put items on the stack <code>(-- d)</code>:</p>
13106
13107 <pre><code>   (a -- b)∘(-- d)
13108 ---------------------
13109      (a -- b d)</code></pre>
13110
13111 </div>
13112 </div>
13113 </div>
13114 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13115 </div><div class="inner_cell">
13116 <div class="text_cell_render border-box-sizing rendered_html">
13117 <h3 id="Second-Rule">Second Rule<a class="anchor-link" href="#Second-Rule">&#182;</a></h3><p>This rule deals with functions that consume items from the stack <code>(a --)</code>:</p>
13118
13119 <pre><code>   (a --)∘(c -- d)
13120 ---------------------
13121      (c a -- d)</code></pre>
13122
13123 </div>
13124 </div>
13125 </div>
13126 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13127 </div><div class="inner_cell">
13128 <div class="text_cell_render border-box-sizing rendered_html">
13129 <h3 id="Third-Rule">Third Rule<a class="anchor-link" href="#Third-Rule">&#182;</a></h3><p>The third rule is actually two rules.  These two rules deal with composing functions when the second one will consume one of items the first one produces.  The two types must be <a href="https://en.wikipedia.org/wiki/Robinson&#39;s_unification_algorithm"><em>unified</em></a> or a type conflict declared.</p>
13130
13131 <pre><code>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
13132 -------------------------------
13133    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
13134                                          ^
13135
13136    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
13137 -------------------------------
13138    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]</code></pre>
13139
13140 </div>
13141 </div>
13142 </div>
13143 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13144 </div><div class="inner_cell">
13145 <div class="text_cell_render border-box-sizing rendered_html">
13146 <p>Let's work through some examples by hand to develop an intuition for the algorithm.</p>
13147
13148 </div>
13149 </div>
13150 </div>
13151 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13152 </div><div class="inner_cell">
13153 <div class="text_cell_render border-box-sizing rendered_html">
13154 <p>There's a function in one of the other notebooks.</p>
13155
13156 <pre><code>F == pop swap roll&lt; rest rest cons cons
13157
13158 </code></pre>
13159 <p>It's all "stack chatter" and list manipulation so we should be able to deduce its type.</p>
13160
13161 </div>
13162 </div>
13163 </div>
13164 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13165 </div><div class="inner_cell">
13166 <div class="text_cell_render border-box-sizing rendered_html">
13167 <h3 id="Stack-Effect-Comments">Stack Effect Comments<a class="anchor-link" href="#Stack-Effect-Comments">&#182;</a></h3><p>Joy function types will be represented by Forth-style stack effect comments.  I'm going to use numbers instead of names to keep track of the stack arguments.  (A little bit like <a href="https://en.wikipedia.org/wiki/De_Bruijn_index">De Bruijn index</a>, at least it reminds me of them):</p>
13168
13169 <pre><code>pop (1 --)
13170
13171 swap (1 2 -- 2 1)
13172
13173 roll&lt; (1 2 3 -- 2 3 1)
13174
13175 </code></pre>
13176 <p>These commands alter the stack but don't "look at" the values so these numbers represent an "Any type".</p>
13177
13178 </div>
13179 </div>
13180 </div>
13181 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13182 </div><div class="inner_cell">
13183 <div class="text_cell_render border-box-sizing rendered_html">
13184 <h3 id="pop-swap"><code>pop swap</code><a class="anchor-link" href="#pop-swap">&#182;</a></h3>
13185 <pre><code>(1 --) (1 2 -- 2 1)
13186
13187 </code></pre>
13188 <p>Here we encounter a complication. The argument numbers need to be made unique among both sides.   For this let's change <code>pop</code> to use 0:</p>
13189
13190 <pre><code>(0 --) (1 2 -- 2 1)
13191
13192 </code></pre>
13193 <p>Following the second rule:</p>
13194
13195 <pre><code>(1 2 0 -- 2 1)</code></pre>
13196
13197 </div>
13198 </div>
13199 </div>
13200 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13201 </div><div class="inner_cell">
13202 <div class="text_cell_render border-box-sizing rendered_html">
13203 <h3 id="pop&#8728;swap-roll&lt;"><code>pop&#8728;swap roll&lt;</code><a class="anchor-link" href="#pop&#8728;swap-roll&lt;">&#182;</a></h3>
13204 <pre><code>(1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
13205
13206 </code></pre>
13207 <p>Let's re-label them:</p>
13208
13209 <pre><code>(1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)</code></pre>
13210
13211 </div>
13212 </div>
13213 </div>
13214 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13215 </div><div class="inner_cell">
13216 <div class="text_cell_render border-box-sizing rendered_html">
13217 <p>Now we follow the rules.</p>
13218 <p>We must unify <code>1a</code> and <code>3b</code>, and <code>2a</code> and <code>2b</code>, replacing the terms in the forms:</p>
13219
13220 <pre><code>(1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
13221                                             w/  {1a: 3b}
13222 (3b 2a 0a -- 2a   ) (1b 2b    -- 2b 3b 1b)
13223                                             w/  {2a: 2b}
13224 (3b 2b 0a --      ) (1b       -- 2b 3b 1b)
13225
13226 </code></pre>
13227 <p>Here we must apply the second rule:</p>
13228
13229 <pre><code>   (3b 2b 0a --) (1b -- 2b 3b 1b)
13230 -----------------------------------
13231      (1b 3b 2b 0a -- 2b 3b 1b)
13232
13233 </code></pre>
13234 <p>Now we de-label the type, uh, labels:</p>
13235
13236 <pre><code>(1b 3b 2b 0a -- 2b 3b 1b)
13237
13238 w/ {
13239     1b: 1,
13240     3b: 2,
13241     2b: 3,
13242     0a: 0,
13243     }
13244
13245 (1 2 3 0 -- 3 2 1)
13246
13247 </code></pre>
13248 <p>And now we have the stack effect comment for <code>pop∘swap∘roll&lt;</code>.</p>
13249
13250 </div>
13251 </div>
13252 </div>
13253 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13254 </div><div class="inner_cell">
13255 <div class="text_cell_render border-box-sizing rendered_html">
13256 <h3 id="Compiling-pop&#8728;swap&#8728;roll&lt;">Compiling <code>pop&#8728;swap&#8728;roll&lt;</code><a class="anchor-link" href="#Compiling-pop&#8728;swap&#8728;roll&lt;">&#182;</a></h3><p>The simplest way to "compile" this function would be something like:</p>
13257
13258 </div>
13259 </div>
13260 </div>
13261 <div class="cell border-box-sizing code_cell rendered">
13262 <div class="input">
13263 <div class="prompt input_prompt">In&nbsp;[1]:</div>
13264 <div class="inner_cell">
13265     <div class="input_area">
13266 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
13267     <span class="k">return</span> <span class="n">rolldown</span><span class="p">(</span><span class="o">*</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="n">pop</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">)))</span>
13268 </pre></div>
13269
13270     </div>
13271 </div>
13272 </div>
13273
13274 </div>
13275 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13276 </div><div class="inner_cell">
13277 <div class="text_cell_render border-box-sizing rendered_html">
13278 <p>However, internally this function would still be allocating tuples (stack cells) and doing other unnecesssary work.</p>
13279 <p>Looking ahead for a moment, from the stack effect comment:</p>
13280
13281 <pre><code>(1 2 3 0 -- 3 2 1)
13282
13283 </code></pre>
13284 <p>We should be able to directly write out a Python function like:</p>
13285
13286 </div>
13287 </div>
13288 </div>
13289 <div class="cell border-box-sizing code_cell rendered">
13290 <div class="input">
13291 <div class="prompt input_prompt">In&nbsp;[2]:</div>
13292 <div class="inner_cell">
13293     <div class="input_area">
13294 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
13295     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
13296     <span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
13297 </pre></div>
13298
13299     </div>
13300 </div>
13301 </div>
13302
13303 </div>
13304 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13305 </div><div class="inner_cell">
13306 <div class="text_cell_render border-box-sizing rendered_html">
13307 <p>This eliminates the internal work of the first version.  Because this function only rearranges the stack and doesn't do any actual processing on the stack items themselves all the information needed to implement it is in the stack effect comment.</p>
13308
13309 </div>
13310 </div>
13311 </div>
13312 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13313 </div><div class="inner_cell">
13314 <div class="text_cell_render border-box-sizing rendered_html">
13315 <h3 id="Functions-on-Stacks">Functions on Stacks<a class="anchor-link" href="#Functions-on-Stacks">&#182;</a></h3><p>These are slightly tricky.</p>
13316
13317 <pre><code>rest ( [1 ...] -- [...] )
13318
13319 cons ( 1 [...] -- [1 ...] )</code></pre>
13320
13321 </div>
13322 </div>
13323 </div>
13324 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13325 </div><div class="inner_cell">
13326 <div class="text_cell_render border-box-sizing rendered_html">
13327 <h3 id="pop&#8728;swap&#8728;roll&lt;-rest"><code>pop&#8728;swap&#8728;roll&lt; rest</code><a class="anchor-link" href="#pop&#8728;swap&#8728;roll&lt;-rest">&#182;</a></h3>
13328 <pre><code>(1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
13329
13330 </code></pre>
13331 <p>Re-label (instead of adding left and right tags I'm just taking the next available index number for the right-side stack effect comment):</p>
13332
13333 <pre><code>(1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
13334
13335 </code></pre>
13336 <p>Unify and update:</p>
13337
13338 <pre><code>(1       2 3 0 -- 3 2 1) ([4 ...] -- [...])
13339                                              w/ {1: [4 ...]}
13340 ([4 ...] 2 3 0 -- 3 2  ) (        -- [...])
13341
13342 </code></pre>
13343 <p>Apply the first rule:</p>
13344
13345 <pre><code>   ([4 ...] 2 3 0 -- 3 2) (-- [...])
13346 ---------------------------------------
13347      ([4 ...] 2 3 0 -- 3 2 [...])
13348
13349 </code></pre>
13350 <p>And there we are.</p>
13351
13352 </div>
13353 </div>
13354 </div>
13355 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13356 </div><div class="inner_cell">
13357 <div class="text_cell_render border-box-sizing rendered_html">
13358 <h3 id="pop&#8728;swap&#8728;roll&lt;&#8728;rest-rest"><code>pop&#8728;swap&#8728;roll&lt;&#8728;rest rest</code><a class="anchor-link" href="#pop&#8728;swap&#8728;roll&lt;&#8728;rest-rest">&#182;</a></h3><p>Let's do it again.</p>
13359
13360 <pre><code>([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
13361
13362 </code></pre>
13363 <p>Re-label (the tails of the lists on each side each get their own label):</p>
13364
13365 <pre><code>([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
13366
13367 </code></pre>
13368 <p>Unify and update (note the opening square brackets have been omited in the substitution dict, this is deliberate and I'll explain below):</p>
13369
13370 <pre><code>([4 .0.]   2 3 0 -- 3 2 [.0.]  ) ([5 .1.] -- [.1.])
13371                                                     w/ { .0.] : 5 .1.] }
13372 ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])</code></pre>
13373
13374 </div>
13375 </div>
13376 </div>
13377 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13378 </div><div class="inner_cell">
13379 <div class="text_cell_render border-box-sizing rendered_html">
13380 <p>How do we find <code>.0.]</code> in <code>[4 .0.]</code> and replace it with <code>5 .1.]</code> getting the result <code>[4 5 .1.]</code>?  This might seem hard, but because the underlying structure of the Joy list is a cons-list in Python it's actually pretty easy.  I'll explain below.</p>
13381
13382 </div>
13383 </div>
13384 </div>
13385 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13386 </div><div class="inner_cell">
13387 <div class="text_cell_render border-box-sizing rendered_html">
13388 <p>Next we unify and find our two terms are the same already: <code>[5 .1.]</code>:</p>
13389
13390 <pre><code>([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
13391
13392 </code></pre>
13393 <p>Giving us:</p>
13394
13395 <pre><code>([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
13396
13397 </code></pre>
13398 <p>From here we apply the first rule and get:</p>
13399
13400 <pre><code>([4 5 .1.] 2 3 0 -- 3 2 [.1.])
13401
13402 </code></pre>
13403 <p>Cleaning up the labels:</p>
13404
13405 <pre><code>([4 5 ...] 2 3 1 -- 3 2 [...])
13406
13407 </code></pre>
13408 <p>This is the stack effect of <code>pop∘swap∘roll&lt;∘rest∘rest</code>.</p>
13409
13410 </div>
13411 </div>
13412 </div>
13413 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13414 </div><div class="inner_cell">
13415 <div class="text_cell_render border-box-sizing rendered_html">
13416 <h3 id="pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest-cons"><code>pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest cons</code><a class="anchor-link" href="#pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest-cons">&#182;</a></h3>
13417 <pre><code>([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
13418
13419 </code></pre>
13420 <p>Re-label:</p>
13421
13422 <pre><code>([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
13423
13424 </code></pre>
13425 <p>Unify:</p>
13426
13427 <pre><code>([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
13428                                                      w/ { .1.] : .2.] }
13429 ([4 5 .2.] 2 3 1 -- 3 2      ) (6       -- [6 .2.])
13430                                                      w/ {2: 6}
13431 ([4 5 .2.] 6 3 1 -- 3        ) (        -- [6 .2.])
13432
13433 </code></pre>
13434 <p>First rule:</p>
13435
13436 <pre><code>([4 5 .2.] 6 3 1 -- 3 [6 .2.])
13437
13438 </code></pre>
13439 <p>Re-label:</p>
13440
13441 <pre><code>([4 5 ...] 2 3 1 -- 3 [2 ...])
13442
13443 </code></pre>
13444 <p>Done.</p>
13445
13446 </div>
13447 </div>
13448 </div>
13449 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13450 </div><div class="inner_cell">
13451 <div class="text_cell_render border-box-sizing rendered_html">
13452 <h3 id="pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest&#8728;cons-cons"><code>pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest&#8728;cons cons</code><a class="anchor-link" href="#pop&#8728;swap&#8728;roll&lt;&#8728;rest&#8728;rest&#8728;cons-cons">&#182;</a></h3><p>One more time.</p>
13453
13454 <pre><code>([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
13455
13456 </code></pre>
13457 <p>Re-label:</p>
13458
13459 <pre><code>([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
13460
13461 </code></pre>
13462 <p>Unify:</p>
13463
13464 <pre><code>([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.]  )
13465                                                        w/ { .2.] : 2 .1.] }
13466 ([4 5 .1.] 2 3 1 -- 3        ) (6       -- [6 2 .1.])
13467                                                        w/ {3: 6}
13468 ([4 5 .1.] 2 6 1 --          ) (        -- [6 2 .1.])
13469
13470 </code></pre>
13471 <p>First or second rule:</p>
13472
13473 <pre><code>([4 5 .1.] 2 6 1 -- [6 2 .1.])
13474
13475 </code></pre>
13476 <p>Clean up the labels:</p>
13477
13478 <pre><code>([4 5 ...] 2 3 1 -- [3 2 ...])
13479
13480 </code></pre>
13481 <p>And there you have it, the stack effect for <code>pop∘swap∘roll&lt;∘rest∘rest∘cons∘cons</code>.</p>
13482
13483 <pre><code>([4 5 ...] 2 3 1 -- [3 2 ...])</code></pre>
13484
13485 </div>
13486 </div>
13487 </div>
13488 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13489 </div><div class="inner_cell">
13490 <div class="text_cell_render border-box-sizing rendered_html">
13491 <p>From this stack effect comment it should be possible to construct the following Python code:</p>
13492
13493 </div>
13494 </div>
13495 </div>
13496 <div class="cell border-box-sizing code_cell rendered">
13497 <div class="input">
13498 <div class="prompt input_prompt">In&nbsp;[3]:</div>
13499 <div class="inner_cell">
13500     <div class="input_area">
13501 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
13502     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
13503     <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
13504 </pre></div>
13505
13506     </div>
13507 </div>
13508 </div>
13509
13510 </div>
13511 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13512 </div><div class="inner_cell">
13513 <div class="text_cell_render border-box-sizing rendered_html">
13514 <h2 id="Part-II:-Implementation">Part II: Implementation<a class="anchor-link" href="#Part-II:-Implementation">&#182;</a></h2>
13515 </div>
13516 </div>
13517 </div>
13518 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13519 </div><div class="inner_cell">
13520 <div class="text_cell_render border-box-sizing rendered_html">
13521 <h3 id="Representing-Stack-Effect-Comments-in-Python">Representing Stack Effect Comments in Python<a class="anchor-link" href="#Representing-Stack-Effect-Comments-in-Python">&#182;</a></h3><p>I'm going to use pairs of tuples of type descriptors, which will be integers or tuples of type descriptors:</p>
13522
13523 </div>
13524 </div>
13525 </div>
13526 <div class="cell border-box-sizing code_cell rendered">
13527 <div class="input">
13528 <div class="prompt input_prompt">In&nbsp;[4]:</div>
13529 <div class="inner_cell">
13530     <div class="input_area">
13531 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
13532
13533 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
13534
13535 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
13536 </pre></div>
13537
13538     </div>
13539 </div>
13540 </div>
13541
13542 </div>
13543 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13544 </div><div class="inner_cell">
13545 <div class="text_cell_render border-box-sizing rendered_html">
13546 <h3 id="compose()"><code>compose()</code><a class="anchor-link" href="#compose()">&#182;</a></h3>
13547 </div>
13548 </div>
13549 </div>
13550 <div class="cell border-box-sizing code_cell rendered">
13551 <div class="input">
13552 <div class="prompt input_prompt">In&nbsp;[5]:</div>
13553 <div class="inner_cell">
13554     <div class="input_area">
13555 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
13556
13557     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
13558
13559     <span class="c1"># First rule.</span>
13560     <span class="c1">#</span>
13561     <span class="c1">#       (a -- b) (-- d)</span>
13562     <span class="c1">#    ---------------------</span>
13563     <span class="c1">#         (a -- b d)</span>
13564
13565     <span class="k">if</span> <span class="ow">not</span> <span class="n">g_in</span><span class="p">:</span>
13566
13567         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span> <span class="o">+</span> <span class="n">g_out</span>
13568
13569     <span class="c1"># Second rule.</span>
13570     <span class="c1">#</span>
13571     <span class="c1">#       (a --) (c -- d)</span>
13572     <span class="c1">#    ---------------------</span>
13573     <span class="c1">#         (c a -- d)</span>
13574
13575     <span class="k">elif</span> <span class="ow">not</span> <span class="n">f_out</span><span class="p">:</span>
13576
13577         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">g_in</span> <span class="o">+</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span>
13578
13579     <span class="k">else</span><span class="p">:</span> <span class="c1"># Unify, update, recur.</span>
13580
13581         <span class="n">fo</span><span class="p">,</span> <span class="n">gi</span> <span class="o">=</span> <span class="n">f_out</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_in</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
13582
13583         <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">gi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
13584
13585         <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>  <span class="c1"># s can also be the empty dict, which is ok.</span>
13586             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">gi</span><span class="p">))</span>
13587
13588         <span class="n">f_g</span> <span class="o">=</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_out</span><span class="p">)</span>
13589
13590         <span class="k">if</span> <span class="n">s</span><span class="p">:</span> <span class="n">f_g</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f_g</span><span class="p">)</span>
13591
13592         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="o">*</span><span class="n">f_g</span><span class="p">)</span>
13593
13594     <span class="k">return</span> <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span>
13595 </pre></div>
13596
13597     </div>
13598 </div>
13599 </div>
13600
13601 </div>
13602 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13603 </div><div class="inner_cell">
13604 <div class="text_cell_render border-box-sizing rendered_html">
13605 <h3 id="unify()"><code>unify()</code><a class="anchor-link" href="#unify()">&#182;</a></h3>
13606 </div>
13607 </div>
13608 </div>
13609 <div class="cell border-box-sizing code_cell rendered">
13610 <div class="input">
13611 <div class="prompt input_prompt">In&nbsp;[6]:</div>
13612 <div class="inner_cell">
13613     <div class="input_area">
13614 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
13615     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
13616         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
13617
13618     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
13619         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
13620     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
13621         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
13622     <span class="k">else</span><span class="p">:</span>
13623         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
13624
13625     <span class="k">return</span> <span class="n">s</span>
13626 </pre></div>
13627
13628     </div>
13629 </div>
13630 </div>
13631
13632 </div>
13633 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13634 </div><div class="inner_cell">
13635 <div class="text_cell_render border-box-sizing rendered_html">
13636 <h3 id="update()"><code>update()</code><a class="anchor-link" href="#update()">&#182;</a></h3>
13637 </div>
13638 </div>
13639 </div>
13640 <div class="cell border-box-sizing code_cell rendered">
13641 <div class="input">
13642 <div class="prompt input_prompt">In&nbsp;[7]:</div>
13643 <div class="inner_cell">
13644     <div class="input_area">
13645 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
13646     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
13647         <span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">term</span><span class="p">)</span>
13648     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">inner</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
13649 </pre></div>
13650
13651     </div>
13652 </div>
13653 </div>
13654
13655 </div>
13656 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13657 </div><div class="inner_cell">
13658 <div class="text_cell_render border-box-sizing rendered_html">
13659 <h3 id="relabel()"><code>relabel()</code><a class="anchor-link" href="#relabel()">&#182;</a></h3>
13660 </div>
13661 </div>
13662 </div>
13663 <div class="cell border-box-sizing code_cell rendered">
13664 <div class="input">
13665 <div class="prompt input_prompt">In&nbsp;[8]:</div>
13666 <div class="inner_cell">
13667     <div class="input_area">
13668 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
13669     <span class="k">return</span> <span class="n">left</span><span class="p">,</span> <span class="n">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
13670
13671 <span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
13672     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">right</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
13673         <span class="k">return</span> <span class="mi">1000</span> <span class="o">+</span> <span class="n">right</span>
13674     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_1000</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">right</span><span class="p">)</span>
13675
13676 <span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
13677 </pre></div>
13678
13679     </div>
13680 </div>
13681 </div>
13682
13683 <div class="output_wrapper">
13684 <div class="output">
13685
13686
13687 <div class="output_area">
13688
13689     <div class="prompt output_prompt">Out[8]:</div>
13690
13691
13692
13693
13694 <div class="output_text output_subarea output_execute_result">
13695 <pre>(((1,), ()), ((1001, 1002), (1002, 1001)))</pre>
13696 </div>
13697
13698 </div>
13699
13700 </div>
13701 </div>
13702
13703 </div>
13704 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13705 </div><div class="inner_cell">
13706 <div class="text_cell_render border-box-sizing rendered_html">
13707 <h3 id="delabel()"><code>delabel()</code><a class="anchor-link" href="#delabel()">&#182;</a></h3>
13708 </div>
13709 </div>
13710 </div>
13711 <div class="cell border-box-sizing code_cell rendered">
13712 <div class="input">
13713 <div class="prompt input_prompt">In&nbsp;[9]:</div>
13714 <div class="inner_cell">
13715     <div class="input_area">
13716 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
13717     <span class="n">s</span> <span class="o">=</span> <span class="p">{</span><span class="n">u</span><span class="p">:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">)))}</span>
13718     <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
13719
13720 <span class="k">def</span> <span class="nf">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
13721     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
13722         <span class="n">seen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
13723     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
13724         <span class="n">seen</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
13725     <span class="k">else</span><span class="p">:</span>
13726         <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
13727             <span class="n">_unique</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">)</span>
13728     <span class="k">return</span> <span class="n">seen</span>
13729
13730 <span class="n">delabel</span><span class="p">(</span><span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">))</span>
13731 </pre></div>
13732
13733     </div>
13734 </div>
13735 </div>
13736
13737 <div class="output_wrapper">
13738 <div class="output">
13739
13740
13741 <div class="output_area">
13742
13743     <div class="prompt output_prompt">Out[9]:</div>
13744
13745
13746
13747
13748 <div class="output_text output_subarea output_execute_result">
13749 <pre>(((0,), ()), ((1, 2), (2, 1)))</pre>
13750 </div>
13751
13752 </div>
13753
13754 </div>
13755 </div>
13756
13757 </div>
13758 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13759 </div><div class="inner_cell">
13760 <div class="text_cell_render border-box-sizing rendered_html">
13761 <h3 id="C()"><code>C()</code><a class="anchor-link" href="#C()">&#182;</a></h3><p>At last we put it all together in a function <code>C()</code> that accepts two stack effect comments and returns their composition (or raises and exception if they can't be composed due to type conflicts.)</p>
13762
13763 </div>
13764 </div>
13765 </div>
13766 <div class="cell border-box-sizing code_cell rendered">
13767 <div class="input">
13768 <div class="prompt input_prompt">In&nbsp;[10]:</div>
13769 <div class="inner_cell">
13770     <div class="input_area">
13771 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
13772     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
13773     <span class="n">fg</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
13774     <span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
13775 </pre></div>
13776
13777     </div>
13778 </div>
13779 </div>
13780
13781 </div>
13782 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13783 </div><div class="inner_cell">
13784 <div class="text_cell_render border-box-sizing rendered_html">
13785 <p>Let's try it out.</p>
13786
13787 </div>
13788 </div>
13789 </div>
13790 <div class="cell border-box-sizing code_cell rendered">
13791 <div class="input">
13792 <div class="prompt input_prompt">In&nbsp;[11]:</div>
13793 <div class="inner_cell">
13794     <div class="input_area">
13795 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
13796 </pre></div>
13797
13798     </div>
13799 </div>
13800 </div>
13801
13802 <div class="output_wrapper">
13803 <div class="output">
13804
13805
13806 <div class="output_area">
13807
13808     <div class="prompt output_prompt">Out[11]:</div>
13809
13810
13811
13812
13813 <div class="output_text output_subarea output_execute_result">
13814 <pre>((1, 2, 0), (2, 1))</pre>
13815 </div>
13816
13817 </div>
13818
13819 </div>
13820 </div>
13821
13822 </div>
13823 <div class="cell border-box-sizing code_cell rendered">
13824 <div class="input">
13825 <div class="prompt input_prompt">In&nbsp;[12]:</div>
13826 <div class="inner_cell">
13827     <div class="input_area">
13828 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
13829 </pre></div>
13830
13831     </div>
13832 </div>
13833 </div>
13834
13835 <div class="output_wrapper">
13836 <div class="output">
13837
13838
13839 <div class="output_area">
13840
13841     <div class="prompt output_prompt">Out[12]:</div>
13842
13843
13844
13845
13846 <div class="output_text output_subarea output_execute_result">
13847 <pre>((3, 1, 2, 0), (2, 1, 3))</pre>
13848 </div>
13849
13850 </div>
13851
13852 </div>
13853 </div>
13854
13855 </div>
13856 <div class="cell border-box-sizing code_cell rendered">
13857 <div class="input">
13858 <div class="prompt input_prompt">In&nbsp;[13]:</div>
13859 <div class="inner_cell">
13860     <div class="input_area">
13861 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
13862 </pre></div>
13863
13864     </div>
13865 </div>
13866 </div>
13867
13868 <div class="output_wrapper">
13869 <div class="output">
13870
13871
13872 <div class="output_area">
13873
13874     <div class="prompt output_prompt">Out[13]:</div>
13875
13876
13877
13878
13879 <div class="output_text output_subarea output_execute_result">
13880 <pre>((2, 0, 1), (1, 0, 2))</pre>
13881 </div>
13882
13883 </div>
13884
13885 </div>
13886 </div>
13887
13888 </div>
13889 <div class="cell border-box-sizing code_cell rendered">
13890 <div class="input">
13891 <div class="prompt input_prompt">In&nbsp;[14]:</div>
13892 <div class="inner_cell">
13893     <div class="input_area">
13894 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
13895 </pre></div>
13896
13897     </div>
13898 </div>
13899 </div>
13900
13901 <div class="output_wrapper">
13902 <div class="output">
13903
13904
13905 <div class="output_area">
13906
13907     <div class="prompt output_prompt">Out[14]:</div>
13908
13909
13910
13911
13912 <div class="output_text output_subarea output_execute_result">
13913 <pre>((3, 1, 2, 0), (2, 1, 3))</pre>
13914 </div>
13915
13916 </div>
13917
13918 </div>
13919 </div>
13920
13921 </div>
13922 <div class="cell border-box-sizing code_cell rendered">
13923 <div class="input">
13924 <div class="prompt input_prompt">In&nbsp;[15]:</div>
13925 <div class="inner_cell">
13926     <div class="input_area">
13927 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
13928 <span class="n">poswrd</span>
13929 </pre></div>
13930
13931     </div>
13932 </div>
13933 </div>
13934
13935 <div class="output_wrapper">
13936 <div class="output">
13937
13938
13939 <div class="output_area">
13940
13941     <div class="prompt output_prompt">Out[15]:</div>
13942
13943
13944
13945
13946 <div class="output_text output_subarea output_execute_result">
13947 <pre>((3, 1, 2, 0), (2, 1, 3))</pre>
13948 </div>
13949
13950 </div>
13951
13952 </div>
13953 </div>
13954
13955 </div>
13956 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13957 </div><div class="inner_cell">
13958 <div class="text_cell_render border-box-sizing rendered_html">
13959 <h3 id="Stack-Functions">Stack Functions<a class="anchor-link" href="#Stack-Functions">&#182;</a></h3><p>Here's that trick to represent functions like <code>rest</code> and <code>cons</code> that manipulate stacks.  We use a cons-list of tuples and give the tails their own numbers.  Then everything above already works.</p>
13960
13961 </div>
13962 </div>
13963 </div>
13964 <div class="cell border-box-sizing code_cell rendered">
13965 <div class="input">
13966 <div class="prompt input_prompt">In&nbsp;[16]:</div>
13967 <div class="inner_cell">
13968     <div class="input_area">
13969 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
13970
13971 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
13972 </pre></div>
13973
13974     </div>
13975 </div>
13976 </div>
13977
13978 </div>
13979 <div class="cell border-box-sizing code_cell rendered">
13980 <div class="input">
13981 <div class="prompt input_prompt">In&nbsp;[17]:</div>
13982 <div class="inner_cell">
13983     <div class="input_area">
13984 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
13985 </pre></div>
13986
13987     </div>
13988 </div>
13989 </div>
13990
13991 <div class="output_wrapper">
13992 <div class="output">
13993
13994
13995 <div class="output_area">
13996
13997     <div class="prompt output_prompt">Out[17]:</div>
13998
13999
14000
14001
14002 <div class="output_text output_subarea output_execute_result">
14003 <pre>(((3, 4), 1, 2, 0), (2, 1, 4))</pre>
14004 </div>
14005
14006 </div>
14007
14008 </div>
14009 </div>
14010
14011 </div>
14012 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14013 </div><div class="inner_cell">
14014 <div class="text_cell_render border-box-sizing rendered_html">
14015 <p>Compare this to the stack effect comment we wrote above:</p>
14016
14017 <pre><code>((  (3, 4), 1, 2, 0 ), ( 2, 1,   4  ))
14018 (   [4 ...] 2  3  0  --  3  2  [...])
14019
14020 </code></pre>
14021 <p>The translation table, if you will, would be:</p>
14022
14023 <pre><code>{
14024 3: 4,
14025 4: ...],
14026 1: 2,
14027 2: 3,
14028 0: 0,
14029 }</code></pre>
14030
14031 </div>
14032 </div>
14033 </div>
14034 <div class="cell border-box-sizing code_cell rendered">
14035 <div class="input">
14036 <div class="prompt input_prompt">In&nbsp;[18]:</div>
14037 <div class="inner_cell">
14038     <div class="input_area">
14039 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
14040
14041 <span class="n">F</span>
14042 </pre></div>
14043
14044     </div>
14045 </div>
14046 </div>
14047
14048 <div class="output_wrapper">
14049 <div class="output">
14050
14051
14052 <div class="output_area">
14053
14054     <div class="prompt output_prompt">Out[18]:</div>
14055
14056
14057
14058
14059 <div class="output_text output_subarea output_execute_result">
14060 <pre>(((3, (4, 5)), 1, 2, 0), ((2, (1, 5)),))</pre>
14061 </div>
14062
14063 </div>
14064
14065 </div>
14066 </div>
14067
14068 </div>
14069 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14070 </div><div class="inner_cell">
14071 <div class="text_cell_render border-box-sizing rendered_html">
14072 <p>Compare with the stack effect comment and you can see it works fine:</p>
14073
14074 <pre><code>([4 5 ...] 2 3 1 -- [3 2 ...])
14075   3 4  5   1 2 0     2 1  5</code></pre>
14076
14077 </div>
14078 </div>
14079 </div>
14080 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14081 </div><div class="inner_cell">
14082 <div class="text_cell_render border-box-sizing rendered_html">
14083 <h3 id="Dealing-with-cons-and-uncons">Dealing with <code>cons</code> and <code>uncons</code><a class="anchor-link" href="#Dealing-with-cons-and-uncons">&#182;</a></h3><p>However, if we try to compose e.g. <code>cons</code> and <code>uncons</code> it won't work:</p>
14084
14085 </div>
14086 </div>
14087 </div>
14088 <div class="cell border-box-sizing code_cell rendered">
14089 <div class="input">
14090 <div class="prompt input_prompt">In&nbsp;[19]:</div>
14091 <div class="inner_cell">
14092     <div class="input_area">
14093 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
14094 </pre></div>
14095
14096     </div>
14097 </div>
14098 </div>
14099
14100 </div>
14101 <div class="cell border-box-sizing code_cell rendered">
14102 <div class="input">
14103 <div class="prompt input_prompt">In&nbsp;[20]:</div>
14104 <div class="inner_cell">
14105     <div class="input_area">
14106 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">try</span><span class="p">:</span>
14107     <span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
14108 <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
14109     <span class="nb">print</span> <span class="n">e</span>
14110 </pre></div>
14111
14112     </div>
14113 </div>
14114 </div>
14115
14116 <div class="output_wrapper">
14117 <div class="output">
14118
14119
14120 <div class="output_area">
14121
14122     <div class="prompt"></div>
14123
14124
14125 <div class="output_subarea output_stream output_stdout output_text">
14126 <pre>Cannot unify (1, 2) and (1001, 1002).
14127 </pre>
14128 </div>
14129 </div>
14130
14131 </div>
14132 </div>
14133
14134 </div>
14135 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14136 </div><div class="inner_cell">
14137 <div class="text_cell_render border-box-sizing rendered_html">
14138 <h4 id="unify()-version-2"><code>unify()</code> version 2<a class="anchor-link" href="#unify()-version-2">&#182;</a></h4><p>The problem is that the <code>unify()</code> function as written doesn't handle the case when both terms are tuples.  We just have to add a clause to deal with this recursively:</p>
14139
14140 </div>
14141 </div>
14142 </div>
14143 <div class="cell border-box-sizing code_cell rendered">
14144 <div class="input">
14145 <div class="prompt input_prompt">In&nbsp;[21]:</div>
14146 <div class="inner_cell">
14147     <div class="input_area">
14148 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
14149     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
14150         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
14151     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
14152         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
14153         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
14154
14155     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
14156         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
14157
14158     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
14159         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
14160
14161     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
14162
14163         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
14164             <span class="c1"># Not a type error, caller passed in a bad value.</span>
14165             <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>  <span class="c1"># FIXME this message sucks.</span>
14166
14167         <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">=</span> <span class="n">u</span><span class="p">,</span> <span class="n">v</span>
14168         <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
14169         <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="kc">False</span><span class="p">:</span>
14170             <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
14171     <span class="k">else</span><span class="p">:</span>
14172         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
14173
14174     <span class="k">return</span> <span class="n">s</span>
14175 </pre></div>
14176
14177     </div>
14178 </div>
14179 </div>
14180
14181 </div>
14182 <div class="cell border-box-sizing code_cell rendered">
14183 <div class="input">
14184 <div class="prompt input_prompt">In&nbsp;[22]:</div>
14185 <div class="inner_cell">
14186     <div class="input_area">
14187 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
14188 </pre></div>
14189
14190     </div>
14191 </div>
14192 </div>
14193
14194 <div class="output_wrapper">
14195 <div class="output">
14196
14197
14198 <div class="output_area">
14199
14200     <div class="prompt output_prompt">Out[22]:</div>
14201
14202
14203
14204
14205 <div class="output_text output_subarea output_execute_result">
14206 <pre>((0, 1), (0, 1))</pre>
14207 </div>
14208
14209 </div>
14210
14211 </div>
14212 </div>
14213
14214 </div>
14215 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14216 </div><div class="inner_cell">
14217 <div class="text_cell_render border-box-sizing rendered_html">
14218 <h2 id="Part-III:-Compiling-Yin-Functions">Part III: Compiling Yin Functions<a class="anchor-link" href="#Part-III:-Compiling-Yin-Functions">&#182;</a></h2><p>Now consider the Python function we would like to derive:</p>
14219
14220 </div>
14221 </div>
14222 </div>
14223 <div class="cell border-box-sizing code_cell rendered">
14224 <div class="input">
14225 <div class="prompt input_prompt">In&nbsp;[23]:</div>
14226 <div class="inner_cell">
14227     <div class="input_area">
14228 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
14229     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
14230     <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
14231 </pre></div>
14232
14233     </div>
14234 </div>
14235 </div>
14236
14237 </div>
14238 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14239 </div><div class="inner_cell">
14240 <div class="text_cell_render border-box-sizing rendered_html">
14241 <p>And compare it to the input stack effect comment tuple we just computed:</p>
14242
14243 </div>
14244 </div>
14245 </div>
14246 <div class="cell border-box-sizing code_cell rendered">
14247 <div class="input">
14248 <div class="prompt input_prompt">In&nbsp;[24]:</div>
14249 <div class="inner_cell">
14250     <div class="input_area">
14251 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
14252 </pre></div>
14253
14254     </div>
14255 </div>
14256 </div>
14257
14258 <div class="output_wrapper">
14259 <div class="output">
14260
14261
14262 <div class="output_area">
14263
14264     <div class="prompt output_prompt">Out[24]:</div>
14265
14266
14267
14268
14269 <div class="output_text output_subarea output_execute_result">
14270 <pre>((3, (4, 5)), 1, 2, 0)</pre>
14271 </div>
14272
14273 </div>
14274
14275 </div>
14276 </div>
14277
14278 </div>
14279 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14280 </div><div class="inner_cell">
14281 <div class="text_cell_render border-box-sizing rendered_html">
14282 <p>The stack-de-structuring tuple has nearly the same form as our input stack effect comment tuple, just in the reverse order:</p>
14283
14284 <pre><code>(_, (d, (c, ((a, (b, S0)), stack))))
14285
14286 </code></pre>
14287 <p>Remove the punctuation:</p>
14288
14289 <pre><code> _   d   c   (a, (b, S0))
14290
14291 </code></pre>
14292 <p>Reverse the order and compare:</p>
14293
14294 <pre><code> (a, (b, S0))   c   d   _
14295 ((3, (4, 5 )),  1,  2,  0)
14296
14297 </code></pre>
14298 <p>Eh?</p>
14299
14300 </div>
14301 </div>
14302 </div>
14303 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14304 </div><div class="inner_cell">
14305 <div class="text_cell_render border-box-sizing rendered_html">
14306 <p>And the return tuple</p>
14307
14308 </div>
14309 </div>
14310 </div>
14311 <div class="cell border-box-sizing code_cell rendered">
14312 <div class="input">
14313 <div class="prompt input_prompt">In&nbsp;[25]:</div>
14314 <div class="inner_cell">
14315     <div class="input_area">
14316 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
14317 </pre></div>
14318
14319     </div>
14320 </div>
14321 </div>
14322
14323 <div class="output_wrapper">
14324 <div class="output">
14325
14326
14327 <div class="output_area">
14328
14329     <div class="prompt output_prompt">Out[25]:</div>
14330
14331
14332
14333
14334 <div class="output_text output_subarea output_execute_result">
14335 <pre>((2, (1, 5)),)</pre>
14336 </div>
14337
14338 </div>
14339
14340 </div>
14341 </div>
14342
14343 </div>
14344 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14345 </div><div class="inner_cell">
14346 <div class="text_cell_render border-box-sizing rendered_html">
14347 <p>is similar to the output stack effect comment tuple:</p>
14348
14349 <pre><code>((d, (c, S0)), stack)
14350 ((2, (1, 5 )),      )
14351
14352 </code></pre>
14353 <p>This should make it pretty easy to write a Python function that accepts the stack effect comment tuples and returns a new Python function (either as a string of code or a function object ready to use) that performs the semantics of that Joy function (described by the stack effect.)</p>
14354
14355 </div>
14356 </div>
14357 </div>
14358 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14359 </div><div class="inner_cell">
14360 <div class="text_cell_render border-box-sizing rendered_html">
14361 <h3 id="Python-Identifiers">Python Identifiers<a class="anchor-link" href="#Python-Identifiers">&#182;</a></h3><p>We want to substitute Python identifiers for the integers.  I'm going to repurpose <code>joy.parser.Symbol</code> class for this:</p>
14362
14363 </div>
14364 </div>
14365 </div>
14366 <div class="cell border-box-sizing code_cell rendered">
14367 <div class="input">
14368 <div class="prompt input_prompt">In&nbsp;[26]:</div>
14369 <div class="inner_cell">
14370     <div class="input_area">
14371 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
14372 <span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">Symbol</span>
14373
14374
14375 <span class="k">def</span> <span class="nf">_names_for</span><span class="p">():</span>
14376     <span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">xrange</span><span class="p">(</span><span class="mi">1000</span><span class="p">))</span>
14377     <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;a</span><span class="si">%i</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
14378
14379
14380 <span class="k">def</span> <span class="nf">identifiers</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
14381     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
14382         <span class="n">s</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">_names_for</span><span class="p">())</span>
14383     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
14384         <span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="n">term</span><span class="p">]</span>
14385     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">identifiers</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
14386 </pre></div>
14387
14388     </div>
14389 </div>
14390 </div>
14391
14392 </div>
14393 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14394 </div><div class="inner_cell">
14395 <div class="text_cell_render border-box-sizing rendered_html">
14396 <h3 id="doc_from_stack_effect()"><code>doc_from_stack_effect()</code><a class="anchor-link" href="#doc_from_stack_effect()">&#182;</a></h3><p>As a convenience I've implemented a function to convert the Python stack effect comment tuples to reasonable text format.  There are some details in how this code works that related to stuff later in the notebook, so you should skip it for now and read it later if you're interested.</p>
14397
14398 </div>
14399 </div>
14400 </div>
14401 <div class="cell border-box-sizing code_cell rendered">
14402 <div class="input">
14403 <div class="prompt input_prompt">In&nbsp;[27]:</div>
14404 <div class="inner_cell">
14405     <div class="input_area">
14406 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
14407     <span class="k">return</span> <span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span>
14408         <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="n">inputs</span> <span class="o">+</span> <span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,))),</span>
14409         <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,)</span> <span class="o">+</span> <span class="n">outputs</span><span class="p">))</span>
14410     <span class="p">)</span>
14411
14412
14413 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">):</span>
14414     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
14415         <span class="k">try</span><span class="p">:</span>
14416             <span class="n">t</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="s1">&#39;s&#39;</span>
14417         <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
14418             <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
14419         <span class="k">return</span> <span class="s1">&#39;[.</span><span class="si">%i</span><span class="s1">.]&#39;</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span> <span class="k">if</span> <span class="n">t</span> <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
14420
14421     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
14422     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
14423         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
14424         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">))</span>
14425
14426     <span class="k">try</span><span class="p">:</span>
14427         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
14428     <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
14429         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span>
14430     <span class="k">else</span><span class="p">:</span>
14431         <span class="k">if</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">!=</span> <span class="s1">&#39;s&#39;</span><span class="p">:</span>
14432             <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Stack label: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">term</span><span class="p">,))</span>
14433
14434     <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;.</span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,))</span>
14435     <span class="k">return</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
14436 </pre></div>
14437
14438     </div>
14439 </div>
14440 </div>
14441
14442 </div>
14443 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14444 </div><div class="inner_cell">
14445 <div class="text_cell_render border-box-sizing rendered_html">
14446 <h3 id="compile_()"><code>compile_()</code><a class="anchor-link" href="#compile_()">&#182;</a></h3><p>Now we can write a compiler function to emit Python source code.  (The underscore suffix distiguishes it from the built-in <code>compile()</code> function.)</p>
14447
14448 </div>
14449 </div>
14450 </div>
14451 <div class="cell border-box-sizing code_cell rendered">
14452 <div class="input">
14453 <div class="prompt input_prompt">In&nbsp;[28]:</div>
14454 <div class="inner_cell">
14455     <div class="input_area">
14456 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
14457     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
14458         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
14459     <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">identifiers</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
14460     <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;stack&#39;</span><span class="p">)</span>
14461     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
14462         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
14463     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
14464         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
14465     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
14466 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
14467 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
14468 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
14469 </pre></div>
14470
14471     </div>
14472 </div>
14473 </div>
14474
14475 </div>
14476 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14477 </div><div class="inner_cell">
14478 <div class="text_cell_render border-box-sizing rendered_html">
14479 <p>Here it is in action:</p>
14480
14481 </div>
14482 </div>
14483 </div>
14484 <div class="cell border-box-sizing code_cell rendered">
14485 <div class="input">
14486 <div class="prompt input_prompt">In&nbsp;[29]:</div>
14487 <div class="inner_cell">
14488     <div class="input_area">
14489 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
14490
14491 <span class="nb">print</span> <span class="n">source</span>
14492 </pre></div>
14493
14494     </div>
14495 </div>
14496 </div>
14497
14498 <div class="output_wrapper">
14499 <div class="output">
14500
14501
14502 <div class="output_area">
14503
14504     <div class="prompt"></div>
14505
14506
14507 <div class="output_subarea output_stream output_stdout output_text">
14508 <pre>def F(stack):
14509     &#34;&#34;&#34;([3 4 .5.] 1 2 0 -- [2 1 .5.])&#34;&#34;&#34;
14510     (a5, (a4, (a3, ((a0, (a1, a2)), stack)))) = stack
14511     return ((a4, (a3, a2)), stack)
14512 </pre>
14513 </div>
14514 </div>
14515
14516 </div>
14517 </div>
14518
14519 </div>
14520 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14521 </div><div class="inner_cell">
14522 <div class="text_cell_render border-box-sizing rendered_html">
14523 <p>Compare:</p>
14524
14525 </div>
14526 </div>
14527 </div>
14528 <div class="cell border-box-sizing code_cell rendered">
14529 <div class="input">
14530 <div class="prompt input_prompt">In&nbsp;[30]:</div>
14531 <div class="inner_cell">
14532     <div class="input_area">
14533 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
14534     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
14535     <span class="k">return</span> <span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
14536 </pre></div>
14537
14538     </div>
14539 </div>
14540 </div>
14541
14542 </div>
14543 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14544 </div><div class="inner_cell">
14545 <div class="text_cell_render border-box-sizing rendered_html">
14546 <p>Next steps:</p>
14547
14548 </div>
14549 </div>
14550 </div>
14551 <div class="cell border-box-sizing code_cell rendered">
14552 <div class="input">
14553 <div class="prompt input_prompt">In&nbsp;[31]:</div>
14554 <div class="inner_cell">
14555     <div class="input_area">
14556 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
14557
14558 <span class="nb">eval</span><span class="p">(</span><span class="nb">compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="s1">&#39;__main__&#39;</span><span class="p">,</span> <span class="s1">&#39;single&#39;</span><span class="p">),</span> <span class="p">{},</span> <span class="n">L</span><span class="p">)</span>
14559
14560 <span class="n">L</span><span class="p">[</span><span class="s1">&#39;F&#39;</span><span class="p">]</span>
14561 </pre></div>
14562
14563     </div>
14564 </div>
14565 </div>
14566
14567 <div class="output_wrapper">
14568 <div class="output">
14569
14570
14571 <div class="output_area">
14572
14573     <div class="prompt output_prompt">Out[31]:</div>
14574
14575
14576
14577
14578 <div class="output_text output_subarea output_execute_result">
14579 <pre>&lt;function F&gt;</pre>
14580 </div>
14581
14582 </div>
14583
14584 </div>
14585 </div>
14586
14587 </div>
14588 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14589 </div><div class="inner_cell">
14590 <div class="text_cell_render border-box-sizing rendered_html">
14591 <p>Let's try it out:</p>
14592
14593 </div>
14594 </div>
14595 </div>
14596 <div class="cell border-box-sizing code_cell rendered">
14597 <div class="input">
14598 <div class="prompt input_prompt">In&nbsp;[32]:</div>
14599 <div class="inner_cell">
14600     <div class="input_area">
14601 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
14602 <span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
14603 </pre></div>
14604
14605     </div>
14606 </div>
14607 </div>
14608
14609 </div>
14610 <div class="cell border-box-sizing code_cell rendered">
14611 <div class="input">
14612 <div class="prompt input_prompt">In&nbsp;[33]:</div>
14613 <div class="inner_cell">
14614     <div class="input_area">
14615 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">&#39;F&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">&#39;F&#39;</span><span class="p">])</span>
14616 </pre></div>
14617
14618     </div>
14619 </div>
14620 </div>
14621
14622 </div>
14623 <div class="cell border-box-sizing code_cell rendered">
14624 <div class="input">
14625 <div class="prompt input_prompt">In&nbsp;[34]:</div>
14626 <div class="inner_cell">
14627     <div class="input_area">
14628 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[4 5 ...] 2 3 1 F&#39;</span><span class="p">)</span>
14629 </pre></div>
14630
14631     </div>
14632 </div>
14633 </div>
14634
14635 <div class="output_wrapper">
14636 <div class="output">
14637
14638
14639 <div class="output_area">
14640
14641     <div class="prompt"></div>
14642
14643
14644 <div class="output_subarea output_stream output_stdout output_text">
14645 <pre>[3 2 ...]
14646 </pre>
14647 </div>
14648 </div>
14649
14650 </div>
14651 </div>
14652
14653 </div>
14654 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14655 </div><div class="inner_cell">
14656 <div class="text_cell_render border-box-sizing rendered_html">
14657 <p>With this, we have a partial Joy compiler that works on the subset of Joy functions that manipulate stacks (both what I call "stack chatter" and the ones that manipulate stacks on the stack.)</p>
14658 <p>I'm probably going to modify the definition wrapper code to detect definitions that can be compiled by this partial compiler and do it automatically.  It might be a reasonable idea to detect sequences of compilable functions in definitions that have uncompilable functions in them and just compile those.  However, if your library is well-factored this might be less helpful.</p>
14659
14660 </div>
14661 </div>
14662 </div>
14663 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14664 </div><div class="inner_cell">
14665 <div class="text_cell_render border-box-sizing rendered_html">
14666 <h3 id="Compiling-Library-Functions">Compiling Library Functions<a class="anchor-link" href="#Compiling-Library-Functions">&#182;</a></h3><p>We can use <code>compile_()</code> to generate many primitives in the library from their stack effect comments:</p>
14667
14668 </div>
14669 </div>
14670 </div>
14671 <div class="cell border-box-sizing code_cell rendered">
14672 <div class="input">
14673 <div class="prompt input_prompt">In&nbsp;[35]:</div>
14674 <div class="inner_cell">
14675     <div class="input_area">
14676 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
14677
14678     <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
14679
14680     <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
14681
14682     <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
14683
14684     <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
14685
14686     <span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
14687     
14688     <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
14689
14690     <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
14691
14692     <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
14693     
14694     <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
14695
14696     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
14697 </pre></div>
14698
14699     </div>
14700 </div>
14701 </div>
14702
14703 </div>
14704 <div class="cell border-box-sizing code_cell rendered">
14705 <div class="input">
14706 <div class="prompt input_prompt">In&nbsp;[36]:</div>
14707 <div class="inner_cell">
14708     <div class="input_area">
14709 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
14710     <span class="nb">print</span>
14711     <span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span><span class="p">)</span>
14712     <span class="nb">print</span>
14713 </pre></div>
14714
14715     </div>
14716 </div>
14717 </div>
14718
14719 <div class="output_wrapper">
14720 <div class="output">
14721
14722
14723 <div class="output_area">
14724
14725     <div class="prompt"></div>
14726
14727
14728 <div class="output_subarea output_stream output_stdout output_text">
14729 <pre>
14730 def cons(stack):
14731     &#34;&#34;&#34;(1 2 -- [1 .2.])&#34;&#34;&#34;
14732     (a1, (a0, stack)) = stack
14733     return ((a0, a1), stack)
14734
14735
14736 def pop(stack):
14737     &#34;&#34;&#34;(1 --)&#34;&#34;&#34;
14738     (a0, stack) = stack
14739     return stack
14740
14741
14742 def rest(stack):
14743     &#34;&#34;&#34;([1 .2.] -- 2)&#34;&#34;&#34;
14744     ((a0, a1), stack) = stack
14745     return (a1, stack)
14746
14747
14748 def rolldown(stack):
14749     &#34;&#34;&#34;(1 2 3 -- 2 3 1)&#34;&#34;&#34;
14750     (a2, (a1, (a0, stack))) = stack
14751     return (a0, (a2, (a1, stack)))
14752
14753
14754 def rollup(stack):
14755     &#34;&#34;&#34;(1 2 3 -- 3 1 2)&#34;&#34;&#34;
14756     (a2, (a1, (a0, stack))) = stack
14757     return (a1, (a0, (a2, stack)))
14758
14759
14760 def rrest(stack):
14761     &#34;&#34;&#34;([0 1 .2.] -- 2)&#34;&#34;&#34;
14762     ((a0, (a1, a2)), stack) = stack
14763     return (a2, stack)
14764
14765
14766 def swap(stack):
14767     &#34;&#34;&#34;(1 2 -- 2 1)&#34;&#34;&#34;
14768     (a1, (a0, stack)) = stack
14769     return (a0, (a1, stack))
14770
14771
14772 def swons(stack):
14773     &#34;&#34;&#34;(0 1 -- [1 .0.])&#34;&#34;&#34;
14774     (a1, (a0, stack)) = stack
14775     return ((a1, a0), stack)
14776
14777
14778 def uncons(stack):
14779     &#34;&#34;&#34;([1 .2.] -- 1 2)&#34;&#34;&#34;
14780     ((a0, a1), stack) = stack
14781     return (a1, (a0, stack))
14782
14783 </pre>
14784 </div>
14785 </div>
14786
14787 </div>
14788 </div>
14789
14790 </div>
14791 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14792 </div><div class="inner_cell">
14793 <div class="text_cell_render border-box-sizing rendered_html">
14794 <h2 id="Part-IV:-Types-and-Subtypes-of-Arguments">Part IV: Types and Subtypes of Arguments<a class="anchor-link" href="#Part-IV:-Types-and-Subtypes-of-Arguments">&#182;</a></h2><p>So far we have dealt with types of functions, those dealing with simple stack manipulation.  Let's extend our machinery to deal with types of arguments.</p>
14795
14796 </div>
14797 </div>
14798 </div>
14799 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14800 </div><div class="inner_cell">
14801 <div class="text_cell_render border-box-sizing rendered_html">
14802 <h3 id="&quot;Number&quot;-Type">"Number" Type<a class="anchor-link" href="#&quot;Number&quot;-Type">&#182;</a></h3><p>Consider the definition of <code>sqr</code>:</p>
14803
14804 <pre><code>sqr == dup mul
14805
14806
14807 </code></pre>
14808 <p>The <code>dup</code> function accepts one <em>anything</em> and returns two of that:</p>
14809
14810 <pre><code>dup (1 -- 1 1)
14811
14812 </code></pre>
14813 <p>And <code>mul</code> accepts two "numbers" (we're ignoring ints vs. floats vs. complex, etc., for now) and returns just one:</p>
14814
14815 <pre><code>mul (n n -- n)
14816
14817 </code></pre>
14818 <p>So we're composing:</p>
14819
14820 <pre><code>(1 -- 1 1)∘(n n -- n)
14821
14822 </code></pre>
14823 <p>The rules say we unify 1 with <code>n</code>:</p>
14824
14825 <pre><code>   (1 -- 1 1)∘(n n -- n)
14826 ---------------------------  w/  {1: n}
14827    (1 -- 1  )∘(n   -- n)
14828
14829 </code></pre>
14830 <p>This involves detecting that "Any type" arguments can accept "numbers".  If we were composing these functions the other way round this is still the case:</p>
14831
14832 <pre><code>   (n n -- n)∘(1 -- 1 1)
14833 ---------------------------  w/  {1: n}
14834    (n n --  )∘(  -- n n) 
14835
14836 </code></pre>
14837 <p>The important thing here is that the mapping is going the same way in both cases, from the "any" integer to the number</p>
14838
14839 </div>
14840 </div>
14841 </div>
14842 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14843 </div><div class="inner_cell">
14844 <div class="text_cell_render border-box-sizing rendered_html">
14845 <h3 id="Distinguishing-Numbers">Distinguishing Numbers<a class="anchor-link" href="#Distinguishing-Numbers">&#182;</a></h3><p>We should also mind that the number that <code>mul</code> produces is not (necessarily) the same as either of its inputs, which are not (necessarily) the same as each other:</p>
14846
14847 <pre><code>mul (n2 n1 -- n3)
14848
14849
14850    (1  -- 1  1)∘(n2 n1 -- n3)
14851 --------------------------------  w/  {1: n2}
14852    (n2 -- n2  )∘(n2    -- n3)
14853
14854
14855    (n2 n1 -- n3)∘(1 -- 1  1 )
14856 --------------------------------  w/  {1: n3}
14857    (n2 n1 --   )∘(  -- n3 n3) </code></pre>
14858
14859 </div>
14860 </div>
14861 </div>
14862 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14863 </div><div class="inner_cell">
14864 <div class="text_cell_render border-box-sizing rendered_html">
14865 <h3 id="Distinguishing-Types">Distinguishing Types<a class="anchor-link" href="#Distinguishing-Types">&#182;</a></h3><p>So we need separate domains of "any" numbers and "number" numbers, and we need to be able to ask the order of these domains.  Now the notes on the right side of rule three make more sense, eh?</p>
14866
14867 <pre><code>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
14868 -------------------------------
14869    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
14870                                          ^
14871
14872    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
14873 -------------------------------
14874    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]
14875
14876 </code></pre>
14877 <p>The indices <code>i</code>, <code>k</code>, and <code>j</code> are the number part of our labels and <code>t</code> and <code>u</code> are the domains.</p>
14878 <p>By creative use of Python's "double underscore" methods we can define a Python class hierarchy of Joy types and use the <code>issubclass()</code> method to establish domain ordering, as well as other handy behaviour that will make it fairly easy to reuse most of the code above.</p>
14879
14880 </div>
14881 </div>
14882 </div>
14883 <div class="cell border-box-sizing code_cell rendered">
14884 <div class="input">
14885 <div class="prompt input_prompt">In&nbsp;[37]:</div>
14886 <div class="inner_cell">
14887     <div class="input_area">
14888 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
14889
14890     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;a&#39;</span>
14891
14892     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
14893         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
14894
14895     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
14896         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
14897
14898     <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
14899         <span class="k">return</span> <span class="p">(</span>
14900             <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
14901             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span>
14902             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
14903         <span class="p">)</span>
14904
14905     <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
14906         <span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
14907
14908     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
14909         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
14910     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
14911     
14912     <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
14913         <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
14914
14915
14916 <span class="k">class</span> <span class="nc">NumberJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;n&#39;</span>
14917 <span class="k">class</span> <span class="nc">FloatJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;f&#39;</span>
14918 <span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;i&#39;</span>
14919
14920
14921 <span class="k">class</span> <span class="nc">StackJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
14922     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;s&#39;</span>
14923
14924
14925 <span class="n">_R</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
14926 <span class="n">A</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
14927 <span class="n">N</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
14928 <span class="n">S</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
14929 </pre></div>
14930
14931     </div>
14932 </div>
14933 </div>
14934
14935 </div>
14936 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14937 </div><div class="inner_cell">
14938 <div class="text_cell_render border-box-sizing rendered_html">
14939 <p>Mess with it a little:</p>
14940
14941 </div>
14942 </div>
14943 </div>
14944 <div class="cell border-box-sizing code_cell rendered">
14945 <div class="input">
14946 <div class="prompt input_prompt">In&nbsp;[38]:</div>
14947 <div class="inner_cell">
14948     <div class="input_area">
14949 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">permutations</span>
14950 </pre></div>
14951
14952     </div>
14953 </div>
14954 </div>
14955
14956 </div>
14957 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14958 </div><div class="inner_cell">
14959 <div class="text_cell_render border-box-sizing rendered_html">
14960 <p>"Any" types can be specialized to numbers and stacks, but not vice versa:</p>
14961
14962 </div>
14963 </div>
14964 </div>
14965 <div class="cell border-box-sizing code_cell rendered">
14966 <div class="input">
14967 <div class="prompt input_prompt">In&nbsp;[39]:</div>
14968 <div class="inner_cell">
14969     <div class="input_area">
14970 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
14971     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span>
14972 </pre></div>
14973
14974     </div>
14975 </div>
14976 </div>
14977
14978 <div class="output_wrapper">
14979 <div class="output">
14980
14981
14982 <div class="output_area">
14983
14984     <div class="prompt"></div>
14985
14986
14987 <div class="output_subarea output_stream output_stdout output_text">
14988 <pre>a0 &gt;= n0 -&gt; True
14989 a0 &gt;= s0 -&gt; True
14990 n0 &gt;= a0 -&gt; False
14991 n0 &gt;= s0 -&gt; False
14992 s0 &gt;= a0 -&gt; False
14993 s0 &gt;= n0 -&gt; False
14994 </pre>
14995 </div>
14996 </div>
14997
14998 </div>
14999 </div>
15000
15001 </div>
15002 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15003 </div><div class="inner_cell">
15004 <div class="text_cell_render border-box-sizing rendered_html">
15005 <p>Our crude <a href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical Tower</a> of <em>numbers</em> &gt; <em>floats</em> &gt; <em>integers</em> works as well (but we're not going to use it yet):</p>
15006
15007 </div>
15008 </div>
15009 </div>
15010 <div class="cell border-box-sizing code_cell rendered">
15011 <div class="input">
15012 <div class="prompt input_prompt">In&nbsp;[40]:</div>
15013 <div class="inner_cell">
15014     <div class="input_area">
15015 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
15016     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span>
15017 </pre></div>
15018
15019     </div>
15020 </div>
15021 </div>
15022
15023 <div class="output_wrapper">
15024 <div class="output">
15025
15026
15027 <div class="output_area">
15028
15029     <div class="prompt"></div>
15030
15031
15032 <div class="output_subarea output_stream output_stdout output_text">
15033 <pre>a0 &gt;= n0 -&gt; True
15034 a0 &gt;= f0 -&gt; True
15035 a0 &gt;= i0 -&gt; True
15036 n0 &gt;= a0 -&gt; False
15037 n0 &gt;= f0 -&gt; True
15038 n0 &gt;= i0 -&gt; True
15039 f0 &gt;= a0 -&gt; False
15040 f0 &gt;= n0 -&gt; False
15041 f0 &gt;= i0 -&gt; True
15042 i0 &gt;= a0 -&gt; False
15043 i0 &gt;= n0 -&gt; False
15044 i0 &gt;= f0 -&gt; False
15045 </pre>
15046 </div>
15047 </div>
15048
15049 </div>
15050 </div>
15051
15052 </div>
15053 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15054 </div><div class="inner_cell">
15055 <div class="text_cell_render border-box-sizing rendered_html">
15056 <h3 id="Typing-sqr">Typing <code>sqr</code><a class="anchor-link" href="#Typing-sqr">&#182;</a></h3>
15057 </div>
15058 </div>
15059 </div>
15060 <div class="cell border-box-sizing code_cell rendered">
15061 <div class="input">
15062 <div class="prompt input_prompt">In&nbsp;[41]:</div>
15063 <div class="inner_cell">
15064     <div class="input_area">
15065 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15066
15067 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
15068 </pre></div>
15069
15070     </div>
15071 </div>
15072 </div>
15073
15074 </div>
15075 <div class="cell border-box-sizing code_cell rendered">
15076 <div class="input">
15077 <div class="prompt input_prompt">In&nbsp;[42]:</div>
15078 <div class="inner_cell">
15079     <div class="input_area">
15080 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">dup</span>
15081 </pre></div>
15082
15083     </div>
15084 </div>
15085 </div>
15086
15087 <div class="output_wrapper">
15088 <div class="output">
15089
15090
15091 <div class="output_area">
15092
15093     <div class="prompt output_prompt">Out[42]:</div>
15094
15095
15096
15097
15098 <div class="output_text output_subarea output_execute_result">
15099 <pre>((a1,), (a1, a1))</pre>
15100 </div>
15101
15102 </div>
15103
15104 </div>
15105 </div>
15106
15107 </div>
15108 <div class="cell border-box-sizing code_cell rendered">
15109 <div class="input">
15110 <div class="prompt input_prompt">In&nbsp;[43]:</div>
15111 <div class="inner_cell">
15112     <div class="input_area">
15113 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">mul</span>
15114 </pre></div>
15115
15116     </div>
15117 </div>
15118 </div>
15119
15120 <div class="output_wrapper">
15121 <div class="output">
15122
15123
15124 <div class="output_area">
15125
15126     <div class="prompt output_prompt">Out[43]:</div>
15127
15128
15129
15130
15131 <div class="output_text output_subarea output_execute_result">
15132 <pre>((n1, n2), (n3,))</pre>
15133 </div>
15134
15135 </div>
15136
15137 </div>
15138 </div>
15139
15140 </div>
15141 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15142 </div><div class="inner_cell">
15143 <div class="text_cell_render border-box-sizing rendered_html">
15144 <h3 id="Modifying-the-Inferencer">Modifying the Inferencer<a class="anchor-link" href="#Modifying-the-Inferencer">&#182;</a></h3><p>Re-labeling still works fine:</p>
15145
15146 </div>
15147 </div>
15148 </div>
15149 <div class="cell border-box-sizing code_cell rendered">
15150 <div class="input">
15151 <div class="prompt input_prompt">In&nbsp;[44]:</div>
15152 <div class="inner_cell">
15153     <div class="input_area">
15154 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
15155
15156 <span class="n">foo</span>
15157 </pre></div>
15158
15159     </div>
15160 </div>
15161 </div>
15162
15163 <div class="output_wrapper">
15164 <div class="output">
15165
15166
15167 <div class="output_area">
15168
15169     <div class="prompt output_prompt">Out[44]:</div>
15170
15171
15172
15173
15174 <div class="output_text output_subarea output_execute_result">
15175 <pre>(((a1,), (a1, a1)), ((n1001, n1002), (n1003,)))</pre>
15176 </div>
15177
15178 </div>
15179
15180 </div>
15181 </div>
15182
15183 </div>
15184 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15185 </div><div class="inner_cell">
15186 <div class="text_cell_render border-box-sizing rendered_html">
15187 <h4 id="delabel()-version-2"><code>delabel()</code> version 2<a class="anchor-link" href="#delabel()-version-2">&#182;</a></h4><p>The <code>delabel()</code> function needs an overhaul.  It now has to keep track of how many labels of each domain it has "seen".</p>
15188
15189 </div>
15190 </div>
15191 </div>
15192 <div class="cell border-box-sizing code_cell rendered">
15193 <div class="input">
15194 <div class="prompt input_prompt">In&nbsp;[45]:</div>
15195 <div class="inner_cell">
15196     <div class="input_area">
15197 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
15198
15199
15200 <span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
15201     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
15202         <span class="k">assert</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span>
15203         <span class="n">seen</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">Counter</span><span class="p">()</span>
15204
15205     <span class="k">try</span><span class="p">:</span>
15206         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
15207     <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
15208         <span class="k">pass</span>
15209
15210     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
15211         <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
15212         <span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
15213         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
15214
15215     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">delabel</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">)</span>
15216 </pre></div>
15217
15218     </div>
15219 </div>
15220 </div>
15221
15222 </div>
15223 <div class="cell border-box-sizing code_cell rendered">
15224 <div class="input">
15225 <div class="prompt input_prompt">In&nbsp;[46]:</div>
15226 <div class="inner_cell">
15227     <div class="input_area">
15228 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
15229 </pre></div>
15230
15231     </div>
15232 </div>
15233 </div>
15234
15235 <div class="output_wrapper">
15236 <div class="output">
15237
15238
15239 <div class="output_area">
15240
15241     <div class="prompt output_prompt">Out[46]:</div>
15242
15243
15244
15245
15246 <div class="output_text output_subarea output_execute_result">
15247 <pre>(((a1,), (a1, a1)), ((n1, n2), (n3,)))</pre>
15248 </div>
15249
15250 </div>
15251
15252 </div>
15253 </div>
15254
15255 </div>
15256 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15257 </div><div class="inner_cell">
15258 <div class="text_cell_render border-box-sizing rendered_html">
15259 <h4 id="unify()-version-3"><code>unify()</code> version 3<a class="anchor-link" href="#unify()-version-3">&#182;</a></h4>
15260 </div>
15261 </div>
15262 </div>
15263 <div class="cell border-box-sizing code_cell rendered">
15264 <div class="input">
15265 <div class="prompt input_prompt">In&nbsp;[47]:</div>
15266 <div class="inner_cell">
15267     <div class="input_area">
15268 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
15269     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
15270         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
15271     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
15272         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
15273         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
15274
15275     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
15276         <span class="k">return</span> <span class="n">s</span>
15277
15278     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">):</span>
15279         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
15280             <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
15281             <span class="k">return</span> <span class="n">s</span>
15282         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
15283             <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
15284             <span class="k">return</span> <span class="n">s</span>
15285         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
15286
15287     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
15288         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
15289             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
15290         <span class="k">for</span> <span class="n">uu</span><span class="p">,</span> <span class="n">vv</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">):</span>
15291             <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">uu</span><span class="p">,</span> <span class="n">vv</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
15292             <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="c1"># (instead of a substitution dict.)</span>
15293                 <span class="k">break</span>
15294         <span class="k">return</span> <span class="n">s</span>
15295  
15296     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
15297         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
15298             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
15299         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
15300         <span class="k">return</span> <span class="n">s</span>
15301
15302     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
15303         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
15304             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
15305         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
15306         <span class="k">return</span> <span class="n">s</span>
15307
15308     <span class="k">return</span> <span class="kc">False</span>
15309
15310
15311 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
15312     <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
15313 </pre></div>
15314
15315     </div>
15316 </div>
15317 </div>
15318
15319 </div>
15320 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15321 </div><div class="inner_cell">
15322 <div class="text_cell_render border-box-sizing rendered_html">
15323 <p>Rewrite the stack effect comments:</p>
15324
15325 </div>
15326 </div>
15327 </div>
15328 <div class="cell border-box-sizing code_cell rendered">
15329 <div class="input">
15330 <div class="prompt input_prompt">In&nbsp;[48]:</div>
15331 <div class="inner_cell">
15332     <div class="input_area">
15333 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
15334
15335     <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15336
15337     <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
15338
15339     <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
15340
15341     <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
15342
15343     <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
15344
15345     <span class="n">popdd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
15346
15347     <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15348
15349     <span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
15350
15351     <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
15352
15353     <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),)</span>
15354
15355     <span class="n">ccons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
15356
15357     <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15358
15359     <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
15360
15361     <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15362
15363     <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15364
15365     <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
15366     
15367     <span class="n">sqrt</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
15368
15369     <span class="n">first</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
15370
15371     <span class="n">second</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">first</span><span class="p">)</span>
15372
15373     <span class="n">third</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">second</span><span class="p">)</span>
15374
15375     <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
15376
15377     <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
15378     
15379     <span class="n">succ</span> <span class="o">=</span> <span class="n">pred</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],)</span>
15380     
15381     <span class="n">divmod_</span> <span class="o">=</span> <span class="n">pm</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
15382
15383     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
15384 </pre></div>
15385
15386     </div>
15387 </div>
15388 </div>
15389
15390 </div>
15391 <div class="cell border-box-sizing code_cell rendered">
15392 <div class="input">
15393 <div class="prompt input_prompt">In&nbsp;[49]:</div>
15394 <div class="inner_cell">
15395     <div class="input_area">
15396 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
15397 </pre></div>
15398
15399     </div>
15400 </div>
15401 </div>
15402
15403 </div>
15404 <div class="cell border-box-sizing code_cell rendered">
15405 <div class="input">
15406 <div class="prompt input_prompt">In&nbsp;[50]:</div>
15407 <div class="inner_cell">
15408     <div class="input_area">
15409 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
15410     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
15411 </pre></div>
15412
15413     </div>
15414 </div>
15415 </div>
15416
15417 <div class="output_wrapper">
15418 <div class="output">
15419
15420
15421 <div class="output_area">
15422
15423     <div class="prompt"></div>
15424
15425
15426 <div class="output_subarea output_stream output_stdout output_text">
15427 <pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
15428 cons = (a1 [.1.] -- [a1 .1.])
15429 divmod_ = (n2 n1 -- n4 n3)
15430 dup = (a1 -- a1 a1)
15431 dupd = (a2 a1 -- a2 a2 a1)
15432 first = ([a1 .1.] -- a1)
15433 mul = (n1 n2 -- n3)
15434 over = (a2 a1 -- a2 a1 a2)
15435 pm = (n2 n1 -- n4 n3)
15436 pop = (a1 --)
15437 popd = (a2 a1 -- a1)
15438 popdd = (a3 a2 a1 -- a2 a1)
15439 popop = (a2 a1 --)
15440 pred = (n1 -- n2)
15441 rest = ([a1 .1.] -- [.1.])
15442 rolldown = (a1 a2 a3 -- a2 a3 a1)
15443 rollup = (a1 a2 a3 -- a3 a1 a2)
15444 rrest = ([a1 a2 .1.] -- [.1.])
15445 second = ([a1 a2 .1.] -- a2)
15446 sqrt = (n1 -- n2)
15447 succ = (n1 -- n2)
15448 swap = (a1 a2 -- a2 a1)
15449 swons = ([.1.] a1 -- [a1 .1.])
15450 third = ([a1 a2 a3 .1.] -- a3)
15451 tuck = (a2 a1 -- a1 a2 a1)
15452 uncons = ([a1 .1.] -- a1 [.1.])
15453 </pre>
15454 </div>
15455 </div>
15456
15457 </div>
15458 </div>
15459
15460 </div>
15461 <div class="cell border-box-sizing code_cell rendered">
15462 <div class="input">
15463 <div class="prompt input_prompt">In&nbsp;[51]:</div>
15464 <div class="inner_cell">
15465     <div class="input_area">
15466 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
15467 </pre></div>
15468
15469     </div>
15470 </div>
15471 </div>
15472
15473 </div>
15474 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15475 </div><div class="inner_cell">
15476 <div class="text_cell_render border-box-sizing rendered_html">
15477 <h4 id="Compose-dup-and-mul">Compose <code>dup</code> and <code>mul</code><a class="anchor-link" href="#Compose-dup-and-mul">&#182;</a></h4>
15478 </div>
15479 </div>
15480 </div>
15481 <div class="cell border-box-sizing code_cell rendered">
15482 <div class="input">
15483 <div class="prompt input_prompt">In&nbsp;[52]:</div>
15484 <div class="inner_cell">
15485     <div class="input_area">
15486 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
15487 </pre></div>
15488
15489     </div>
15490 </div>
15491 </div>
15492
15493 <div class="output_wrapper">
15494 <div class="output">
15495
15496
15497 <div class="output_area">
15498
15499     <div class="prompt output_prompt">Out[52]:</div>
15500
15501
15502
15503
15504 <div class="output_text output_subarea output_execute_result">
15505 <pre>((n1,), (n2,))</pre>
15506 </div>
15507
15508 </div>
15509
15510 </div>
15511 </div>
15512
15513 </div>
15514 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15515 </div><div class="inner_cell">
15516 <div class="text_cell_render border-box-sizing rendered_html">
15517 <p>Revisit the <code>F</code> function, works fine.</p>
15518
15519 </div>
15520 </div>
15521 </div>
15522 <div class="cell border-box-sizing code_cell rendered">
15523 <div class="input">
15524 <div class="prompt input_prompt">In&nbsp;[53]:</div>
15525 <div class="inner_cell">
15526     <div class="input_area">
15527 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
15528 <span class="n">F</span>
15529 </pre></div>
15530
15531     </div>
15532 </div>
15533 </div>
15534
15535 <div class="output_wrapper">
15536 <div class="output">
15537
15538
15539 <div class="output_area">
15540
15541     <div class="prompt output_prompt">Out[53]:</div>
15542
15543
15544
15545
15546 <div class="output_text output_subarea output_execute_result">
15547 <pre>(((a1, (a2, s1)), a3, a4, a5), ((a4, (a3, s1)),))</pre>
15548 </div>
15549
15550 </div>
15551
15552 </div>
15553 </div>
15554
15555 </div>
15556 <div class="cell border-box-sizing code_cell rendered">
15557 <div class="input">
15558 <div class="prompt input_prompt">In&nbsp;[54]:</div>
15559 <div class="inner_cell">
15560     <div class="input_area">
15561 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
15562 </pre></div>
15563
15564     </div>
15565 </div>
15566 </div>
15567
15568 <div class="output_wrapper">
15569 <div class="output">
15570
15571
15572 <div class="output_area">
15573
15574     <div class="prompt"></div>
15575
15576
15577 <div class="output_subarea output_stream output_stdout output_text">
15578 <pre>([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])
15579 </pre>
15580 </div>
15581 </div>
15582
15583 </div>
15584 </div>
15585
15586 </div>
15587 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15588 </div><div class="inner_cell">
15589 <div class="text_cell_render border-box-sizing rendered_html">
15590 <p>Some otherwise inefficient functions are no longer to be feared.  We can also get the effect of combinators in some limited cases.</p>
15591
15592 </div>
15593 </div>
15594 </div>
15595 <div class="cell border-box-sizing code_cell rendered">
15596 <div class="input">
15597 <div class="prompt input_prompt">In&nbsp;[55]:</div>
15598 <div class="inner_cell">
15599     <div class="input_area">
15600 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
15601     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">funcs</span><span class="p">))</span>
15602 </pre></div>
15603
15604     </div>
15605 </div>
15606 </div>
15607
15608 </div>
15609 <div class="cell border-box-sizing code_cell rendered">
15610 <div class="input">
15611 <div class="prompt input_prompt">In&nbsp;[56]:</div>
15612 <div class="inner_cell">
15613     <div class="input_area">
15614 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
15615 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">)</span>
15616 </pre></div>
15617
15618     </div>
15619 </div>
15620 </div>
15621
15622 <div class="output_wrapper">
15623 <div class="output">
15624
15625
15626 <div class="output_area">
15627
15628     <div class="prompt"></div>
15629
15630
15631 <div class="output_subarea output_stream output_stdout output_text">
15632 <pre>(a1 a2 a3 -- a2 a1 a3)
15633 </pre>
15634 </div>
15635 </div>
15636
15637 </div>
15638 </div>
15639
15640 </div>
15641 <div class="cell border-box-sizing code_cell rendered">
15642 <div class="input">
15643 <div class="prompt input_prompt">In&nbsp;[57]:</div>
15644 <div class="inner_cell">
15645     <div class="input_area">
15646 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
15647 <span class="n">neato</span><span class="p">(</span><span class="n">popdd</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">pop</span><span class="p">)</span>
15648 </pre></div>
15649
15650     </div>
15651 </div>
15652 </div>
15653
15654 <div class="output_wrapper">
15655 <div class="output">
15656
15657
15658 <div class="output_area">
15659
15660     <div class="prompt"></div>
15661
15662
15663 <div class="output_subarea output_stream output_stdout output_text">
15664 <pre>(a1 a2 a3 a4 -- a3 a4)
15665 </pre>
15666 </div>
15667 </div>
15668
15669 </div>
15670 </div>
15671
15672 </div>
15673 <div class="cell border-box-sizing code_cell rendered">
15674 <div class="input">
15675 <div class="prompt input_prompt">In&nbsp;[58]:</div>
15676 <div class="inner_cell">
15677     <div class="input_area">
15678 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
15679 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
15680 </pre></div>
15681
15682     </div>
15683 </div>
15684 </div>
15685
15686 <div class="output_wrapper">
15687 <div class="output">
15688
15689
15690 <div class="output_area">
15691
15692     <div class="prompt"></div>
15693
15694
15695 <div class="output_subarea output_stream output_stdout output_text">
15696 <pre>(a1 a2 a3 -- a3 a2 a1)
15697 </pre>
15698 </div>
15699 </div>
15700
15701 </div>
15702 </div>
15703
15704 </div>
15705 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15706 </div><div class="inner_cell">
15707 <div class="text_cell_render border-box-sizing rendered_html">
15708 <h4 id="compile_()-version-2"><code>compile_()</code> version 2<a class="anchor-link" href="#compile_()-version-2">&#182;</a></h4><p>Because the type labels represent themselves as valid Python identifiers the <code>compile_()</code> function doesn't need to generate them anymore:</p>
15709
15710 </div>
15711 </div>
15712 </div>
15713 <div class="cell border-box-sizing code_cell rendered">
15714 <div class="input">
15715 <div class="prompt input_prompt">In&nbsp;[59]:</div>
15716 <div class="inner_cell">
15717     <div class="input_area">
15718 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
15719     <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
15720     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
15721         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">)</span>
15722     <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;stack&#39;</span><span class="p">)</span>
15723     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
15724         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
15725     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
15726         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
15727     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
15728 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
15729 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
15730 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
15731 </pre></div>
15732
15733     </div>
15734 </div>
15735 </div>
15736
15737 </div>
15738 <div class="cell border-box-sizing code_cell rendered">
15739 <div class="input">
15740 <div class="prompt input_prompt">In&nbsp;[60]:</div>
15741 <div class="inner_cell">
15742     <div class="input_area">
15743 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
15744 </pre></div>
15745
15746     </div>
15747 </div>
15748 </div>
15749
15750 <div class="output_wrapper">
15751 <div class="output">
15752
15753
15754 <div class="output_area">
15755
15756     <div class="prompt"></div>
15757
15758
15759 <div class="output_subarea output_stream output_stdout output_text">
15760 <pre>def F(stack):
15761     &#34;&#34;&#34;([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])&#34;&#34;&#34;
15762     (a5, (a4, (a3, ((a1, (a2, s1)), stack)))) = stack
15763     return ((a4, (a3, s1)), stack)
15764 </pre>
15765 </div>
15766 </div>
15767
15768 </div>
15769 </div>
15770
15771 </div>
15772 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15773 </div><div class="inner_cell">
15774 <div class="text_cell_render border-box-sizing rendered_html">
15775 <p>But it cannot magically create new functions that involve e.g. math and such.  Note that this is <em>not</em> a <code>sqr</code> function implementation:</p>
15776
15777 </div>
15778 </div>
15779 </div>
15780 <div class="cell border-box-sizing code_cell rendered">
15781 <div class="input">
15782 <div class="prompt input_prompt">In&nbsp;[61]:</div>
15783 <div class="inner_cell">
15784     <div class="input_area">
15785 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;sqr&#39;</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">))</span>
15786 </pre></div>
15787
15788     </div>
15789 </div>
15790 </div>
15791
15792 <div class="output_wrapper">
15793 <div class="output">
15794
15795
15796 <div class="output_area">
15797
15798     <div class="prompt"></div>
15799
15800
15801 <div class="output_subarea output_stream output_stdout output_text">
15802 <pre>def sqr(stack):
15803     &#34;&#34;&#34;(n1 -- n2)&#34;&#34;&#34;
15804     (n1, stack) = stack
15805     return (n2, stack)
15806 </pre>
15807 </div>
15808 </div>
15809
15810 </div>
15811 </div>
15812
15813 </div>
15814 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15815 </div><div class="inner_cell">
15816 <div class="text_cell_render border-box-sizing rendered_html">
15817 <p>(Eventually I should come back around to this becuase it's not tooo difficult to exend this code to be able to compile e.g. <code>n2 = mul(n1, n1)</code> for <code>mul</code> with the right variable names and insert it in the right place.  It requires a little more support from the library functions, in that we need to know to call <code>mul()</code> the Python function for <code>mul</code> the Joy function, but since <em>most</em> of the math functions (at least) are already wrappers it should be straightforward.)</p>
15818
15819 </div>
15820 </div>
15821 </div>
15822 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15823 </div><div class="inner_cell">
15824 <div class="text_cell_render border-box-sizing rendered_html">
15825 <h4 id="compilable()"><code>compilable()</code><a class="anchor-link" href="#compilable()">&#182;</a></h4><p>The functions that <em>can</em> be compiled are the ones that have only <code>AnyJoyType</code> and <code>StackJoyType</code> labels in their stack effect comments.  We can write a function to check that:</p>
15826
15827 </div>
15828 </div>
15829 </div>
15830 <div class="cell border-box-sizing code_cell rendered">
15831 <div class="input">
15832 <div class="prompt input_prompt">In&nbsp;[62]:</div>
15833 <div class="inner_cell">
15834     <div class="input_area">
15835 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">imap</span>
15836
15837
15838 <span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
15839     <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">all</span><span class="p">(</span><span class="n">imap</span><span class="p">(</span><span class="n">compilable</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span> <span class="ow">or</span> <span class="n">stacky</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
15840 </pre></div>
15841
15842     </div>
15843 </div>
15844 </div>
15845
15846 </div>
15847 <div class="cell border-box-sizing code_cell rendered">
15848 <div class="input">
15849 <div class="prompt input_prompt">In&nbsp;[63]:</div>
15850 <div class="inner_cell">
15851     <div class="input_area">
15852 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
15853     <span class="k">if</span> <span class="n">compilable</span><span class="p">(</span><span class="n">stack_effect_comment</span><span class="p">):</span>
15854         <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
15855 </pre></div>
15856
15857     </div>
15858 </div>
15859 </div>
15860
15861 <div class="output_wrapper">
15862 <div class="output">
15863
15864
15865 <div class="output_area">
15866
15867     <div class="prompt"></div>
15868
15869
15870 <div class="output_subarea output_stream output_stdout output_text">
15871 <pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
15872 cons = (a1 [.1.] -- [a1 .1.])
15873 dup = (a1 -- a1 a1)
15874 dupd = (a2 a1 -- a2 a2 a1)
15875 first = ([a1 .1.] -- a1)
15876 over = (a2 a1 -- a2 a1 a2)
15877 pop = (a1 --)
15878 popd = (a2 a1 -- a1)
15879 popdd = (a3 a2 a1 -- a2 a1)
15880 popop = (a2 a1 --)
15881 rest = ([a1 .1.] -- [.1.])
15882 rolldown = (a1 a2 a3 -- a2 a3 a1)
15883 rollup = (a1 a2 a3 -- a3 a1 a2)
15884 rrest = ([a1 a2 .1.] -- [.1.])
15885 second = ([a1 a2 .1.] -- a2)
15886 swap = (a1 a2 -- a2 a1)
15887 swons = ([.1.] a1 -- [a1 .1.])
15888 third = ([a1 a2 a3 .1.] -- a3)
15889 tuck = (a2 a1 -- a1 a2 a1)
15890 uncons = ([a1 .1.] -- a1 [.1.])
15891 </pre>
15892 </div>
15893 </div>
15894
15895 </div>
15896 </div>
15897
15898 </div>
15899 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15900 </div><div class="inner_cell">
15901 <div class="text_cell_render border-box-sizing rendered_html">
15902 <h2 id="Part-V:-Functions-that-use-the-Stack">Part V: Functions that use the Stack<a class="anchor-link" href="#Part-V:-Functions-that-use-the-Stack">&#182;</a></h2><p>Consider the <code>stack</code> function which grabs the whole stack, quotes it, and puts it on itself:</p>
15903
15904 <pre><code>stack (...     -- ... [...]        )
15905 stack (... a   -- ... a [a ...]    )
15906 stack (... b a -- ... b a [a b ...])
15907
15908 </code></pre>
15909 <p>We would like to represent this in Python somehow. 
15910 To do this we use a simple, elegant trick.</p>
15911
15912 <pre><code>stack         S   -- (         S,           S)
15913 stack     (a, S)  -- (     (a, S),      (a, S))
15914 stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
15915
15916 </code></pre>
15917 <p>Instead of representing the stack effect comments as a single tuple (with N items in it) we use the same cons-list structure to hold the sequence and <code>unify()</code> the whole comments.</p>
15918
15919 </div>
15920 </div>
15921 </div>
15922 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15923 </div><div class="inner_cell">
15924 <div class="text_cell_render border-box-sizing rendered_html">
15925 <h3 id="stack&#8728;uncons"><code>stack&#8728;uncons</code><a class="anchor-link" href="#stack&#8728;uncons">&#182;</a></h3><p>Let's try composing <code>stack</code> and <code>uncons</code>.  We want this result:</p>
15926
15927 <pre><code>stack∘uncons (... a -- ... a a [...])</code></pre>
15928
15929 </div>
15930 </div>
15931 </div>
15932 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15933 </div><div class="inner_cell">
15934 <div class="text_cell_render border-box-sizing rendered_html">
15935 <p>The stack effects are:</p>
15936
15937 <pre><code>stack = S -- (S, S)
15938
15939 uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
15940
15941 </div>
15942 </div>
15943 </div>
15944 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15945 </div><div class="inner_cell">
15946 <div class="text_cell_render border-box-sizing rendered_html">
15947 <p>Unifying:</p>
15948
15949 <pre><code>  S    -- (S, S) ∘ ((a, Z), S) -- (Z, (a,   S   ))
15950                                                     w/ { S: (a, Z) }
15951 (a, Z) --        ∘             -- (Z, (a, (a, Z)))
15952
15953 </code></pre>
15954 <p>So:</p>
15955
15956 <pre><code>stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
15957
15958 </code></pre>
15959 <p>It works.</p>
15960
15961 </div>
15962 </div>
15963 </div>
15964 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15965 </div><div class="inner_cell">
15966 <div class="text_cell_render border-box-sizing rendered_html">
15967 <h3 id="stack&#8728;uncons&#8728;uncons"><code>stack&#8728;uncons&#8728;uncons</code><a class="anchor-link" href="#stack&#8728;uncons&#8728;uncons">&#182;</a></h3><p>Let's try <code>stack∘uncons∘uncons</code>:</p>
15968
15969 <pre><code>(a, S     ) -- (S,      (a, (a, S     ))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
15970
15971                                                                                 w/ { S: (b, Z) }
15972
15973 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
15974
15975                                                                                 w/ { S`: (a, (a, (b, Z))) }
15976
15977 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
15978
15979 (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
15980
15981 </code></pre>
15982 <p>It works.</p>
15983
15984 </div>
15985 </div>
15986 </div>
15987 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15988 </div><div class="inner_cell">
15989 <div class="text_cell_render border-box-sizing rendered_html">
15990 <h4 id="compose()-version-2"><code>compose()</code> version 2<a class="anchor-link" href="#compose()-version-2">&#182;</a></h4><p>This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.  (One easy way to see this is that now an empty stack effect comment is represented by a <code>StackJoyType</code> instance which is not "falsey" and so neither of the first two rules' <code>if</code> clauses will ever be <code>True</code>.  Later on I change the "truthiness" of <code>StackJoyType</code> to false to let e.g. <code>joy.utils.stack.concat</code> work with our stack effect comment cons-list tuples.)</p>
15991
15992 </div>
15993 </div>
15994 </div>
15995 <div class="cell border-box-sizing code_cell rendered">
15996 <div class="input">
15997 <div class="prompt input_prompt">In&nbsp;[64]:</div>
15998 <div class="inner_cell">
15999     <div class="input_area">
16000 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
16001     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
16002     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
16003     <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>  <span class="c1"># s can also be the empty dict, which is ok.</span>
16004         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
16005     <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
16006 </pre></div>
16007
16008     </div>
16009 </div>
16010 </div>
16011
16012 </div>
16013 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16014 </div><div class="inner_cell">
16015 <div class="text_cell_render border-box-sizing rendered_html">
16016 <p>I don't want to rewrite all the defs myself, so I'll write a little conversion function instead.  This is programmer's laziness.</p>
16017
16018 </div>
16019 </div>
16020 </div>
16021 <div class="cell border-box-sizing code_cell rendered">
16022 <div class="input">
16023 <div class="prompt input_prompt">In&nbsp;[65]:</div>
16024 <div class="inner_cell">
16025     <div class="input_area">
16026 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
16027     <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
16028     <span class="k">return</span> <span class="n">stack</span>
16029
16030 <span class="n">NEW_DEFS</span> <span class="o">=</span> <span class="p">{</span>
16031     <span class="n">name</span><span class="p">:</span> <span class="p">(</span><span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">o</span><span class="p">))</span>
16032     <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span> <span class="ow">in</span> <span class="n">DEFS</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()</span>
16033 <span class="p">}</span>
16034 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">&#39;stack&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
16035 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">&#39;swaack&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
16036 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="p">)</span>
16037 </pre></div>
16038
16039     </div>
16040 </div>
16041 </div>
16042
16043 </div>
16044 <div class="cell border-box-sizing code_cell rendered">
16045 <div class="input">
16046 <div class="prompt input_prompt">In&nbsp;[66]:</div>
16047 <div class="inner_cell">
16048     <div class="input_area">
16049 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
16050 </pre></div>
16051
16052     </div>
16053 </div>
16054 </div>
16055
16056 <div class="output_wrapper">
16057 <div class="output">
16058
16059
16060 <div class="output_area">
16061
16062     <div class="prompt output_prompt">Out[66]:</div>
16063
16064
16065
16066
16067 <div class="output_text output_subarea output_execute_result">
16068 <pre>((a1, s1), (s1, (a1, (a1, s1))))</pre>
16069 </div>
16070
16071 </div>
16072
16073 </div>
16074 </div>
16075
16076 </div>
16077 <div class="cell border-box-sizing code_cell rendered">
16078 <div class="input">
16079 <div class="prompt input_prompt">In&nbsp;[67]:</div>
16080 <div class="inner_cell">
16081     <div class="input_area">
16082 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
16083 </pre></div>
16084
16085     </div>
16086 </div>
16087 </div>
16088
16089 <div class="output_wrapper">
16090 <div class="output">
16091
16092
16093 <div class="output_area">
16094
16095     <div class="prompt output_prompt">Out[67]:</div>
16096
16097
16098
16099
16100 <div class="output_text output_subarea output_execute_result">
16101 <pre>((a1, (a2, s1)), (s1, (a2, (a1, (a1, (a2, s1))))))</pre>
16102 </div>
16103
16104 </div>
16105
16106 </div>
16107 </div>
16108
16109 </div>
16110 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16111 </div><div class="inner_cell">
16112 <div class="text_cell_render border-box-sizing rendered_html">
16113 <p>The display function should be changed too.</p>
16114
16115 </div>
16116 </div>
16117 </div>
16118 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16119 </div><div class="inner_cell">
16120 <div class="text_cell_render border-box-sizing rendered_html">
16121 <h3 id="doc_from_stack_effect()-version-2"><code>doc_from_stack_effect()</code> version 2<a class="anchor-link" href="#doc_from_stack_effect()-version-2">&#182;</a></h3><p>Clunky junk, but it will suffice for now.</p>
16122
16123 </div>
16124 </div>
16125 </div>
16126 <div class="cell border-box-sizing code_cell rendered">
16127 <div class="input">
16128 <div class="prompt input_prompt">In&nbsp;[68]:</div>
16129 <div class="inner_cell">
16130     <div class="input_area">
16131 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
16132     <span class="n">switch</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span>  <span class="c1"># Do we need to display the &#39;...&#39; for the rest of the main stack?</span>
16133     <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">_f</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">),</span> <span class="n">_f</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span>
16134     <span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
16135         <span class="n">i</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
16136         <span class="n">o</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
16137     <span class="k">return</span> <span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span>
16138         <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">reversed</span><span class="p">([</span><span class="s1">&#39;&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">i</span><span class="p">)),</span>
16139         <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">o</span> <span class="o">+</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">])),</span>
16140     <span class="p">)</span>
16141
16142
16143 <span class="k">def</span> <span class="nf">_f</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
16144     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
16145     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
16146         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
16147         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
16148     <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
16149     <span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="n">_to_str</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">a</span><span class="p">]</span>
16150     <span class="k">return</span> <span class="n">a</span>
16151
16152
16153 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
16154     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
16155         <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
16156             <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
16157             <span class="k">return</span> <span class="s1">&#39;[...]&#39;</span>
16158         <span class="k">return</span> <span class="p">(</span>
16159             <span class="s1">&#39;[.</span><span class="si">%i</span><span class="s1">.]&#39;</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
16160             <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">)</span>
16161             <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
16162         <span class="p">)</span>
16163
16164     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
16165     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
16166         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
16167         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">))</span>
16168     <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
16169     <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
16170         <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
16171         <span class="n">end</span> <span class="o">=</span> <span class="s1">&#39;...&#39;</span>
16172     <span class="k">else</span><span class="p">:</span>
16173         <span class="n">end</span> <span class="o">=</span> <span class="s1">&#39;.</span><span class="si">%i</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
16174     <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">end</span><span class="p">)</span>
16175     <span class="k">return</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
16176 </pre></div>
16177
16178     </div>
16179 </div>
16180 </div>
16181
16182 </div>
16183 <div class="cell border-box-sizing code_cell rendered">
16184 <div class="input">
16185 <div class="prompt input_prompt">In&nbsp;[69]:</div>
16186 <div class="inner_cell">
16187     <div class="input_area">
16188 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
16189     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
16190 </pre></div>
16191
16192     </div>
16193 </div>
16194 </div>
16195
16196 <div class="output_wrapper">
16197 <div class="output">
16198
16199
16200 <div class="output_area">
16201
16202     <div class="prompt"></div>
16203
16204
16205 <div class="output_subarea output_stream output_stdout output_text">
16206 <pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
16207 cons = (a1 [.1.] -- [a1 .1.])
16208 divmod_ = (n2 n1 -- n4 n3)
16209 dup = (a1 -- a1 a1)
16210 dupd = (a2 a1 -- a2 a2 a1)
16211 first = ([a1 .1.] -- a1)
16212 mul = (n1 n2 -- n3)
16213 over = (a2 a1 -- a2 a1 a2)
16214 pm = (n2 n1 -- n4 n3)
16215 pop = (a1 --)
16216 popd = (a2 a1 -- a1)
16217 popdd = (a3 a2 a1 -- a2 a1)
16218 popop = (a2 a1 --)
16219 pred = (n1 -- n2)
16220 rest = ([a1 .1.] -- [.1.])
16221 rolldown = (a1 a2 a3 -- a2 a3 a1)
16222 rollup = (a1 a2 a3 -- a3 a1 a2)
16223 rrest = ([a1 a2 .1.] -- [.1.])
16224 second = ([a1 a2 .1.] -- a2)
16225 sqrt = (n1 -- n2)
16226 stack = (... -- ... [...])
16227 succ = (n1 -- n2)
16228 swaack = ([.1.] -- [.0.])
16229 swap = (a1 a2 -- a2 a1)
16230 swons = ([.1.] a1 -- [a1 .1.])
16231 third = ([a1 a2 a3 .1.] -- a3)
16232 tuck = (a2 a1 -- a1 a2 a1)
16233 uncons = ([a1 .1.] -- a1 [.1.])
16234 </pre>
16235 </div>
16236 </div>
16237
16238 </div>
16239 </div>
16240
16241 </div>
16242 <div class="cell border-box-sizing code_cell rendered">
16243 <div class="input">
16244 <div class="prompt input_prompt">In&nbsp;[70]:</div>
16245 <div class="inner_cell">
16246     <div class="input_area">
16247 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
16248 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
16249 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
16250 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
16251 </pre></div>
16252
16253     </div>
16254 </div>
16255 </div>
16256
16257 <div class="output_wrapper">
16258 <div class="output">
16259
16260
16261 <div class="output_area">
16262
16263     <div class="prompt"></div>
16264
16265
16266 <div class="output_subarea output_stream output_stdout output_text">
16267 <pre>
16268 (... -- ... [...])
16269
16270 (... a1 -- ... a1 a1 [...])
16271
16272 (... a2 a1 -- ... a2 a1 a1 a2 [...])
16273
16274 (... a1 -- ... a1 [a1 ...])
16275 </pre>
16276 </div>
16277 </div>
16278
16279 </div>
16280 </div>
16281
16282 </div>
16283 <div class="cell border-box-sizing code_cell rendered">
16284 <div class="input">
16285 <div class="prompt input_prompt">In&nbsp;[71]:</div>
16286 <div class="inner_cell">
16287     <div class="input_area">
16288 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
16289 </pre></div>
16290
16291     </div>
16292 </div>
16293 </div>
16294
16295 <div class="output_wrapper">
16296 <div class="output">
16297
16298
16299 <div class="output_area">
16300
16301     <div class="prompt"></div>
16302
16303
16304 <div class="output_subarea output_stream output_stdout output_text">
16305 <pre>(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
16306 </pre>
16307 </div>
16308 </div>
16309
16310 </div>
16311 </div>
16312
16313 </div>
16314 <div class="cell border-box-sizing code_cell rendered">
16315 <div class="input">
16316 <div class="prompt input_prompt">In&nbsp;[72]:</div>
16317 <div class="inner_cell">
16318     <div class="input_area">
16319 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
16320
16321 <span class="n">Q</span>
16322 </pre></div>
16323
16324     </div>
16325 </div>
16326 </div>
16327
16328 <div class="output_wrapper">
16329 <div class="output">
16330
16331
16332 <div class="output_area">
16333
16334     <div class="prompt output_prompt">Out[72]:</div>
16335
16336
16337
16338
16339 <div class="output_text output_subarea output_execute_result">
16340 <pre>((s1, (a1, (a2, s2))), (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2)))</pre>
16341 </div>
16342
16343 </div>
16344
16345 </div>
16346 </div>
16347
16348 </div>
16349 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16350 </div><div class="inner_cell">
16351 <div class="text_cell_render border-box-sizing rendered_html">
16352 <h4 id="compile_()-version-3"><code>compile_()</code> version 3<a class="anchor-link" href="#compile_()-version-3">&#182;</a></h4><p>This makes the <code>compile_()</code> function pretty simple as the stack effect comments are now already in the form needed for the Python code:</p>
16353
16354 </div>
16355 </div>
16356 </div>
16357 <div class="cell border-box-sizing code_cell rendered">
16358 <div class="input">
16359 <div class="prompt input_prompt">In&nbsp;[73]:</div>
16360 <div class="inner_cell">
16361     <div class="input_area">
16362 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
16363     <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
16364     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
16365         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
16366     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
16367 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
16368 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
16369 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
16370 </pre></div>
16371
16372     </div>
16373 </div>
16374 </div>
16375
16376 </div>
16377 <div class="cell border-box-sizing code_cell rendered">
16378 <div class="input">
16379 <div class="prompt input_prompt">In&nbsp;[74]:</div>
16380 <div class="inner_cell">
16381     <div class="input_area">
16382 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;Q&#39;</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
16383 </pre></div>
16384
16385     </div>
16386 </div>
16387 </div>
16388
16389 <div class="output_wrapper">
16390 <div class="output">
16391
16392
16393 <div class="output_area">
16394
16395     <div class="prompt"></div>
16396
16397
16398 <div class="output_subarea output_stream output_stdout output_text">
16399 <pre>def Q(stack):
16400     &#34;&#34;&#34;(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])&#34;&#34;&#34;
16401     (s1, (a1, (a2, s2))) = stack
16402     return (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2))
16403 </pre>
16404 </div>
16405 </div>
16406
16407 </div>
16408 </div>
16409
16410 </div>
16411 <div class="cell border-box-sizing code_cell rendered">
16412 <div class="input">
16413 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16414 <div class="inner_cell">
16415     <div class="input_area">
16416 <div class=" highlight hl-ipython2"><pre><span></span> 
16417 </pre></div>
16418
16419     </div>
16420 </div>
16421 </div>
16422
16423 </div>
16424 <div class="cell border-box-sizing code_cell rendered">
16425 <div class="input">
16426 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16427 <div class="inner_cell">
16428     <div class="input_area">
16429 <div class=" highlight hl-ipython2"><pre><span></span> 
16430 </pre></div>
16431
16432     </div>
16433 </div>
16434 </div>
16435
16436 </div>
16437 <div class="cell border-box-sizing code_cell rendered">
16438 <div class="input">
16439 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16440 <div class="inner_cell">
16441     <div class="input_area">
16442 <div class=" highlight hl-ipython2"><pre><span></span> 
16443 </pre></div>
16444
16445     </div>
16446 </div>
16447 </div>
16448
16449 </div>
16450 <div class="cell border-box-sizing code_cell rendered">
16451 <div class="input">
16452 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16453 <div class="inner_cell">
16454     <div class="input_area">
16455 <div class=" highlight hl-ipython2"><pre><span></span> 
16456 </pre></div>
16457
16458     </div>
16459 </div>
16460 </div>
16461
16462 </div>
16463 <div class="cell border-box-sizing code_cell rendered">
16464 <div class="input">
16465 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16466 <div class="inner_cell">
16467     <div class="input_area">
16468 <div class=" highlight hl-ipython2"><pre><span></span> 
16469 </pre></div>
16470
16471     </div>
16472 </div>
16473 </div>
16474
16475 </div>
16476 <div class="cell border-box-sizing code_cell rendered">
16477 <div class="input">
16478 <div class="prompt input_prompt">In&nbsp;[75]:</div>
16479 <div class="inner_cell">
16480     <div class="input_area">
16481 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
16482 <span class="n">enstacken</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
16483 </pre></div>
16484
16485     </div>
16486 </div>
16487 </div>
16488
16489 </div>
16490 <div class="cell border-box-sizing code_cell rendered">
16491 <div class="input">
16492 <div class="prompt input_prompt">In&nbsp;[76]:</div>
16493 <div class="inner_cell">
16494     <div class="input_area">
16495 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
16496 </pre></div>
16497
16498     </div>
16499 </div>
16500 </div>
16501
16502 <div class="output_wrapper">
16503 <div class="output">
16504
16505
16506 <div class="output_area">
16507
16508     <div class="prompt"></div>
16509
16510
16511 <div class="output_subarea output_stream output_stdout output_text">
16512 <pre>([.1.] --)
16513 </pre>
16514 </div>
16515 </div>
16516
16517 </div>
16518 </div>
16519
16520 </div>
16521 <div class="cell border-box-sizing code_cell rendered">
16522 <div class="input">
16523 <div class="prompt input_prompt">In&nbsp;[77]:</div>
16524 <div class="inner_cell">
16525     <div class="input_area">
16526 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
16527 </pre></div>
16528
16529     </div>
16530 </div>
16531 </div>
16532
16533 <div class="output_wrapper">
16534 <div class="output">
16535
16536
16537 <div class="output_area">
16538
16539     <div class="prompt"></div>
16540
16541
16542 <div class="output_subarea output_stream output_stdout output_text">
16543 <pre>(-- [.0.])
16544 </pre>
16545 </div>
16546 </div>
16547
16548 </div>
16549 </div>
16550
16551 </div>
16552 <div class="cell border-box-sizing code_cell rendered">
16553 <div class="input">
16554 <div class="prompt input_prompt">In&nbsp;[78]:</div>
16555 <div class="inner_cell">
16556     <div class="input_area">
16557 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
16558 </pre></div>
16559
16560     </div>
16561 </div>
16562 </div>
16563
16564 <div class="output_wrapper">
16565 <div class="output">
16566
16567
16568 <div class="output_area">
16569
16570     <div class="prompt"></div>
16571
16572
16573 <div class="output_subarea output_stream output_stdout output_text">
16574 <pre>(a1 [.1.] -- a1)
16575 </pre>
16576 </div>
16577 </div>
16578
16579 </div>
16580 </div>
16581
16582 </div>
16583 <div class="cell border-box-sizing code_cell rendered">
16584 <div class="input">
16585 <div class="prompt input_prompt">In&nbsp;[79]:</div>
16586 <div class="inner_cell">
16587     <div class="input_area">
16588 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
16589 </pre></div>
16590
16591     </div>
16592 </div>
16593 </div>
16594
16595 <div class="output_wrapper">
16596 <div class="output">
16597
16598
16599 <div class="output_area">
16600
16601     <div class="prompt"></div>
16602
16603
16604 <div class="output_subarea output_stream output_stdout output_text">
16605 <pre>(a1 [.1.] -- [[a1 .1.] .2.])
16606 </pre>
16607 </div>
16608 </div>
16609
16610 </div>
16611 </div>
16612
16613 </div>
16614 <div class="cell border-box-sizing code_cell rendered">
16615 <div class="input">
16616 <div class="prompt input_prompt">In&nbsp;[80]:</div>
16617 <div class="inner_cell">
16618     <div class="input_area">
16619 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
16620 </pre></div>
16621
16622     </div>
16623 </div>
16624 </div>
16625
16626 <div class="output_wrapper">
16627 <div class="output">
16628
16629
16630 <div class="output_area">
16631
16632     <div class="prompt output_prompt">Out[80]:</div>
16633
16634
16635
16636
16637 <div class="output_text output_subarea output_execute_result">
16638 <pre>((s1, (a1, s2)), (a1, s1))</pre>
16639 </div>
16640
16641 </div>
16642
16643 </div>
16644 </div>
16645
16646 </div>
16647 <div class="cell border-box-sizing code_cell rendered">
16648 <div class="input">
16649 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
16650 <div class="inner_cell">
16651     <div class="input_area">
16652 <div class=" highlight hl-ipython2"><pre><span></span> 
16653 </pre></div>
16654
16655     </div>
16656 </div>
16657 </div>
16658
16659 </div>
16660 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16661 </div><div class="inner_cell">
16662 <div class="text_cell_render border-box-sizing rendered_html">
16663 <h2 id="Part-VI:-Multiple-Stack-Effects">Part VI: Multiple Stack Effects<a class="anchor-link" href="#Part-VI:-Multiple-Stack-Effects">&#182;</a></h2><p>...</p>
16664
16665 </div>
16666 </div>
16667 </div>
16668 <div class="cell border-box-sizing code_cell rendered">
16669 <div class="input">
16670 <div class="prompt input_prompt">In&nbsp;[81]:</div>
16671 <div class="inner_cell">
16672     <div class="input_area">
16673 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;i&#39;</span>
16674
16675
16676 <span class="n">F</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
16677 <span class="n">I</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">IntJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
16678 </pre></div>
16679
16680     </div>
16681 </div>
16682 </div>
16683
16684 </div>
16685 <div class="cell border-box-sizing code_cell rendered">
16686 <div class="input">
16687 <div class="prompt input_prompt">In&nbsp;[82]:</div>
16688 <div class="inner_cell">
16689     <div class="input_area">
16690 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
16691      <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
16692      <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
16693      <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
16694      <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
16695 <span class="p">]</span>
16696 </pre></div>
16697
16698     </div>
16699 </div>
16700 </div>
16701
16702 </div>
16703 <div class="cell border-box-sizing code_cell rendered">
16704 <div class="input">
16705 <div class="prompt input_prompt">In&nbsp;[83]:</div>
16706 <div class="inner_cell">
16707     <div class="input_area">
16708 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
16709     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
16710 </pre></div>
16711
16712     </div>
16713 </div>
16714 </div>
16715
16716 <div class="output_wrapper">
16717 <div class="output">
16718
16719
16720 <div class="output_area">
16721
16722     <div class="prompt"></div>
16723
16724
16725 <div class="output_subarea output_stream output_stdout output_text">
16726 <pre>(i1 i2 -- i3)
16727 (i1 f2 -- f3)
16728 (f1 i2 -- f3)
16729 (f1 f2 -- f3)
16730 </pre>
16731 </div>
16732 </div>
16733
16734 </div>
16735 </div>
16736
16737 </div>
16738 <div class="cell border-box-sizing code_cell rendered">
16739 <div class="input">
16740 <div class="prompt input_prompt">In&nbsp;[84]:</div>
16741 <div class="inner_cell">
16742     <div class="input_area">
16743 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
16744     <span class="k">try</span><span class="p">:</span>
16745         <span class="n">e</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
16746     <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
16747         <span class="k">continue</span>
16748     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">dup</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">e</span><span class="p">)</span>
16749 </pre></div>
16750
16751     </div>
16752 </div>
16753 </div>
16754
16755 <div class="output_wrapper">
16756 <div class="output">
16757
16758
16759 <div class="output_area">
16760
16761     <div class="prompt"></div>
16762
16763
16764 <div class="output_subarea output_stream output_stdout output_text">
16765 <pre>(a1 -- a1 a1) (i1 i2 -- i3) (i1 -- i2)
16766 (a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
16767 </pre>
16768 </div>
16769 </div>
16770
16771 </div>
16772 </div>
16773
16774 </div>
16775 <div class="cell border-box-sizing code_cell rendered">
16776 <div class="input">
16777 <div class="prompt input_prompt">In&nbsp;[85]:</div>
16778 <div class="inner_cell">
16779     <div class="input_area">
16780 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
16781
16782
16783 <span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
16784     <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
16785         <span class="k">try</span><span class="p">:</span>
16786             <span class="k">yield</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
16787         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
16788             <span class="k">pass</span>
16789
16790
16791 <span class="k">def</span> <span class="nf">MC</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
16792     <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">)))</span>
16793 </pre></div>
16794
16795     </div>
16796 </div>
16797 </div>
16798
16799 </div>
16800 <div class="cell border-box-sizing code_cell rendered">
16801 <div class="input">
16802 <div class="prompt input_prompt">In&nbsp;[86]:</div>
16803 <div class="inner_cell">
16804     <div class="input_area">
16805 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
16806     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
16807 </pre></div>
16808
16809     </div>
16810 </div>
16811 </div>
16812
16813 <div class="output_wrapper">
16814 <div class="output">
16815
16816
16817 <div class="output_area">
16818
16819     <div class="prompt"></div>
16820
16821
16822 <div class="output_subarea output_stream output_stdout output_text">
16823 <pre>(n1 -- n2)
16824 </pre>
16825 </div>
16826 </div>
16827
16828 </div>
16829 </div>
16830
16831 </div>
16832 <div class="cell border-box-sizing code_cell rendered">
16833 <div class="input">
16834 <div class="prompt input_prompt">In&nbsp;[87]:</div>
16835 <div class="inner_cell">
16836     <div class="input_area">
16837 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
16838     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
16839 </pre></div>
16840
16841     </div>
16842 </div>
16843 </div>
16844
16845 <div class="output_wrapper">
16846 <div class="output">
16847
16848
16849 <div class="output_area">
16850
16851     <div class="prompt"></div>
16852
16853
16854 <div class="output_subarea output_stream output_stdout output_text">
16855 <pre>(f1 -- f2)
16856 (i1 -- i2)
16857 </pre>
16858 </div>
16859 </div>
16860
16861 </div>
16862 </div>
16863
16864 </div>
16865 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16866 </div><div class="inner_cell">
16867 <div class="text_cell_render border-box-sizing rendered_html">
16868 <h3 id="Representing-an-Unbounded-Sequence-of-Types">Representing an Unbounded Sequence of Types<a class="anchor-link" href="#Representing-an-Unbounded-Sequence-of-Types">&#182;</a></h3><p>We can borrow a trick from <a href="https://en.wikipedia.org/wiki/Brzozowski_derivative">Brzozowski's Derivatives of Regular Expressions</a> to invent a new type of type variable, a "sequence type" (I think this is what they mean in the literature by that term...) or "<a href="https://en.wikipedia.org/wiki/Kleene_star">Kleene Star</a>" type.  I'm going to represent it as a type letter and the asterix, so a sequence of zero or more <code>AnyJoyType</code> variables would be:</p>
16869
16870 <pre><code>A*</code></pre>
16871
16872 </div>
16873 </div>
16874 </div>
16875 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16876 </div><div class="inner_cell">
16877 <div class="text_cell_render border-box-sizing rendered_html">
16878 <p>The <code>A*</code> works by splitting the universe into two alternate histories:</p>
16879
16880 <pre><code>A* -&gt; 0 | A A*
16881
16882 </code></pre>
16883 <p>The Kleene star variable disappears in one universe, and in the other it turns into an <code>AnyJoyType</code> variable followed by itself again.  We have to return all universes (represented by their substitution dicts, the "unifiers") that don't lead to type conflicts.</p>
16884
16885 </div>
16886 </div>
16887 </div>
16888 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16889 </div><div class="inner_cell">
16890 <div class="text_cell_render border-box-sizing rendered_html">
16891 <p>Consider unifying two stacks (the lowercase letters are any type variables of the kinds we have defined so far):</p>
16892
16893 <pre><code>[a A* b .0.] U [c d .1.]
16894                           w/ {c: a}
16895 [  A* b .0.] U [  d .1.]</code></pre>
16896
16897 </div>
16898 </div>
16899 </div>
16900 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16901 </div><div class="inner_cell">
16902 <div class="text_cell_render border-box-sizing rendered_html">
16903 <p>Now we have to split universes to unify <code>A*</code>.  In the first universe it disappears:</p>
16904
16905 <pre><code>[b .0.] U [d .1.]
16906                    w/ {d: b, .1.: .0.} 
16907      [] U []</code></pre>
16908
16909 </div>
16910 </div>
16911 </div>
16912 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16913 </div><div class="inner_cell">
16914 <div class="text_cell_render border-box-sizing rendered_html">
16915 <p>While in the second it spawns an <code>A</code>, which we will label <code>e</code>:</p>
16916
16917 <pre><code>[e A* b .0.] U [d .1.]
16918                         w/ {d: e}
16919 [  A* b .0.] U [  .1.]
16920                         w/ {.1.: A* b .0.}
16921 [  A* b .0.] U [  A* b .0.]</code></pre>
16922
16923 </div>
16924 </div>
16925 </div>
16926 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16927 </div><div class="inner_cell">
16928 <div class="text_cell_render border-box-sizing rendered_html">
16929 <p>Giving us two unifiers:</p>
16930
16931 <pre><code>{c: a,  d: b,  .1.:      .0.}
16932 {c: a,  d: e,  .1.: A* b .0.}</code></pre>
16933
16934 </div>
16935 </div>
16936 </div>
16937 <div class="cell border-box-sizing code_cell rendered">
16938 <div class="input">
16939 <div class="prompt input_prompt">In&nbsp;[88]:</div>
16940 <div class="inner_cell">
16941     <div class="input_area">
16942 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
16943
16944     <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
16945
16946     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
16947         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
16948         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
16949         <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
16950
16951     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
16952         <span class="k">return</span> <span class="s1">&#39;</span><span class="si">%s%i</span><span class="s1">*&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="o">.</span><span class="n">prefix</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
16953
16954     <span class="k">def</span> <span class="nf">another</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
16955         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
16956         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="p">(</span><span class="mi">10000</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>
16957
16958     <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
16959         <span class="k">return</span> <span class="p">(</span>
16960             <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
16961             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
16962         <span class="p">)</span>
16963
16964     <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
16965         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span> <span class="o">&gt;=</span> <span class="n">other</span><span class="o">.</span><span class="n">kind</span>
16966
16967     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
16968         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
16969     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
16970     
16971     <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
16972         <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
16973
16974 <span class="k">class</span> <span class="nc">AnyStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
16975 <span class="k">class</span> <span class="nc">NumberStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">NumberJoyType</span>
16976 <span class="c1">#class FloatStarJoyType(KleeneStar): kind = FloatJoyType</span>
16977 <span class="c1">#class IntStarJoyType(KleeneStar): kind = IntJoyType</span>
16978 <span class="k">class</span> <span class="nc">StackStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">StackJoyType</span>
16979
16980
16981 <span class="n">As</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
16982 <span class="n">Ns</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
16983 <span class="n">Ss</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
16984 </pre></div>
16985
16986     </div>
16987 </div>
16988 </div>
16989
16990 </div>
16991 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16992 </div><div class="inner_cell">
16993 <div class="text_cell_render border-box-sizing rendered_html">
16994 <h4 id="unify()-version-4"><code>unify()</code> version 4<a class="anchor-link" href="#unify()-version-4">&#182;</a></h4><p>Can now return multiple results...</p>
16995
16996 </div>
16997 </div>
16998 </div>
16999 <div class="cell border-box-sizing code_cell rendered">
17000 <div class="input">
17001 <div class="prompt input_prompt">In&nbsp;[89]:</div>
17002 <div class="inner_cell">
17003     <div class="input_area">
17004 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
17005     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
17006         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
17007     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
17008         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
17009         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
17010
17011     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
17012         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
17013
17014     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">):</span>
17015         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
17016             <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
17017             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
17018         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
17019             <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
17020             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
17021         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
17022
17023     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
17024         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
17025             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
17026             
17027         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">v</span>
17028         <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
17029             <span class="c1"># Two universes, in one the Kleene star disappears and unification</span>
17030             <span class="c1"># continues without it...</span>
17031             <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
17032             
17033             <span class="c1"># In the other it spawns a new variable.</span>
17034             <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">v</span><span class="p">))</span>
17035             
17036             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
17037             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
17038                 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
17039             <span class="k">return</span> <span class="n">t</span>
17040
17041         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">u</span>
17042         <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
17043             <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
17044             <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">u</span><span class="p">))</span>
17045             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
17046             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
17047                 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
17048             <span class="k">return</span> <span class="n">t</span>
17049
17050         <span class="n">ses</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
17051         <span class="n">results</span> <span class="o">=</span> <span class="p">()</span>
17052         <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">ses</span><span class="p">:</span>
17053             <span class="n">results</span> <span class="o">+=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">sn</span><span class="p">)</span>
17054         <span class="k">return</span> <span class="n">results</span>
17055  
17056     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
17057         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
17058             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
17059         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
17060         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
17061
17062     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
17063         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
17064             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
17065         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
17066         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
17067
17068     <span class="k">return</span> <span class="p">()</span>
17069
17070
17071 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
17072     <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
17073 </pre></div>
17074
17075     </div>
17076 </div>
17077 </div>
17078
17079 </div>
17080 <div class="cell border-box-sizing code_cell rendered">
17081 <div class="input">
17082 <div class="prompt input_prompt">In&nbsp;[90]:</div>
17083 <div class="inner_cell">
17084     <div class="input_area">
17085 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
17086 <span class="n">a</span>
17087 </pre></div>
17088
17089     </div>
17090 </div>
17091 </div>
17092
17093 <div class="output_wrapper">
17094 <div class="output">
17095
17096
17097 <div class="output_area">
17098
17099     <div class="prompt output_prompt">Out[90]:</div>
17100
17101
17102
17103
17104 <div class="output_text output_subarea output_execute_result">
17105 <pre>(a1*, s1)</pre>
17106 </div>
17107
17108 </div>
17109
17110 </div>
17111 </div>
17112
17113 </div>
17114 <div class="cell border-box-sizing code_cell rendered">
17115 <div class="input">
17116 <div class="prompt input_prompt">In&nbsp;[91]:</div>
17117 <div class="inner_cell">
17118     <div class="input_area">
17119 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
17120 <span class="n">b</span>
17121 </pre></div>
17122
17123     </div>
17124 </div>
17125 </div>
17126
17127 <div class="output_wrapper">
17128 <div class="output">
17129
17130
17131 <div class="output_area">
17132
17133     <div class="prompt output_prompt">Out[91]:</div>
17134
17135
17136
17137
17138 <div class="output_text output_subarea output_execute_result">
17139 <pre>(a1, s2)</pre>
17140 </div>
17141
17142 </div>
17143
17144 </div>
17145 </div>
17146
17147 </div>
17148 <div class="cell border-box-sizing code_cell rendered">
17149 <div class="input">
17150 <div class="prompt input_prompt">In&nbsp;[92]:</div>
17151 <div class="inner_cell">
17152     <div class="input_area">
17153 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
17154     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
17155 </pre></div>
17156
17157     </div>
17158 </div>
17159 </div>
17160
17161 <div class="output_wrapper">
17162 <div class="output">
17163
17164
17165 <div class="output_area">
17166
17167     <div class="prompt"></div>
17168
17169
17170 <div class="output_subarea output_stream output_stdout output_text">
17171 <pre>{s1: (a1, s2)} -&gt; (a1*, (a1, s2)) (a1, s2)
17172 {a1: a10001, s2: (a1*, s1)} -&gt; (a1*, s1) (a10001, (a1*, s1))
17173 </pre>
17174 </div>
17175 </div>
17176
17177 </div>
17178 </div>
17179
17180 </div>
17181 <div class="cell border-box-sizing code_cell rendered">
17182 <div class="input">
17183 <div class="prompt input_prompt">In&nbsp;[93]:</div>
17184 <div class="inner_cell">
17185     <div class="input_area">
17186 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
17187     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
17188 </pre></div>
17189
17190     </div>
17191 </div>
17192 </div>
17193
17194 <div class="output_wrapper">
17195 <div class="output">
17196
17197
17198 <div class="output_area">
17199
17200     <div class="prompt"></div>
17201
17202
17203 <div class="output_subarea output_stream output_stdout output_text">
17204 <pre>{s1: (a1, s2)} -&gt; (a1*, (a1, s2)) (a1, s2)
17205 {a1: a10002, s2: (a1*, s1)} -&gt; (a1*, s1) (a10002, (a1*, s1))
17206 </pre>
17207 </div>
17208 </div>
17209
17210 </div>
17211 </div>
17212
17213 </div>
17214 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17215 </div><div class="inner_cell">
17216 <div class="text_cell_render border-box-sizing rendered_html">
17217
17218 <pre><code>(a1*, s1)       [a1*]       (a1, s2)        [a1]
17219
17220 (a1*, (a1, s2)) [a1* a1]    (a1, s2)        [a1]
17221
17222 (a1*, s1)       [a1*]       (a2, (a1*, s1)) [a2 a1*]</code></pre>
17223
17224 </div>
17225 </div>
17226 </div>
17227 <div class="cell border-box-sizing code_cell rendered">
17228 <div class="input">
17229 <div class="prompt input_prompt">In&nbsp;[94]:</div>
17230 <div class="inner_cell">
17231     <div class="input_area">
17232 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
17233
17234 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">)</span>
17235 </pre></div>
17236
17237     </div>
17238 </div>
17239 </div>
17240
17241 <div class="output_wrapper">
17242 <div class="output">
17243
17244
17245 <div class="output_area">
17246
17247     <div class="prompt"></div>
17248
17249
17250 <div class="output_subarea output_stream output_stdout output_text">
17251 <pre>([n1* .1.] -- n0)
17252 </pre>
17253 </div>
17254 </div>
17255
17256 </div>
17257 </div>
17258
17259 </div>
17260 <div class="cell border-box-sizing code_cell rendered">
17261 <div class="input">
17262 <div class="prompt input_prompt">In&nbsp;[95]:</div>
17263 <div class="inner_cell">
17264     <div class="input_area">
17265 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
17266
17267 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">)</span>
17268 </pre></div>
17269
17270     </div>
17271 </div>
17272 </div>
17273
17274 <div class="output_wrapper">
17275 <div class="output">
17276
17277
17278 <div class="output_area">
17279
17280     <div class="prompt"></div>
17281
17282
17283 <div class="output_subarea output_stream output_stdout output_text">
17284 <pre>(-- [n1 n2 n3 .1.])
17285 </pre>
17286 </div>
17287 </div>
17288
17289 </div>
17290 </div>
17291
17292 </div>
17293 <div class="cell border-box-sizing code_cell rendered">
17294 <div class="input">
17295 <div class="prompt input_prompt">In&nbsp;[96]:</div>
17296 <div class="inner_cell">
17297     <div class="input_area">
17298 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
17299     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">sum_</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
17300 </pre></div>
17301
17302     </div>
17303 </div>
17304 </div>
17305
17306 <div class="output_wrapper">
17307 <div class="output">
17308
17309
17310 <div class="output_area">
17311
17312     <div class="prompt"></div>
17313
17314
17315 <div class="output_subarea output_stream output_stdout output_text">
17316 <pre>{s1: (n1, (n2, (n3, s1)))} -&gt; (n0, s0)
17317 {n1: n10001, s1: (n2, (n3, s1))} -&gt; (n0, s0)
17318 {n1: n10001, s1: (n3, s1), n2: n10002} -&gt; (n0, s0)
17319 {n1: n10001, s1: (n1*, s1), n3: n10003, n2: n10002} -&gt; (n0, s0)
17320 </pre>
17321 </div>
17322 </div>
17323
17324 </div>
17325 </div>
17326
17327 </div>
17328 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17329 </div><div class="inner_cell">
17330 <div class="text_cell_render border-box-sizing rendered_html">
17331 <h4 id="compose()-version-3"><code>compose()</code> version 3<a class="anchor-link" href="#compose()-version-3">&#182;</a></h4><p>This function has to be modified to yield multiple results.</p>
17332
17333 </div>
17334 </div>
17335 </div>
17336 <div class="cell border-box-sizing code_cell rendered">
17337 <div class="input">
17338 <div class="prompt input_prompt">In&nbsp;[97]:</div>
17339 <div class="inner_cell">
17340     <div class="input_area">
17341 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
17342     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
17343     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
17344     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
17345         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
17346     <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
17347         <span class="k">yield</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
17348 </pre></div>
17349
17350     </div>
17351 </div>
17352 </div>
17353
17354 </div>
17355 <div class="cell border-box-sizing code_cell rendered">
17356 <div class="input">
17357 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
17358 <div class="inner_cell">
17359     <div class="input_area">
17360 <div class=" highlight hl-ipython2"><pre><span></span> 
17361 </pre></div>
17362
17363     </div>
17364 </div>
17365 </div>
17366
17367 </div>
17368 <div class="cell border-box-sizing code_cell rendered">
17369 <div class="input">
17370 <div class="prompt input_prompt">In&nbsp;[98]:</div>
17371 <div class="inner_cell">
17372     <div class="input_area">
17373 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
17374     <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
17375         <span class="k">try</span><span class="p">:</span>
17376             <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
17377                 <span class="k">yield</span> <span class="n">result</span>
17378         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
17379             <span class="k">pass</span>
17380
17381
17382 <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
17383     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
17384     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
17385         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
17386 </pre></div>
17387
17388     </div>
17389 </div>
17390 </div>
17391
17392 </div>
17393 <div class="cell border-box-sizing code_cell rendered">
17394 <div class="input">
17395 <div class="prompt input_prompt">In&nbsp;[99]:</div>
17396 <div class="inner_cell">
17397     <div class="input_area">
17398 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
17399     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
17400 </pre></div>
17401
17402     </div>
17403 </div>
17404 </div>
17405
17406 <div class="output_wrapper">
17407 <div class="output">
17408
17409
17410 <div class="output_area">
17411
17412     <div class="prompt"></div>
17413
17414
17415 <div class="output_subarea output_stream output_stdout output_text">
17416 <pre>(f1 -- f2)
17417 (i1 -- i2)
17418 </pre>
17419 </div>
17420 </div>
17421
17422 </div>
17423 </div>
17424
17425 </div>
17426 <div class="cell border-box-sizing code_cell rendered">
17427 <div class="input">
17428 <div class="prompt input_prompt">In&nbsp;[100]:</div>
17429 <div class="inner_cell">
17430     <div class="input_area">
17431 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
17432     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
17433 </pre></div>
17434
17435     </div>
17436 </div>
17437 </div>
17438
17439 <div class="output_wrapper">
17440 <div class="output">
17441
17442
17443 <div class="output_area">
17444
17445     <div class="prompt"></div>
17446
17447
17448 <div class="output_subarea output_stream output_stdout output_text">
17449 <pre>([n1* .1.] -- [n1* .1.] n1)
17450 </pre>
17451 </div>
17452 </div>
17453
17454 </div>
17455 </div>
17456
17457 </div>
17458 <div class="cell border-box-sizing code_cell rendered">
17459 <div class="input">
17460 <div class="prompt input_prompt">In&nbsp;[101]:</div>
17461 <div class="inner_cell">
17462     <div class="input_area">
17463 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
17464     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
17465 </pre></div>
17466
17467     </div>
17468 </div>
17469 </div>
17470
17471 <div class="output_wrapper">
17472 <div class="output">
17473
17474
17475 <div class="output_area">
17476
17477     <div class="prompt"></div>
17478
17479
17480 <div class="output_subarea output_stream output_stdout output_text">
17481 <pre>(a1 [.1.] -- n1)
17482 (n1 [n1* .1.] -- n2)
17483 </pre>
17484 </div>
17485 </div>
17486
17487 </div>
17488 </div>
17489
17490 </div>
17491 <div class="cell border-box-sizing code_cell rendered">
17492 <div class="input">
17493 <div class="prompt input_prompt">In&nbsp;[102]:</div>
17494 <div class="inner_cell">
17495     <div class="input_area">
17496 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
17497 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">cons</span><span class="p">),</span>
17498 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">),</span>
17499
17500 <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
17501     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
17502 </pre></div>
17503
17504     </div>
17505 </div>
17506 </div>
17507
17508 <div class="output_wrapper">
17509 <div class="output">
17510
17511
17512 <div class="output_area">
17513
17514     <div class="prompt"></div>
17515
17516
17517 <div class="output_subarea output_stream output_stdout output_text">
17518 <pre>(a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
17519 </pre>
17520 </div>
17521 </div>
17522
17523 </div>
17524 </div>
17525
17526 </div>
17527 <div class="cell border-box-sizing code_cell rendered">
17528 <div class="input">
17529 <div class="prompt input_prompt">In&nbsp;[103]:</div>
17530 <div class="inner_cell">
17531     <div class="input_area">
17532 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
17533 <span class="n">a</span>
17534 </pre></div>
17535
17536     </div>
17537 </div>
17538 </div>
17539
17540 <div class="output_wrapper">
17541 <div class="output">
17542
17543
17544 <div class="output_area">
17545
17546     <div class="prompt output_prompt">Out[103]:</div>
17547
17548
17549
17550
17551 <div class="output_text output_subarea output_execute_result">
17552 <pre>(a4, (a1*, (a3, s1)))</pre>
17553 </div>
17554
17555 </div>
17556
17557 </div>
17558 </div>
17559
17560 </div>
17561 <div class="cell border-box-sizing code_cell rendered">
17562 <div class="input">
17563 <div class="prompt input_prompt">In&nbsp;[104]:</div>
17564 <div class="inner_cell">
17565     <div class="input_area">
17566 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
17567 <span class="n">b</span>
17568 </pre></div>
17569
17570     </div>
17571 </div>
17572 </div>
17573
17574 <div class="output_wrapper">
17575 <div class="output">
17576
17577
17578 <div class="output_area">
17579
17580     <div class="prompt output_prompt">Out[104]:</div>
17581
17582
17583
17584
17585 <div class="output_text output_subarea output_execute_result">
17586 <pre>(a1, (a2, s2))</pre>
17587 </div>
17588
17589 </div>
17590
17591 </div>
17592 </div>
17593
17594 </div>
17595 <div class="cell border-box-sizing code_cell rendered">
17596 <div class="input">
17597 <div class="prompt input_prompt">In&nbsp;[105]:</div>
17598 <div class="inner_cell">
17599     <div class="input_area">
17600 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
17601     <span class="nb">print</span> <span class="n">result</span>
17602 </pre></div>
17603
17604     </div>
17605 </div>
17606 </div>
17607
17608 <div class="output_wrapper">
17609 <div class="output">
17610
17611
17612 <div class="output_area">
17613
17614     <div class="prompt"></div>
17615
17616
17617 <div class="output_subarea output_stream output_stdout output_text">
17618 <pre>{a1: a4, s2: s1, a2: a3}
17619 {a1: a4, s2: (a1*, (a3, s1)), a2: a10003}
17620 </pre>
17621 </div>
17622 </div>
17623
17624 </div>
17625 </div>
17626
17627 </div>
17628 <div class="cell border-box-sizing code_cell rendered">
17629 <div class="input">
17630 <div class="prompt input_prompt">In&nbsp;[106]:</div>
17631 <div class="inner_cell">
17632     <div class="input_area">
17633 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
17634     <span class="nb">print</span> <span class="n">result</span>
17635 </pre></div>
17636
17637     </div>
17638 </div>
17639 </div>
17640
17641 <div class="output_wrapper">
17642 <div class="output">
17643
17644
17645 <div class="output_area">
17646
17647     <div class="prompt"></div>
17648
17649
17650 <div class="output_subarea output_stream output_stdout output_text">
17651 <pre>{s2: s1, a2: a3, a4: a1}
17652 {s2: (a1*, (a3, s1)), a2: a10004, a4: a1}
17653 </pre>
17654 </div>
17655 </div>
17656
17657 </div>
17658 </div>
17659
17660 </div>
17661 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17662 </div><div class="inner_cell">
17663 <div class="text_cell_render border-box-sizing rendered_html">
17664 <h2 id="Part-VII:-Typing-Combinators">Part VII: Typing Combinators<a class="anchor-link" href="#Part-VII:-Typing-Combinators">&#182;</a></h2><p>In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available.  In the most general case, the <code>i</code> combinator, you can't say anything about its stack effect other than it expects one quote:</p>
17665
17666 <pre><code>i (... [.1.] -- ... .1.)
17667
17668 </code></pre>
17669 <p>Or</p>
17670
17671 <pre><code>i (... [A* .1.] -- ... A*)
17672
17673 </code></pre>
17674 <p>Consider the type of:</p>
17675
17676 <pre><code>[cons] dip
17677
17678 </code></pre>
17679 <p>Obviously it would be:</p>
17680
17681 <pre><code>(a1 [..1] a2 -- [a1 ..1] a2)
17682
17683 </code></pre>
17684 <p><code>dip</code> itself could have:</p>
17685
17686 <pre><code>(a1 [..1] -- ... then what?
17687
17688
17689 </code></pre>
17690 <p>Without any information about the contents of the quote we can't say much about the result.</p>
17691
17692 </div>
17693 </div>
17694 </div>
17695 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17696 </div><div class="inner_cell">
17697 <div class="text_cell_render border-box-sizing rendered_html">
17698 <h3 id="Hybrid-Inferencer/Interpreter">Hybrid Inferencer/Interpreter<a class="anchor-link" href="#Hybrid-Inferencer/Interpreter">&#182;</a></h3><p>I think there's a way forward.  If we convert our list (of terms we are composing) into a stack structure we can use it as a <em>Joy expression</em>, then we can treat the <em>output half</em> of a function's stack effect comment as a Joy interpreter stack, and just execute combinators directly.  We can hybridize the compostition function with an interpreter to evaluate combinators, compose non-combinator functions, and put type variables on the stack.  For combinators like <code>branch</code> that can have more than one stack effect we have to "split universes" again and return both.</p>
17699
17700 </div>
17701 </div>
17702 </div>
17703 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17704 </div><div class="inner_cell">
17705 <div class="text_cell_render border-box-sizing rendered_html">
17706 <h4 id="Joy-Types-for-Functions">Joy Types for Functions<a class="anchor-link" href="#Joy-Types-for-Functions">&#182;</a></h4><p>We need a type variable for Joy functions that can go in our expressions and be used by the hybrid inferencer/interpreter.  They have to store a name and a list of stack effects.</p>
17707
17708 </div>
17709 </div>
17710 </div>
17711 <div class="cell border-box-sizing code_cell rendered">
17712 <div class="input">
17713 <div class="prompt input_prompt">In&nbsp;[107]:</div>
17714 <div class="inner_cell">
17715     <div class="input_area">
17716 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
17717
17718     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
17719         <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
17720         <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
17721         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
17722
17723     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
17724         <span class="k">return</span> <span class="bp">self</span>
17725     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
17726
17727     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
17728         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
17729 </pre></div>
17730
17731     </div>
17732 </div>
17733 </div>
17734
17735 </div>
17736 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17737 </div><div class="inner_cell">
17738 <div class="text_cell_render border-box-sizing rendered_html">
17739 <h4 id="Specialized-for-Simple-Functions-and-Combinators">Specialized for Simple Functions and Combinators<a class="anchor-link" href="#Specialized-for-Simple-Functions-and-Combinators">&#182;</a></h4><p>For non-combinator functions the stack effects list contains stack effect comments (represented by pairs of cons-lists as described above.)</p>
17740
17741 </div>
17742 </div>
17743 </div>
17744 <div class="cell border-box-sizing code_cell rendered">
17745 <div class="input">
17746 <div class="prompt input_prompt">In&nbsp;[108]:</div>
17747 <div class="inner_cell">
17748     <div class="input_area">
17749 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
17750     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;F&#39;</span>
17751 </pre></div>
17752
17753     </div>
17754 </div>
17755 </div>
17756
17757 </div>
17758 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17759 </div><div class="inner_cell">
17760 <div class="text_cell_render border-box-sizing rendered_html">
17761 <p>For combinators the list contains Python functions.</p>
17762
17763 </div>
17764 </div>
17765 </div>
17766 <div class="cell border-box-sizing code_cell rendered">
17767 <div class="input">
17768 <div class="prompt input_prompt">In&nbsp;[109]:</div>
17769 <div class="inner_cell">
17770     <div class="input_area">
17771 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
17772
17773     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;C&#39;</span>
17774
17775     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
17776         <span class="nb">super</span><span class="p">(</span><span class="n">CombinatorJoyType</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">)</span>
17777         <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="o">=</span> <span class="n">expect</span>
17778
17779     <span class="k">def</span> <span class="nf">enter_guard</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
17780         <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
17781             <span class="k">return</span> <span class="n">f</span>
17782         <span class="n">g</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span>
17783         <span class="n">new_f</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="p">()))</span>
17784         <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span>
17785         <span class="k">return</span> <span class="n">new_f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
17786 </pre></div>
17787
17788     </div>
17789 </div>
17790 </div>
17791
17792 </div>
17793 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17794 </div><div class="inner_cell">
17795 <div class="text_cell_render border-box-sizing rendered_html">
17796 <p>For simple combinators that have only one effect (like <code>dip</code>) you only need one function and it can be the combinator itself.</p>
17797
17798 </div>
17799 </div>
17800 </div>
17801 <div class="cell border-box-sizing code_cell rendered">
17802 <div class="input">
17803 <div class="prompt input_prompt">In&nbsp;[110]:</div>
17804 <div class="inner_cell">
17805     <div class="input_area">
17806 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
17807
17808 <span class="n">dip</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;dip&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
17809 </pre></div>
17810
17811     </div>
17812 </div>
17813 </div>
17814
17815 </div>
17816 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17817 </div><div class="inner_cell">
17818 <div class="text_cell_render border-box-sizing rendered_html">
17819 <p>For combinators that can have more than one effect (like <code>branch</code>) you have to write functions that each implement the action of one of the effects.</p>
17820
17821 </div>
17822 </div>
17823 </div>
17824 <div class="cell border-box-sizing code_cell rendered">
17825 <div class="input">
17826 <div class="prompt input_prompt">In&nbsp;[111]:</div>
17827 <div class="inner_cell">
17828     <div class="input_area">
17829 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
17830     <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
17831     <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
17832
17833 <span class="k">def</span> <span class="nf">branch_false</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
17834     <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
17835     <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
17836
17837 <span class="n">branch</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;branch&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">branch_true</span><span class="p">,</span> <span class="n">branch_false</span><span class="p">],</span> <span class="mi">100</span><span class="p">)</span>
17838 </pre></div>
17839
17840     </div>
17841 </div>
17842 </div>
17843
17844 </div>
17845 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17846 </div><div class="inner_cell">
17847 <div class="text_cell_render border-box-sizing rendered_html">
17848 <p>You can also provide an optional stack effect, input-side only, that will then be used as an identity function (that accepts and returns stacks that match the "guard" stack effect) which will be used to guard against type mismatches going into the evaluation of the combinator.</p>
17849
17850 </div>
17851 </div>
17852 </div>
17853 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17854 </div><div class="inner_cell">
17855 <div class="text_cell_render border-box-sizing rendered_html">
17856 <h4 id="infer()"><code>infer()</code><a class="anchor-link" href="#infer()">&#182;</a></h4><p>With those in place, we can define a function that accepts a sequence of Joy type variables, including ones representing functions (not just values), and attempts to grind out all the possible stack effects of that expression.</p>
17857 <p>One tricky thing is that type variables <em>in the expression</em> have to be updated along with the stack effects after doing unification or we risk losing useful information.  This was a straightforward, if awkward, modification to the call structure of <code>meta_compose()</code> et. al.</p>
17858
17859 </div>
17860 </div>
17861 </div>
17862 <div class="cell border-box-sizing code_cell rendered">
17863 <div class="input">
17864 <div class="prompt input_prompt">In&nbsp;[112]:</div>
17865 <div class="inner_cell">
17866     <div class="input_area">
17867 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>  <span class="c1"># Identity function.</span>
17868
17869
17870 <span class="k">def</span> <span class="nf">infer</span><span class="p">(</span><span class="o">*</span><span class="n">expression</span><span class="p">):</span>
17871     <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">_infer</span><span class="p">(</span><span class="n">list_to_stack</span><span class="p">(</span><span class="n">expression</span><span class="p">))))</span>
17872
17873
17874 <span class="k">def</span> <span class="nf">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="o">=</span><span class="n">ID</span><span class="p">):</span>
17875     <span class="n">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
17876     <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
17877         <span class="k">return</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span>
17878
17879     <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
17880
17881     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">SymbolJoyType</span><span class="p">):</span>
17882         <span class="n">eFG</span> <span class="o">=</span> <span class="n">meta_compose</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
17883         <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">Fn</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span><span class="p">,</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">eFG</span><span class="p">)</span>
17884
17885     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">CombinatorJoyType</span><span class="p">):</span>
17886         <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">enter_guard</span><span class="p">(</span><span class="n">F</span><span class="p">)</span>
17887         <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">)</span>
17888
17889     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">Symbol</span><span class="p">):</span>
17890         <span class="k">assert</span> <span class="n">n</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">FUNCTIONS</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
17891         <span class="n">func</span> <span class="o">=</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">_dictionary</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
17892         <span class="n">res</span> <span class="o">=</span> <span class="n">_interpret</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">e</span><span class="p">)</span>
17893
17894     <span class="k">else</span><span class="p">:</span>
17895         <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">F</span>
17896         <span class="n">res</span> <span class="o">=</span> <span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">fo</span><span class="p">)))</span>
17897
17898     <span class="k">return</span> <span class="n">res</span>
17899
17900
17901 <span class="k">def</span> <span class="nf">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
17902     <span class="n">new_fo</span><span class="p">,</span> <span class="n">ee</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="p">{})</span>
17903     <span class="n">ee</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">,</span> <span class="n">ee</span><span class="p">)</span>  <span class="c1"># Fix Symbols.</span>
17904     <span class="n">new_F</span> <span class="o">=</span> <span class="n">fi</span><span class="p">,</span> <span class="n">new_fo</span>
17905     <span class="k">return</span> <span class="n">_infer</span><span class="p">(</span><span class="n">ee</span><span class="p">,</span> <span class="n">new_F</span><span class="p">)</span>
17906
17907
17908 <span class="k">def</span> <span class="nf">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">):</span>
17909     <span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
17910         <span class="sa">u</span><span class="s1">&#39;</span><span class="si">%3i</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> ∘ </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span>
17911         <span class="nb">len</span><span class="p">(</span><span class="n">inspect_stack</span><span class="p">()),</span>
17912         <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">),</span>
17913         <span class="n">expression_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
17914         <span class="p">)</span>
17915 </pre></div>
17916
17917     </div>
17918 </div>
17919 </div>
17920
17921 </div>
17922 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17923 </div><div class="inner_cell">
17924 <div class="text_cell_render border-box-sizing rendered_html">
17925 <h4 id="Work-in-Progress">Work in Progress<a class="anchor-link" href="#Work-in-Progress">&#182;</a></h4><p>And that brings us to current Work-In-Progress.  The mixed-mode inferencer/interpreter <code>infer()</code> function seems to work well.  There are details I should document, and the rest of the code in the <code>types</code> module (FIXME link to its docs here!) should be explained...  There is cruft to convert the definitions in <code>DEFS</code> to the new <code>SymbolJoyType</code> objects, and some combinators.  Here is an example of output from the current code :</p>
17926
17927 </div>
17928 </div>
17929 </div>
17930 <div class="cell border-box-sizing code_cell rendered">
17931 <div class="input">
17932 <div class="prompt input_prompt">In&nbsp;[1]:</div>
17933 <div class="inner_cell">
17934     <div class="input_area">
17935 <div class=" highlight hl-ipython2"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span>  <span class="c1"># (Don&#39;t try to run this cell!  It&#39;s not going to work.  This is &quot;read only&quot; code heh..)</span>
17936
17937 <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
17938
17939 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">)</span>
17940
17941 <span class="n">h</span> <span class="o">=</span> <span class="n">infer</span><span class="p">((</span><span class="n">pred</span><span class="p">,</span> <span class="n">s2</span><span class="p">),</span> <span class="p">(</span><span class="n">mul</span><span class="p">,</span> <span class="n">s3</span><span class="p">),</span> <span class="p">(</span><span class="n">div</span><span class="p">,</span> <span class="n">s4</span><span class="p">),</span> <span class="p">(</span><span class="n">nullary</span><span class="p">,</span> <span class="p">(</span><span class="nb">bool</span><span class="p">,</span> <span class="n">s5</span><span class="p">)),</span> <span class="n">dipd</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
17942
17943 <span class="nb">print</span> <span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">40</span>
17944
17945 <span class="k">for</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="ow">in</span> <span class="n">h</span><span class="p">:</span>
17946     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
17947 </pre></div>
17948
17949     </div>
17950 </div>
17951 </div>
17952
17953 <div class="output_wrapper">
17954 <div class="output">
17955
17956
17957 <div class="output_area">
17958
17959     <div class="prompt"></div>
17960
17961
17962 <div class="output_subarea output_text output_error">
17963 <pre>
17964 <span class="ansi-red-fg">---------------------------------------------------------------------------</span>
17965 <span class="ansi-red-fg">ZeroDivisionError</span>                         Traceback (most recent call last)
17966 <span class="ansi-green-fg">&lt;ipython-input-1-9a9d60354c35&gt;</span> in <span class="ansi-cyan-fg">&lt;module&gt;</span><span class="ansi-blue-fg">()</span>
17967 <span class="ansi-green-fg">----&gt; 1</span><span class="ansi-red-fg"> </span><span class="ansi-cyan-fg">1</span><span class="ansi-blue-fg">/</span><span class="ansi-cyan-fg">0</span>  <span class="ansi-red-fg"># (Don&#39;t try to run this cell!  It&#39;s not going to work.  This is &#34;read only&#34; code heh..)</span>
17968 <span class="ansi-green-intense-fg ansi-bold">      2</span> 
17969 <span class="ansi-green-intense-fg ansi-bold">      3</span> logging<span class="ansi-blue-fg">.</span>basicConfig<span class="ansi-blue-fg">(</span>format<span class="ansi-blue-fg">=</span><span class="ansi-blue-fg">&#39;%(message)s&#39;</span><span class="ansi-blue-fg">,</span> stream<span class="ansi-blue-fg">=</span>sys<span class="ansi-blue-fg">.</span>stdout<span class="ansi-blue-fg">,</span> level<span class="ansi-blue-fg">=</span>logging<span class="ansi-blue-fg">.</span>INFO<span class="ansi-blue-fg">)</span>
17970 <span class="ansi-green-intense-fg ansi-bold">      4</span> 
17971 <span class="ansi-green-intense-fg ansi-bold">      5</span> globals<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">.</span>update<span class="ansi-blue-fg">(</span>FUNCTIONS<span class="ansi-blue-fg">)</span>
17972
17973 <span class="ansi-red-fg">ZeroDivisionError</span>: integer division or modulo by zero</pre>
17974 </div>
17975 </div>
17976
17977 </div>
17978 </div>
17979
17980 </div>
17981 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17982 </div><div class="inner_cell">
17983 <div class="text_cell_render border-box-sizing rendered_html">
17984 <p>The numbers at the start of the lines are the current depth of the Python call stack.  They're followed by the current computed stack effect (initialized to <code>ID</code>) then the pending expression (the inference of the stack effect of which is the whole object of the current example.)</p>
17985 <p>In this example we are implementing (and inferring) <code>ifte</code> as <code>[nullary bool] dipd branch</code> which shows off a lot of the current implementation in action.</p>
17986
17987 <pre><code>  7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
17988   8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
17989   9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
17990  10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
17991  11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
17992  15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
17993  19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
17994  20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
17995  22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
17996  26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
17997  29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
17998  30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
17999  34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
18000  37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
18001  38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
18002  41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
18003  44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
18004  47 (n1 -- n1 b1) ∘ [mul] [div] branch
18005  48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
18006  49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
18007  53 (n1 -- n1) ∘ div
18008  56 (f2 f1 -- f3) ∘ 
18009  56 (i1 f1 -- f2) ∘ 
18010  56 (f1 i1 -- f2) ∘ 
18011  56 (i2 i1 -- f1) ∘ 
18012  53 (n1 -- n1) ∘ mul
18013  56 (f2 f1 -- f3) ∘ 
18014  56 (i1 f1 -- f2) ∘ 
18015  56 (f1 i1 -- f2) ∘ 
18016  56 (i2 i1 -- i3) ∘ 
18017 ----------------------------------------
18018 (f2 f1 -- f3)
18019 (i1 f1 -- f2)
18020 (f1 i1 -- f2)
18021 (i2 i1 -- f1)
18022 (i2 i1 -- i3)</code></pre>
18023
18024 </div>
18025 </div>
18026 </div>
18027 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18028 </div><div class="inner_cell">
18029 <div class="text_cell_render border-box-sizing rendered_html">
18030 <h2 id="Conclusion">Conclusion<a class="anchor-link" href="#Conclusion">&#182;</a></h2><p>We built a simple type inferencer, and a kind of crude "compiler" for a subset of Joy functions.  Then we built a more powerful inferencer that actually does some evaluation and explores branching code paths</p>
18031
18032 </div>
18033 </div>
18034 </div>
18035 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18036 </div><div class="inner_cell">
18037 <div class="text_cell_render border-box-sizing rendered_html">
18038 <p>Work remains to be done:</p>
18039 <ul>
18040 <li>the rest of the library has to be covered</li>
18041 <li>figure out how to deal with <code>loop</code> and <code>genrec</code>, etc..</li>
18042 <li>extend the types to check values (see the appendix)</li>
18043 <li>other kinds of "higher order" type variables, OR, AND, etc..</li>
18044 <li>maybe rewrite in Prolog for great good?</li>
18045 <li>definitions<ul>
18046 <li>don't permit composition of functions that don't compose</li>
18047 <li>auto-compile compilable functions</li>
18048 </ul>
18049 </li>
18050 <li>Compiling more than just the Yin functions.</li>
18051 <li>getting better visibility (than Python debugger.)</li>
18052 <li>DOOOOCS!!!!  Lots of docs!<ul>
18053 <li>docstrings all around</li>
18054 <li>improve this notebook (it kinda falls apart at the end narratively.  I went off and just started writing code to see if it would work.  It does, but now I have to come back and describe here what I did.</li>
18055 </ul>
18056 </li>
18057 </ul>
18058
18059 </div>
18060 </div>
18061 </div>
18062 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18063 </div><div class="inner_cell">
18064 <div class="text_cell_render border-box-sizing rendered_html">
18065 <h2 id="Appendix:-Joy-in-the-Logical-Paradigm">Appendix: Joy in the Logical Paradigm<a class="anchor-link" href="#Appendix:-Joy-in-the-Logical-Paradigm">&#182;</a></h2><p>For <em>type checking</em> to work the type label classes have to be modified to let <code>T &gt;= t</code> succeed, where e.g. <code>T</code> is <code>IntJoyType</code> and <code>t</code> is <code>int</code>.  If you do that you can take advantage of the <em>logical relational</em> nature of the stack effect comments to "compute in reverse" as it were.  There's a working demo of this at the end of the <code>types</code> module.  But if you're interested in all that you should just use Prolog!</p>
18066 <p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
18067
18068 </div>
18069 </div>
18070 </div>
18071 <div class="cell border-box-sizing code_cell rendered">
18072 <div class="input">
18073 <div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
18074 <div class="inner_cell">
18075     <div class="input_area">
18076 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
18077     <span class="k">return</span> <span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
18078             <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;accept&#39;</span><span class="p">)</span>
18079             <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">accept</span><span class="p">))</span>
18080
18081 <span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
18082 <span class="n">AnyJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="n">long</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">unicode</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">Symbol</span>
18083 <span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
18084 </pre></div>
18085
18086     </div>
18087 </div>
18088 </div>
18089
18090 </div>
18091     </div>
18092   </div>
18093 </body>
18094
18095  
18096
18097
18098 </html>