├── tags └── .gitignore ├── jams ├── .gitignore ├── 2017.json ├── images │ ├── sonengamejam.png │ ├── betabreakers_shield.png │ ├── 16948013604ead9a1feb2934.png │ ├── 10282912634fe1e92192fa97.43665403.png │ ├── 1048199494f6f336d1de416.62094898.png │ ├── 1142016024ec90d328f6348.64394634.png │ ├── 11985497554fa69890d89a03.91405932.png │ ├── 12025080144f79bd12761776.04109073.png │ ├── 13760416354fc27f66b2af88.23717672.png │ ├── 14398886984e81fd1418e4f9.82238073.png │ ├── 15019029394f84723d379fd0.46492417.png │ ├── 15116654334fad3f1051de20.06475324.png │ ├── 15414486034f27c963981b89.22760942.png │ ├── 15600348814fb7f33d4864c2.95915620.png │ ├── 16411624904f6f30112eb008.55982747.png │ ├── 17584516494f8b24460f06c3.64197387.png │ ├── 1818960464e81fd1bc94c14.96327136.png │ ├── 1880194794fad3f3ae815b0.79745585.png │ ├── 19003792814f7ee5c09d9cc1.14773680.png │ ├── 19804984004f577e69add270.03538846.png │ ├── 20363448984ec933b019dee5.26597249.png │ ├── 20407160144e81fc8ca13646.87700235.png │ ├── 21092272484ec673cc161ac7.89017946.png │ ├── 2343652204fad4460ab5408.25629911.png │ ├── 2576340814e81fd09b7e248.82235325.png │ ├── 278394084f91d85bd2d4e0.09374261.png │ ├── 2849173764e81fcee271a33.24238708.png │ ├── 3375839034fa30435b05b18.70136392.png │ ├── 3709999234e81fd00a63371.60060855.png │ ├── 394033884e81fcdd5c1342.40999022.png │ ├── 4757581634fe8679ed69125.40169351.png │ ├── 5056893384ec919f008ff74.18114017.png │ ├── 553949174f2bd02caa84e1.40172513.png │ ├── 5547059584ef4cba2eb7b79.79793277.png │ ├── 5813508324ec80ddb9370b8.82371048.png │ ├── 5881530114e81fce6e265e9.02648622.png │ ├── 6118046254fcb8871be0534.46857674.png │ ├── 6746560214f50ec762565c5.01011571.png │ ├── 736915804f861809855ba8.45185674.png │ ├── 7694252444f2bc8755bd765.26723435.png │ ├── 9347887744f85813630bf26.40088607.png │ ├── 9357150184ed42c5861d735.08548510.png │ ├── screenshot_1349019684.6_0.643413466896.png │ ├── screenshot_1354646888.17_0.16336391192.png │ ├── screenshot_1360930026.0_0.813907784503.png │ ├── screenshot_1362265433.77_0.25981079131.png │ ├── screenshot_1362265626.98_0.15127399745.png │ ├── screenshot_1341682264.27_0.547807576502.png │ ├── screenshot_1342206345.26_0.257730348311.png │ ├── screenshot_1342206500.01_0.233973319802.png │ ├── screenshot_1342207392.13_0.0996304039715.png │ ├── screenshot_1342858515.44_0.690744901939.png │ ├── screenshot_1343188369.39_0.640801537297.png │ ├── screenshot_1343328868.42_0.447394252922.png │ ├── screenshot_1343586023.16_0.540877325193.png │ ├── screenshot_1346225703.16_0.399590314009.png │ ├── screenshot_1346964108.43_0.409160845116.png │ ├── screenshot_1347048714.05_0.758921376018.png │ ├── screenshot_1347049065.71_0.982523196048.png │ ├── screenshot_1348086870.35_0.468618479484.png │ ├── screenshot_1348418592.98_0.396531958743.png │ ├── screenshot_1348418828.73_0.171391028487.png │ ├── screenshot_1350319205.86_0.403430105792.png │ ├── screenshot_1351369746.17_0.468428717153.png │ ├── screenshot_1351372559.17_0.659258102208.png │ ├── screenshot_1354242342.03_0.509000986088.png │ ├── screenshot_1357482231.58_0.677604945519.png │ ├── screenshot_1357787634.63_0.183862265963.png │ ├── screenshot_1359836493.39_0.601642125852.png │ ├── screenshot_1361983720.95_0.555822640963.png │ ├── screenshot_1362141935.44_0.578388289649.png │ ├── screenshot_1363725125.36_0.205630490849.png │ ├── screenshot_1363996761.17_0.824015385924.png │ ├── screenshot_1367848701.84_0.878419596429.png │ ├── screenshot_1368122117.97_0.426456551762.png │ ├── screenshot_1368122796.51_0.157840830543.png │ ├── screenshot_1370302712.74_0.0441713671398.png │ ├── screenshot_1370303087.0_0.0216202400774.png │ ├── screenshot_1371600445.89_0.575707247352.png │ ├── screenshot_1374676901.57_0.452344611688.png │ ├── screenshot_1374677792.68_0.492546391434.png │ ├── screenshot_1374681486.76_0.625152289568.png │ ├── screenshot_1377726831.57_0.338148130721.png │ ├── screenshot_1378240484.27_0.966870129666.png │ ├── screenshot_1378323312.55_0.278542391715.png │ ├── screenshot_1378930597.14_0.604868461647.png │ ├── screenshot_1378934741.05_0.304507859101.png │ ├── screenshot_1380838742.62_0.856640919509.png │ └── screenshot_1380914266.52_0.935968657593.png ├── 2016.json ├── README.md ├── 2011.json └── 2015.json ├── .travis.yml ├── .gitignore ├── Tupfile ├── font ├── LatoLatin-Bold.eot ├── LatoLatin-Bold.ttf ├── LatoLatin-Bold.woff ├── LatoLatin-Regular.eot ├── LatoLatin-Regular.ttf ├── LatoLatin-Regular.woff ├── LatoLatinThin-Regular.eot ├── LatoLatinThin-Regular.ttf ├── LatoLatinThin-Regular.woff ├── LatoLatin-Bold.css ├── LatoLatin-Regular.css ├── LatoLatinThin-Regular.css ├── LatoLatin-Regular.html ├── LatoLatin-Bold.html ├── LatoLatinThin-Regular.html ├── README.txt └── OFL.txt ├── templates ├── all_jams.hbs ├── tag.hbs ├── jam.hbs └── layout.hbs ├── Makefile ├── package.json ├── font.css ├── test └── jamhub.coffee ├── README.md ├── LICENSE.md ├── index.html ├── misc └── export_jams.php ├── Gruntfile.coffee ├── underscore-min.js ├── jamhub.scss ├── jamhub.coffee └── moment.min.js /tags/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /jams/.gitignore: -------------------------------------------------------------------------------- 1 | /*/ 2 | index.html 3 | -------------------------------------------------------------------------------- /jams/2017.json: -------------------------------------------------------------------------------- 1 | { 2 | "jams": [] 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | .tup 3 | .ics 4 | /node_modules 5 | /jamhub.css 6 | /jamhub.js 7 | -------------------------------------------------------------------------------- /Tupfile: -------------------------------------------------------------------------------- 1 | : jamhub.coffee |> coffee -c %f |> %B.js 2 | : foreach *.scss |> sassc < %f > %o |> %B.css -------------------------------------------------------------------------------- /font/LatoLatin-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Bold.eot -------------------------------------------------------------------------------- /font/LatoLatin-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Bold.ttf -------------------------------------------------------------------------------- /font/LatoLatin-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Bold.woff -------------------------------------------------------------------------------- /font/LatoLatin-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Regular.eot -------------------------------------------------------------------------------- /font/LatoLatin-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Regular.ttf -------------------------------------------------------------------------------- /font/LatoLatin-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatin-Regular.woff -------------------------------------------------------------------------------- /jams/images/sonengamejam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/sonengamejam.png -------------------------------------------------------------------------------- /font/LatoLatinThin-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatinThin-Regular.eot -------------------------------------------------------------------------------- /font/LatoLatinThin-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatinThin-Regular.ttf -------------------------------------------------------------------------------- /font/LatoLatinThin-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/font/LatoLatinThin-Regular.woff -------------------------------------------------------------------------------- /jams/images/betabreakers_shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/betabreakers_shield.png -------------------------------------------------------------------------------- /jams/images/16948013604ead9a1feb2934.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/16948013604ead9a1feb2934.png -------------------------------------------------------------------------------- /jams/images/10282912634fe1e92192fa97.43665403.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/10282912634fe1e92192fa97.43665403.png -------------------------------------------------------------------------------- /jams/images/1048199494f6f336d1de416.62094898.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/1048199494f6f336d1de416.62094898.png -------------------------------------------------------------------------------- /jams/images/1142016024ec90d328f6348.64394634.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/1142016024ec90d328f6348.64394634.png -------------------------------------------------------------------------------- /jams/images/11985497554fa69890d89a03.91405932.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/11985497554fa69890d89a03.91405932.png -------------------------------------------------------------------------------- /jams/images/12025080144f79bd12761776.04109073.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/12025080144f79bd12761776.04109073.png -------------------------------------------------------------------------------- /jams/images/13760416354fc27f66b2af88.23717672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/13760416354fc27f66b2af88.23717672.png -------------------------------------------------------------------------------- /jams/images/14398886984e81fd1418e4f9.82238073.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/14398886984e81fd1418e4f9.82238073.png -------------------------------------------------------------------------------- /jams/images/15019029394f84723d379fd0.46492417.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/15019029394f84723d379fd0.46492417.png -------------------------------------------------------------------------------- /jams/images/15116654334fad3f1051de20.06475324.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/15116654334fad3f1051de20.06475324.png -------------------------------------------------------------------------------- /jams/images/15414486034f27c963981b89.22760942.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/15414486034f27c963981b89.22760942.png -------------------------------------------------------------------------------- /jams/images/15600348814fb7f33d4864c2.95915620.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/15600348814fb7f33d4864c2.95915620.png -------------------------------------------------------------------------------- /jams/images/16411624904f6f30112eb008.55982747.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/16411624904f6f30112eb008.55982747.png -------------------------------------------------------------------------------- /jams/images/17584516494f8b24460f06c3.64197387.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/17584516494f8b24460f06c3.64197387.png -------------------------------------------------------------------------------- /jams/images/1818960464e81fd1bc94c14.96327136.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/1818960464e81fd1bc94c14.96327136.png -------------------------------------------------------------------------------- /jams/images/1880194794fad3f3ae815b0.79745585.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/1880194794fad3f3ae815b0.79745585.png -------------------------------------------------------------------------------- /jams/images/19003792814f7ee5c09d9cc1.14773680.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/19003792814f7ee5c09d9cc1.14773680.png -------------------------------------------------------------------------------- /jams/images/19804984004f577e69add270.03538846.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/19804984004f577e69add270.03538846.png -------------------------------------------------------------------------------- /jams/images/20363448984ec933b019dee5.26597249.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/20363448984ec933b019dee5.26597249.png -------------------------------------------------------------------------------- /jams/images/20407160144e81fc8ca13646.87700235.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/20407160144e81fc8ca13646.87700235.png -------------------------------------------------------------------------------- /jams/images/21092272484ec673cc161ac7.89017946.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/21092272484ec673cc161ac7.89017946.png -------------------------------------------------------------------------------- /jams/images/2343652204fad4460ab5408.25629911.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/2343652204fad4460ab5408.25629911.png -------------------------------------------------------------------------------- /jams/images/2576340814e81fd09b7e248.82235325.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/2576340814e81fd09b7e248.82235325.png -------------------------------------------------------------------------------- /jams/images/278394084f91d85bd2d4e0.09374261.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/278394084f91d85bd2d4e0.09374261.png -------------------------------------------------------------------------------- /jams/images/2849173764e81fcee271a33.24238708.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/2849173764e81fcee271a33.24238708.png -------------------------------------------------------------------------------- /jams/images/3375839034fa30435b05b18.70136392.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/3375839034fa30435b05b18.70136392.png -------------------------------------------------------------------------------- /jams/images/3709999234e81fd00a63371.60060855.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/3709999234e81fd00a63371.60060855.png -------------------------------------------------------------------------------- /jams/images/394033884e81fcdd5c1342.40999022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/394033884e81fcdd5c1342.40999022.png -------------------------------------------------------------------------------- /jams/images/4757581634fe8679ed69125.40169351.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/4757581634fe8679ed69125.40169351.png -------------------------------------------------------------------------------- /jams/images/5056893384ec919f008ff74.18114017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/5056893384ec919f008ff74.18114017.png -------------------------------------------------------------------------------- /jams/images/553949174f2bd02caa84e1.40172513.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/553949174f2bd02caa84e1.40172513.png -------------------------------------------------------------------------------- /jams/images/5547059584ef4cba2eb7b79.79793277.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/5547059584ef4cba2eb7b79.79793277.png -------------------------------------------------------------------------------- /jams/images/5813508324ec80ddb9370b8.82371048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/5813508324ec80ddb9370b8.82371048.png -------------------------------------------------------------------------------- /jams/images/5881530114e81fce6e265e9.02648622.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/5881530114e81fce6e265e9.02648622.png -------------------------------------------------------------------------------- /jams/images/6118046254fcb8871be0534.46857674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/6118046254fcb8871be0534.46857674.png -------------------------------------------------------------------------------- /jams/images/6746560214f50ec762565c5.01011571.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/6746560214f50ec762565c5.01011571.png -------------------------------------------------------------------------------- /jams/images/736915804f861809855ba8.45185674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/736915804f861809855ba8.45185674.png -------------------------------------------------------------------------------- /jams/images/7694252444f2bc8755bd765.26723435.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/7694252444f2bc8755bd765.26723435.png -------------------------------------------------------------------------------- /jams/images/9347887744f85813630bf26.40088607.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/9347887744f85813630bf26.40088607.png -------------------------------------------------------------------------------- /jams/images/9357150184ed42c5861d735.08548510.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/9357150184ed42c5861d735.08548510.png -------------------------------------------------------------------------------- /jams/images/screenshot_1349019684.6_0.643413466896.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1349019684.6_0.643413466896.png -------------------------------------------------------------------------------- /jams/images/screenshot_1354646888.17_0.16336391192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1354646888.17_0.16336391192.png -------------------------------------------------------------------------------- /jams/images/screenshot_1360930026.0_0.813907784503.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1360930026.0_0.813907784503.png -------------------------------------------------------------------------------- /jams/images/screenshot_1362265433.77_0.25981079131.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1362265433.77_0.25981079131.png -------------------------------------------------------------------------------- /jams/images/screenshot_1362265626.98_0.15127399745.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1362265626.98_0.15127399745.png -------------------------------------------------------------------------------- /jams/images/screenshot_1341682264.27_0.547807576502.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1341682264.27_0.547807576502.png -------------------------------------------------------------------------------- /jams/images/screenshot_1342206345.26_0.257730348311.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1342206345.26_0.257730348311.png -------------------------------------------------------------------------------- /jams/images/screenshot_1342206500.01_0.233973319802.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1342206500.01_0.233973319802.png -------------------------------------------------------------------------------- /jams/images/screenshot_1342207392.13_0.0996304039715.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1342207392.13_0.0996304039715.png -------------------------------------------------------------------------------- /jams/images/screenshot_1342858515.44_0.690744901939.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1342858515.44_0.690744901939.png -------------------------------------------------------------------------------- /jams/images/screenshot_1343188369.39_0.640801537297.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1343188369.39_0.640801537297.png -------------------------------------------------------------------------------- /jams/images/screenshot_1343328868.42_0.447394252922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1343328868.42_0.447394252922.png -------------------------------------------------------------------------------- /jams/images/screenshot_1343586023.16_0.540877325193.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1343586023.16_0.540877325193.png -------------------------------------------------------------------------------- /jams/images/screenshot_1346225703.16_0.399590314009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1346225703.16_0.399590314009.png -------------------------------------------------------------------------------- /jams/images/screenshot_1346964108.43_0.409160845116.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1346964108.43_0.409160845116.png -------------------------------------------------------------------------------- /jams/images/screenshot_1347048714.05_0.758921376018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1347048714.05_0.758921376018.png -------------------------------------------------------------------------------- /jams/images/screenshot_1347049065.71_0.982523196048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1347049065.71_0.982523196048.png -------------------------------------------------------------------------------- /jams/images/screenshot_1348086870.35_0.468618479484.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1348086870.35_0.468618479484.png -------------------------------------------------------------------------------- /jams/images/screenshot_1348418592.98_0.396531958743.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1348418592.98_0.396531958743.png -------------------------------------------------------------------------------- /jams/images/screenshot_1348418828.73_0.171391028487.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1348418828.73_0.171391028487.png -------------------------------------------------------------------------------- /jams/images/screenshot_1350319205.86_0.403430105792.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1350319205.86_0.403430105792.png -------------------------------------------------------------------------------- /jams/images/screenshot_1351369746.17_0.468428717153.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1351369746.17_0.468428717153.png -------------------------------------------------------------------------------- /jams/images/screenshot_1351372559.17_0.659258102208.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1351372559.17_0.659258102208.png -------------------------------------------------------------------------------- /jams/images/screenshot_1354242342.03_0.509000986088.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1354242342.03_0.509000986088.png -------------------------------------------------------------------------------- /jams/images/screenshot_1357482231.58_0.677604945519.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1357482231.58_0.677604945519.png -------------------------------------------------------------------------------- /jams/images/screenshot_1357787634.63_0.183862265963.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1357787634.63_0.183862265963.png -------------------------------------------------------------------------------- /jams/images/screenshot_1359836493.39_0.601642125852.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1359836493.39_0.601642125852.png -------------------------------------------------------------------------------- /jams/images/screenshot_1361983720.95_0.555822640963.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1361983720.95_0.555822640963.png -------------------------------------------------------------------------------- /jams/images/screenshot_1362141935.44_0.578388289649.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1362141935.44_0.578388289649.png -------------------------------------------------------------------------------- /jams/images/screenshot_1363725125.36_0.205630490849.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1363725125.36_0.205630490849.png -------------------------------------------------------------------------------- /jams/images/screenshot_1363996761.17_0.824015385924.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1363996761.17_0.824015385924.png -------------------------------------------------------------------------------- /jams/images/screenshot_1367848701.84_0.878419596429.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1367848701.84_0.878419596429.png -------------------------------------------------------------------------------- /jams/images/screenshot_1368122117.97_0.426456551762.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1368122117.97_0.426456551762.png -------------------------------------------------------------------------------- /jams/images/screenshot_1368122796.51_0.157840830543.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1368122796.51_0.157840830543.png -------------------------------------------------------------------------------- /jams/images/screenshot_1370302712.74_0.0441713671398.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1370302712.74_0.0441713671398.png -------------------------------------------------------------------------------- /jams/images/screenshot_1370303087.0_0.0216202400774.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1370303087.0_0.0216202400774.png -------------------------------------------------------------------------------- /jams/images/screenshot_1371600445.89_0.575707247352.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1371600445.89_0.575707247352.png -------------------------------------------------------------------------------- /jams/images/screenshot_1374676901.57_0.452344611688.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1374676901.57_0.452344611688.png -------------------------------------------------------------------------------- /jams/images/screenshot_1374677792.68_0.492546391434.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1374677792.68_0.492546391434.png -------------------------------------------------------------------------------- /jams/images/screenshot_1374681486.76_0.625152289568.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1374681486.76_0.625152289568.png -------------------------------------------------------------------------------- /jams/images/screenshot_1377726831.57_0.338148130721.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1377726831.57_0.338148130721.png -------------------------------------------------------------------------------- /jams/images/screenshot_1378240484.27_0.966870129666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1378240484.27_0.966870129666.png -------------------------------------------------------------------------------- /jams/images/screenshot_1378323312.55_0.278542391715.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1378323312.55_0.278542391715.png -------------------------------------------------------------------------------- /jams/images/screenshot_1378930597.14_0.604868461647.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1378930597.14_0.604868461647.png -------------------------------------------------------------------------------- /jams/images/screenshot_1378934741.05_0.304507859101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1378934741.05_0.304507859101.png -------------------------------------------------------------------------------- /jams/images/screenshot_1380838742.62_0.856640919509.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1380838742.62_0.856640919509.png -------------------------------------------------------------------------------- /jams/images/screenshot_1380914266.52_0.935968657593.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafo/compohub/HEAD/jams/images/screenshot_1380914266.52_0.935968657593.png -------------------------------------------------------------------------------- /templates/all_jams.hbs: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{#each jams_by_year }} 4 |
5 |

{{ year }}

6 | 18 |
19 | {{/each }} 20 |
21 | -------------------------------------------------------------------------------- /font/LatoLatin-Bold.css: -------------------------------------------------------------------------------- 1 | /* Webfont: LatoLatin-Bold */@font-face { 2 | font-family: 'LatoLatin'; 3 | src: url('LatoLatin-Bold.eot'); /* IE9 Compat Modes */ 4 | src: url('LatoLatin-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('LatoLatin-Bold.woff') format('woff'), /* Modern Browsers */ 6 | url('LatoLatin-Bold.ttf') format('truetype'); 7 | font-style: normal; 8 | font-weight: bold; 9 | text-rendering: optimizeLegibility; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /font/LatoLatin-Regular.css: -------------------------------------------------------------------------------- 1 | /* Webfont: LatoLatin-Regular */@font-face { 2 | font-family: 'LatoLatin'; 3 | src: url('LatoLatin-Regular.eot'); /* IE9 Compat Modes */ 4 | src: url('LatoLatin-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('LatoLatin-Regular.woff') format('woff'), /* Modern Browsers */ 6 | url('LatoLatin-Regular.ttf') format('truetype'); 7 | font-style: normal; 8 | font-weight: normal; 9 | text-rendering: optimizeLegibility; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /font/LatoLatinThin-Regular.css: -------------------------------------------------------------------------------- 1 | /* Webfont: LatoLatinThin-Regular */@font-face { 2 | font-family: 'LatoLatinThin'; 3 | src: url('LatoLatinThin-Regular.eot'); /* IE9 Compat Modes */ 4 | src: url('LatoLatinThin-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('LatoLatinThin-Regular.woff') format('woff'), /* Modern Browsers */ 6 | url('LatoLatinThin-Regular.ttf') format('truetype'); 7 | font-style: normal; 8 | font-weight: normal; 9 | text-rendering: optimizeLegibility; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /templates/tag.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Jams tagged '{{ tag }}'

3 |
4 | 16 |
17 | 18 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: deploy json test 3 | 4 | test: 5 | ./node_modules/.bin/mocha \ 6 | --compilers coffee:coffee-script/register \ 7 | --reporter dot 8 | 9 | pages: 10 | grunt coffee sass 11 | grunt assemble 12 | grunt ical 13 | 14 | json: 15 | php misc/export_jams.php 2011 > jams/2011.json 16 | php misc/export_jams.php 2012 > jams/2012.json 17 | php misc/export_jams.php 2013 > jams/2013.json 18 | php misc/export_jams.php 2014 > jams/2014.json 19 | php misc/export_jams.php 2015 > jams/2015.json 20 | 21 | deploy: 22 | rsync -RrvuzL index.html *.ics *.js *.css jams/ font/ tags/ leaf@leafo.net:www/compohub.net 23 | -------------------------------------------------------------------------------- /font/LatoLatin-Regular.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Lato Latin Regular - Web Font Specimen 7 | 8 | 11 | 12 | 13 |

The quick brown fox jumps over the lazy dog. $123.45!

14 | 15 | 16 | -------------------------------------------------------------------------------- /font/LatoLatin-Bold.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Lato Latin Bold - Web Font Specimen 7 | 8 | 11 | 12 | 13 |

The quick brown fox jumps over the lazy dog. $123.45!

14 | 15 | 16 | -------------------------------------------------------------------------------- /font/LatoLatinThin-Regular.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Lato Latin Thin Regular - Web Font Specimen 7 | 8 | 11 | 12 | 13 |

The quick brown fox jumps over the lazy dog. $123.45!

14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jamhub", 3 | "version": "0.0.0", 4 | "description": "A community-run listing of game jams.", 5 | "scripts": { 6 | "test": "make" 7 | }, 8 | "devDependencies": { 9 | "assemble": "^0.4.37", 10 | "coffee-script": "", 11 | "connect-livereload": "^0.5.0", 12 | "grunt": "^0.4.4", 13 | "grunt-contrib-coffee": "^0.10.1", 14 | "grunt-contrib-connect": "^0.8.0", 15 | "grunt-contrib-sass": "^0.7.3", 16 | "grunt-contrib-watch": "^0.6.1", 17 | "grunt-open": "^0.2.3", 18 | "ical-generator": "^0.1.5", 19 | "load-grunt-tasks": "^1.0.0", 20 | "mocha": "", 21 | "moment": "" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git://github.com/leafo/compohub.git" 26 | }, 27 | "author": "leaf coran", 28 | "license": "Unlicense", 29 | "bugs": { 30 | "url": "https://github.com/leafo/compohub/issues" 31 | }, 32 | "homepage": "https://github.com/leafo/compohub" 33 | } 34 | -------------------------------------------------------------------------------- /jams/2016.json: -------------------------------------------------------------------------------- 1 | { 2 | "jams": [ 3 | { 4 | "name": "Berkeley Global Game Jam", 5 | "url": "https://www.facebook.com/events/1117401494948921/", 6 | "start_date": "2016-01-29 18:00 -0700", 7 | "end_date": "2016-01-31 23:59 -0700" 8 | }, 9 | { 10 | "name": "#CPCRetroDev 2016: International Game Development Contest for Amstrad CPC", 11 | "url": "http://cpcretrodev.byterealms.com/contest-en/cpcretrodev-2016/", 12 | "start_date": "2014-05-18 00:00 -0100", 13 | "end_date": "2014-10-26 23:59 -0100", 14 | "themes": ["any", "Camelot Warriors"], 15 | "tags": ["Amstrad", "Retro", "64K", "8bits", "casete"], 16 | "description": "This contest awards the best and most creative developers of the retro scene, able to develop the best games for Amstrad CPC 464. Prizes (1050€). PRO Category: 1) 300€, 2) 150€, 3) 75€. BASIC Category: 1) 100€, 2) 50€. Special Mentions: 125€ Gominolas best music, 125€ Jon Ritman best technical development, 125€ Dinamic most innovative playability." 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /font.css: -------------------------------------------------------------------------------- 1 | 2 | /* Webfont: LatoLatinThin-Regular */@font-face { 3 | font-family: 'lato'; 4 | src: url('font/LatoLatinThin-Regular.eot'); /* IE9 Compat Modes */ 5 | src: url('font/LatoLatinThin-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 6 | url('font/LatoLatinThin-Regular.woff') format('woff'), /* Modern Browsers */ 7 | url('font/LatoLatinThin-Regular.ttf') format('truetype'); 8 | 9 | font-style: normal; 10 | font-weight: 200; 11 | text-rendering: optimizeLegibility; 12 | } 13 | 14 | /* Webfont: LatoLatin-Regular */@font-face { 15 | font-family: 'lato'; 16 | src: url('font/LatoLatin-Regular.eot'); /* IE9 Compat Modes */ 17 | src: url('font/LatoLatin-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 18 | url('font/LatoLatin-Regular.woff') format('woff'), /* Modern Browsers */ 19 | url('font/LatoLatin-Regular.ttf') format('truetype'); 20 | font-style: normal; 21 | font-weight: normal; 22 | text-rendering: optimizeLegibility; 23 | } 24 | 25 | /* Webfont: LatoLatin-Bold */@font-face { 26 | font-family: 'lato'; 27 | src: url('font/LatoLatin-Bold.eot'); /* IE9 Compat Modes */ 28 | src: url('font/LatoLatin-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 29 | url('font/LatoLatin-Bold.woff') format('woff'), /* Modern Browsers */ 30 | url('font/LatoLatin-Bold.ttf') format('truetype'); 31 | font-style: normal; 32 | font-weight: bold; 33 | text-rendering: optimizeLegibility; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /test/jamhub.coffee: -------------------------------------------------------------------------------- 1 | 2 | fs = require "fs" 3 | moment = require "moment" 4 | 5 | {J} = require "../jamhub" 6 | 7 | check_date = (val) -> 8 | [valid, date] = J.parse_jam_timestamp val 9 | valid 10 | 11 | has_attrs = (jam, attrs...) -> 12 | name = jam.name || "jam" 13 | it "`#{name}` should have required attributes", -> 14 | for attr in attrs 15 | t = typeof attr 16 | if t == "object" 17 | [attr, params] = attr 18 | 19 | if !jam[attr]? && !params?.optional 20 | throw new Error "missing attribute `#{attr}`" 21 | 22 | if params && jam[attr]? 23 | if params.type && !jam[attr] instanceof params.type 24 | throw new Error "type of `#{attr}` should be `#{params.type}`" 25 | 26 | if params.validate && !params.validate?(jam[attr], attr) 27 | throw new Error "`#{attr}` is invalid format" 28 | 29 | 30 | describe "jamhub", -> 31 | for file in fs.readdirSync "jams/" 32 | continue unless file.match /\.json$/ 33 | do (file) -> 34 | full_path = "jams/#{file}" 35 | it "`#{full_path}` should have proper syntax", -> 36 | JSON.parse fs.readFileSync full_path 37 | 38 | try 39 | jams = JSON.parse fs.readFileSync full_path 40 | catch error 41 | 42 | if jams 43 | for jam in jams.jams 44 | has_attrs jam, "name", "url", 45 | ["start_date", validate: check_date], 46 | ["end_date", validate: check_date], 47 | ["tags", optional: true, type: Array], 48 | ["themes", optional: true, type: Array], 49 | 50 | 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compohub 2 | 3 | [![Build Status](https://travis-ci.org/leafo/compohub.svg?branch=master)](https://travis-ci.org/leafo/compohub) 4 | 5 | A community run listing of game jams. 6 | 7 | ## Adding a new jam 8 | 9 | Instructions for adding a new jam: 10 | 11 | ## Running locally 12 | 13 | ### Node.js server with Grunt 14 | Running the project in a local Node.js server with Grunt should get around any `XMLHttpRequest` errors that may come up when trying to run index.html through `file://`. It also compiles changes to jamhub.js and jamhub.css whenever you make changes. 15 | 16 | First start by installing [Node.js](http://nodejs.org/). After installing Node.js, you should be able to start a local server by running the following commands in your command prompt: 17 | 18 | npm install -g grunt-cli 19 | npm install 20 | grunt serve 21 | 22 | This will: 23 | 24 | 1. Globally install the grunt-cli package, giving you access to the `grunt` command used to run Grunt tasks. 25 | 2. Locally install any Node.js packages required by the project. 26 | 3. Run the `serve` Grunt task, which will compile the coffee and sass files, run a local server and listen for any file changes. 27 | 28 | ### Manually 29 | After checking out the repository you'll need a 30 | [CoffeeScript](http://coffeescript.org/) compiler and a [SCSS 31 | compiler](http://sass-lang.com/). Compile the `coffee` and `scss` files in the 32 | main directory then you can view `index.html` in your browser to see the jams. 33 | 34 | ## Issues and bugs 35 | 36 | Found something wrong or want to see a new feature? Add an issue to the [issues 37 | tracker](https://github.com/leafo/compohub/issues). 38 | -------------------------------------------------------------------------------- /templates/jam.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ jam.name }}

4 | 5 |

{{ jam.description }}

6 | 7 |
8 |
9 | Start date: 10 | 11 | {{ jam.start_date }} 12 | 13 |
14 |
15 | End date: 16 | 17 | {{ jam.end_date }} 18 | 19 |
20 |
21 | 22 | {{#if jam.tags }} 23 |
24 | {{#each jam.tags }} 25 | {{ this }} 26 | {{/each }} 27 |
28 | {{/if }} 29 |
30 | 31 | 34 |
35 | 36 | 37 |
38 |

Comment on this jam

39 |
40 | 49 |
50 | 51 | 56 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## License 2 | 3 | This is free and unencumbered software released into the public domain. 4 | 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | 29 | ### Note 30 | 31 | This repository contains copies of the following projects that contain their 32 | own respective license: 33 | 34 | ``` 35 | jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license 36 | ``` 37 | 38 | ``` 39 | moment.js 40 | version : 2.5.1 41 | authors : Tim Wood, Iskren Chernev, Moment.js contributors 42 | license : MIT 43 | momentjs.com 44 | ``` 45 | 46 | ``` 47 | Underscore.js 1.6.0 48 | http://underscorejs.org 49 | (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 50 | Underscore may be freely distributed under the MIT license. 51 | ``` 52 | 53 | 54 | ``` 55 | Lato font family 56 | 57 | ================ 58 | 59 | Version 2.007; Latin+Cyrillic+Greek+IPA opensource 60 | 61 | Created by: tyPoland Lukasz Dziedzic 62 | Creation year: 2014 63 | 64 | Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic with Reserved Font Name 65 | "Lato". Licensed under the SIL Open Font License, Version 1.1. 66 | 67 | Lato is a trademark of tyPoland Lukasz Dziedzic. 68 | ``` 69 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompoHub - Find game jams 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 |
17 |

CompoHub

18 |

Find game jams

19 |
20 | Submit a jam 21 | 22 |
23 |
Share
24 |
25 | Facebook 26 |
27 | 28 |
29 | Google+ 30 |
31 | 32 |
33 | Twitter 34 |
35 |
36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 |
44 | 45 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /templates/layout.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ page_title }} - CompoHub 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 |
17 |

18 | CompoHub 19 |

20 |

Find game jams

21 |
22 | Submit a jam 23 | 24 |
25 |
Share
26 |
27 | 28 |
29 | 30 |
31 | Google+ 32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 | {{> body }} 42 | 43 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /font/README.txt: -------------------------------------------------------------------------------- 1 | 2 | Lato font family 3 | 4 | ================ 5 | 6 | Version 2.010; Latin+Cyrillic+Greek+IPA opensource 7 | 8 | Created by: tyPoland Lukasz Dziedzic 9 | Creation year: 2014 10 | 11 | Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1. 12 | 13 | Lato is a trademark of tyPoland Lukasz Dziedzic. 14 | 15 | Source URL: http://www.latofonts.com/ 16 | License URL: http://scripts.sil.org/OFL 17 | 18 | ================ 19 | 20 | Lato is a sanserif typeface family designed in the Summer 2010 and extended in the Summer 2013 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in the 2010s, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness. In 2013-2014, the family was greatly extended (with the help of Adam Twardoch and Botio Nikoltchev) to cover 3000+ glyphs over nine weights with italics. It now supports 100+ Latin-based languages, 50+ Cyrillic-based languages as well as Greek and IPA phonetics. The Lato fonts are available free of charge under the SIL Open Font License from http://www.latofonts.com/ 21 | 22 | ================ 23 | 24 | CONTENTS: 25 | 26 | This folder contains 18 font files in OpenType TT (.ttf) format. You can install these fonts on your computer and use in any desktop applications (such as Word, InDesign, Illustrator, Photoshop, Keynote or Pages). 27 | 28 | ================ 29 | 30 | REVISION LOG: 31 | 32 | # Version 2.010 (2014-09-01) 33 | Improved some contour bugs and diacritics positioning. 34 | Improved outline quality. 35 | Revised OTL features so that they work in browsers (ot-sanitise). 36 | Autohinted using ttfautohint 1.1. 37 | Interpolated the Medium weight differently so it provides more visual difference from Regular. 38 | 39 | # Version 2.007 (2014-02-27) 40 | Greatly expanded character set, revised metrics, four additional weights. 41 | 42 | # Version 1.104 (2011-11-08) 43 | Merged the distribution again 44 | Autohinted with updated ttfautohint 0.4 (which no longer causes Adobe and iOS problems) 45 | except the Hai and Lig weights which are hinted in FLS 5.1. 46 | 47 | # Version 1.102 (2011-10-28) 48 | Added OpenType Layout features 49 | Ssplit between desktop and web versions 50 | Desktop version: all weights autohinted with FontLab Studio 51 | Web version autohinted with ttfautohint 0.4 except the Hai and Lig weights 52 | 53 | # Version 1.101 (2011-09-30) 54 | Fixed OS/2 table Unicode and codepage entries 55 | 56 | # Version 1.100 (2011-09-12) 57 | Added Polish diacritics to the character set 58 | Weights Hai and Lig autohinted with FontLab Studio 59 | Other weights autohinted with ttfautohint 0.3 60 | 61 | # Version 1.011 (2010-12-29) 62 | Added the soft hyphen glyph 63 | 64 | # Version 1.010 (2010-12-13) 65 | Initial version released under SIL Open Font License 66 | Western character set 67 | 68 | ================ 69 | -------------------------------------------------------------------------------- /misc/export_jams.php: -------------------------------------------------------------------------------- 1 | set_charset("utf8"); 19 | 20 | function slugify($text) { 21 | $text = preg_replace('~[^\\pL\d]+~u', '-', $text); 22 | $text = trim($text, '-'); 23 | $text = strtolower($text); 24 | $text = preg_replace('~[^-\w]+~', '', $text); 25 | return $text; 26 | } 27 | 28 | function categories_by_id($out=array()) { 29 | global $mysqli; 30 | $res = $mysqli->query("select * from gdc2_categories"); 31 | 32 | while ($row = $res->fetch_assoc()) { 33 | $out[$row["id"]] = $row; 34 | } 35 | 36 | foreach ($out as $k => &$v) { 37 | if ($v["parent"]) { 38 | $v["parent_obj"] = $out[$v["parent"]]; 39 | } 40 | } 41 | 42 | return $out; 43 | } 44 | 45 | function find_first_value($item, $field) { 46 | if (!empty($item[$field])) { 47 | return $item[$field]; 48 | } elseif (!empty($item["parent_obj"])) { 49 | return find_first_value($item["parent_obj"], $field); 50 | } 51 | } 52 | 53 | function parse_themes($str) { 54 | if (empty($str)) return; 55 | $themes = explode(",", $str); 56 | $themes = array_map(function($theme) { 57 | return slugify(trim($theme)); 58 | }, $themes); 59 | 60 | return $themes; 61 | } 62 | 63 | $parents = categories_by_id(); 64 | 65 | function format_time($time, $event) { 66 | if ($event["accurate"]) { 67 | $time_format = "Y-m-d h:i:s O"; 68 | } else { 69 | $time_format = "Y-m-d"; 70 | } 71 | 72 | return date($time_format, $time); 73 | } 74 | 75 | $clause = ""; 76 | 77 | if (isset($year)) { 78 | $clause .= ' and from_unixtime(start, "%X") = ' . $mysqli->escape_string($year); 79 | } 80 | 81 | $res = $mysqli->query("SELECT * FROM gdc2_events where deleted = 0 $clause order by id asc"); 82 | 83 | $events = array(); 84 | while ($row = $res->fetch_assoc()) { 85 | $themes = null; 86 | $tags = array(); 87 | 88 | $parent = isset($parents[$row["parent"]]) ? $parents[$row["parent"]] : false; 89 | $row["parent_obj"] = $parent; 90 | 91 | if ($fetch_images) { 92 | $image = find_first_value($row, "image"); 93 | if ($image) { 94 | $dest = "$image_dir/$image"; 95 | if (!file_exists($dest)) { 96 | error_log("Downloading $image"); 97 | file_put_contents($dest, file_get_contents("$image_root/$image")); 98 | } 99 | } 100 | } 101 | 102 | $current_parent = $parent; 103 | while ($current_parent) { 104 | $tags[] = slugify($current_parent["name"]); 105 | $current_parent = isset($current_parent["parent_obj"]) ? $current_parent["parent_obj"] : false; 106 | } 107 | 108 | if (!empty($row["theme"])) { 109 | $themes = parse_themes($row["theme"]); 110 | } 111 | 112 | $event = array( 113 | "name" => find_first_value($row, "name"), 114 | "start_date" => format_time($row["start"], $row), 115 | "end_date" => format_time($row["end"], $row), 116 | "description" => find_first_value($row, "description"), 117 | "local" => (bool)$row["local_time"], 118 | "url" => find_first_value($row, "url") 119 | ); 120 | 121 | if (!empty($tags)) { 122 | $event["tags"] = $tags; 123 | } 124 | 125 | if (!empty($themes)) { 126 | $event["themes"] = $themes; 127 | } 128 | 129 | if (!empty($image)) { 130 | $event["image"] = "jams/images/$image"; 131 | } 132 | 133 | $events[] = $event; 134 | } 135 | 136 | echo json_encode(array("jams" => $events), JSON_PRETTY_PRINT); 137 | -------------------------------------------------------------------------------- /jams/README.md: -------------------------------------------------------------------------------- 1 | # How to add a new jam 2 | 3 | To add a new jam you can submit a pull request with the information of the jam 4 | added to one of the `json` files in this directory. Once accepted 5 | the page will be updated and your jam will be visible. 6 | 7 | If you're not familiar with creating a pull request then alternatively you can also open an 8 | issue on the [issues tracker](https://github.com/leafo/compohub/issues) with 9 | the jam you want to submit. 10 | 11 | If you don't want to use GitHub at all then you can use this Google Form to submit a jam and an administrator will review your submission and create the change for you: 12 | 13 | Jams are organized by their starting year. Choose the `json` file that 14 | corresponds to the year when your jam starts, if the file doesn't exist yet 15 | then you can create it. 16 | 17 | For example, let's create a new jam that starts *May 4th, 2014 at 12pm* and 18 | lasts 10 days. 19 | 20 | You'll need to create a new object in the `jams` array, the position doesn't 21 | matter but for simplicity keep things in ascending order of start date. 22 | 23 | If you are specifying a time in addition to the date for your start and end then 24 | you should provide a timezone (otherwise it defaults to UTC). More information 25 | on times and dates below. 26 | 27 | The following fields are required: `name`, `url`, `start_date`, `end_date`. 28 | 29 | **jams/2014.json** 30 | 31 | { 32 | jams: [ 33 | .. other jams .., 34 | 35 | { 36 | "name": "My cool jam", 37 | "url": "http://example.com/my-jam", 38 | "start_date": "2014-05-04 13:00 -0700", 39 | "end_date": "2014-05-14 13:00 -0700" 40 | } 41 | ] 42 | } 43 | 44 | 45 | 46 | Optionally you can provide the fields `description`, `image`, `tags`, `themes`. 47 | Here's a more complete version of the above example: 48 | 49 | **jams/2014.json** 50 | 51 | { 52 | jams: [ 53 | .. other jams .., 54 | 55 | { 56 | "name": "My cool jam", 57 | "url": "http://example.com/my-jam", 58 | "start_date": "2014-05-04 13:00 -0700", 59 | "end_date": "2014-05-14 13:00 -0700", 60 | "themes": ["cool-things"], 61 | "tags": ["leafo-jams"], 62 | "description": "This is the jam we've been waiting for, I hope you are ready. I know I am!" 63 | } 64 | ] 65 | } 66 | 67 | 68 | ### Tags and themes 69 | 70 | Tags and themes can be used to categorise your jam. If your jam is part of a 71 | series then definitely make a tag for that series (even if it's the first one 72 | of the series). Re-use existing tags whenever possible. 73 | 74 | Tags and themes should be written `in-lowercase` and `separated-by-dashes`. 75 | 76 | Both tags and themes are JSON arrays, so provide an array of strings (even if 77 | there is only one tag/theme). 78 | 79 | 80 | ### Date and time format 81 | 82 | The following patterns are supported for parsing dates. If either the start or 83 | end can't be parsed then the jam entry is invalid. 84 | 85 | YYYY-MM-DD HH:mm:ss Z 86 | YYYY-MM-DD HH:mm Z 87 | YYYY-MM-DD 88 | 89 | 90 | `Z` means timezone, in the form `+0000`. So PST would be `-0700`. You must 91 | provide 2 digits for day, month, or seconds even when they are less than 10. So 92 | `05` for May, `01` for the first day of the month, etc. 93 | 94 | The final format `YYYY-MM-DD` is special, there is no time or timezone. This 95 | will cause the jam's start time to be `0:00` and end time to be `23:59` in the 96 | viewer's local time zone on the respective days passed in. That makes an 97 | inclusive range from start to end. 98 | 99 | ### Editing an existing jam 100 | 101 | Feel free to edit any existing jams, fixing any errors or adding themes after 102 | they've been announced. 103 | -------------------------------------------------------------------------------- /font/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2014, Łukasz Dziedzic (dziedzic@typoland.com), 2 | with Reserved Font Name Lato. 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | moment = require "moment" 2 | ical = require "ical-generator" 3 | 4 | LIVERELOAD_PORT = 35729; 5 | lrSnippet = require("connect-livereload") { port: LIVERELOAD_PORT } 6 | mountFolder = (connect, dir) -> 7 | return connect.static require("path").resolve dir 8 | 9 | {J} = require "./jamhub" 10 | 11 | module.exports = (grunt) -> 12 | require("load-grunt-tasks")(grunt) 13 | 14 | jam_files = [ 15 | "jams/2011.json" 16 | "jams/2012.json" 17 | "jams/2013.json" 18 | "jams/2014.json" 19 | "jams/2015.json" 20 | ] 21 | 22 | assemble = { 23 | options: { 24 | cache_buster: "#{+new Date}" 25 | layout: "templates/layout.hbs" 26 | root: "../../.." # path to index from jam page 27 | } 28 | 29 | all_jams: { 30 | options: { 31 | root: ".." 32 | page_title: "All game jams" 33 | } 34 | src: "templates/all_jams.hbs" 35 | dest: "jams/index.html" 36 | } 37 | } 38 | 39 | for file in jam_files 40 | build_jam_pages assemble, grunt.file.readJSON file 41 | 42 | build_tag_pages assemble 43 | build_jam_root_page assemble 44 | 45 | grunt.initConfig { 46 | pkg: grunt.file.readJSON "package.json" 47 | 48 | watch: { 49 | coffee: { 50 | files: ['jamhub.coffee'] 51 | tasks: ['coffee'] 52 | options: { 53 | spawn: false 54 | interrupt: false, 55 | debounceDelay: 250 56 | } 57 | } 58 | 59 | sass: { 60 | files: ['jamhub.scss'] 61 | tasks: ['sass'] 62 | options: { 63 | spawn: false 64 | interrupt: false, 65 | debounceDelay: 250 66 | } 67 | } 68 | 69 | # BUG-LR-JSCSS: Livereload doesn't always refresh browser for jamhub.css and jamhub.js. index.html seems fine. 70 | livereload: { 71 | options: { 72 | livereload: LIVERELOAD_PORT 73 | spawn: false 74 | interrupt: false, 75 | debounceDelay: 250 76 | } 77 | files: [ 78 | "jamhub.js" 79 | "jamhub.css" 80 | "index.html" 81 | ] 82 | } 83 | } 84 | 85 | coffee: { 86 | compile: { 87 | files: { 88 | "jamhub.js": "jamhub.coffee" 89 | } 90 | } 91 | } 92 | 93 | sass: { 94 | compile: { 95 | files: { 96 | "jamhub.css": "jamhub.scss" 97 | } 98 | } 99 | } 100 | 101 | connect: { 102 | options: { 103 | port: 9000 104 | hostname: "localhost" 105 | } 106 | livereload: { 107 | options: { 108 | middleware: (connect) -> 109 | return [ 110 | lrSnippet 111 | mountFolder(connect, './') 112 | ] 113 | } 114 | } 115 | } 116 | 117 | open: { 118 | server: { 119 | path: "http://<%= connect.options.hostname %>:<%= connect.options.port %>" 120 | } 121 | } 122 | 123 | 124 | assemble: assemble 125 | } 126 | 127 | grunt.loadNpmTasks "assemble" 128 | grunt.loadNpmTasks "grunt-contrib-sass" 129 | grunt.loadNpmTasks "grunt-contrib-coffee" 130 | 131 | grunt.registerTask "ical", "create ical feed", -> 132 | build_ical_feed assemble 133 | 134 | grunt.registerTask "default", ["coffee", "sass"] 135 | 136 | grunt.registerTask "serve", [ 137 | "coffee" 138 | "sass" 139 | "connect:livereload" 140 | "open" 141 | "watch" 142 | ] 143 | 144 | build_ical_feed = (params) -> 145 | calendar = ical() 146 | calendar.setDomain('compohub.net') 147 | calendar.setName('Compohub Game Jams') 148 | 149 | #Get a list of jams in sorted order 150 | jams = [] 151 | for slug, jam of params.options.jams_by_slug 152 | jams.push(jam) 153 | jams.sort (a, b) -> 154 | b.start_date - a.start_date 155 | 156 | #iCal library does not propery escape carriage returns 157 | escape_carriage_return = (str) -> 158 | str.replace(/\r/g, (match) -> "" ) 159 | 160 | #Iterate through jams, adding it to ical builder 161 | for jam in jams 162 | #Parse dates 163 | [start_date] = J.parse_jam_timestamp jam.start_date 164 | [end_date] = J.parse_jam_timestamp jam.end_date 165 | 166 | #Escape Summary and Description 167 | summary = if jam.name? then escape_carriage_return(jam.name) else "" 168 | description = if jam.description? then escape_carriage_return(jam.description) else "" 169 | 170 | #Ensure that there is both a start_date and end_date for this event 171 | continue unless start_date 172 | continue unless end_date 173 | 174 | calendar.addEvent { 175 | start: start_date, 176 | end: end_date, 177 | summary: summary, 178 | description: description, 179 | url: jam.url, 180 | uid: jam.slug 181 | } 182 | 183 | calendar.saveSync("feed.ics") 184 | 185 | build_jam_pages = (params, jam_data) -> 186 | params.options ||= {} 187 | 188 | # images is reserved name 189 | params.options.jams_by_slug ||= { 190 | images: true 191 | } 192 | 193 | J.Jams.slugify_jams jam_data.jams, params.options.jams_by_slug 194 | 195 | for jam in jam_data.jams 196 | params["jam_#{jam.slug}"] = { 197 | options: { 198 | jam: jam 199 | jam_json: JSON.stringify(jam) 200 | page_title: jam.name 201 | } 202 | src: "templates/jam.hbs" 203 | dest: "#{jam.local_url}/index.html" 204 | } 205 | 206 | params 207 | 208 | format_jam_for_list = (jam, start_date) -> 209 | { 210 | start_date: +start_date.toDate() 211 | simple_date: start_date.format("MMM D") 212 | url: "#{jam.local_url}" 213 | jam: jam 214 | } 215 | 216 | build_tag_pages = (params) -> 217 | jams = params.options.jams_by_slug 218 | 219 | jams_by_tag = {} 220 | 221 | for slug of jams 222 | jam = jams[slug] 223 | [start_date] = J.parse_jam_timestamp jam.start_date 224 | continue unless start_date 225 | start_date = moment start_date 226 | 227 | wrapped = { 228 | start_date: +start_date.toDate() 229 | simple_date: start_date.format("YYYY-MM-DD") 230 | url: "#{jam.local_url}" 231 | jam: jam 232 | } 233 | 234 | if jam.tags 235 | for tag in jam.tags 236 | jams_by_tag[tag] ||= [] 237 | jams_by_tag[tag].push wrapped 238 | 239 | for tag of jams_by_tag 240 | jams = jams_by_tag[tag] 241 | jams.sort (a, b) -> 242 | b.start_date - a.start_date 243 | 244 | params["tag_#{tag}"] = { 245 | options: { 246 | tag: tag 247 | jams: jams 248 | page_title: "Jams taged '#{tag}'" 249 | root: "../.." 250 | } 251 | 252 | src: "templates/tag.hbs" 253 | dest: "tags/#{tag}/index.html" 254 | } 255 | 256 | build_jam_root_page = (params) -> 257 | jams = params.options.jams_by_slug 258 | 259 | jams_by_year = {} 260 | for slug of jams 261 | jam = jams[slug] 262 | [start_date] = J.parse_jam_timestamp jam.start_date 263 | continue unless start_date 264 | start_date = moment start_date 265 | year = start_date.year() 266 | 267 | wrapped = { 268 | start_date: +start_date.toDate() 269 | simple_date: start_date.format("MMM D") 270 | url: "#{jam.local_url}" 271 | jam: jam 272 | } 273 | 274 | unless jams_by_year[year] 275 | jams_by_year[year] = [] 276 | 277 | jams_by_year[year].push wrapped 278 | 279 | year_tuples = for year of jams_by_year 280 | list = jams_by_year[year] 281 | list.sort (a, b) -> 282 | a.start_date - b.start_date 283 | 284 | { year: year, jams: list } 285 | 286 | year_tuples.sort (a, b) -> 287 | b.year - a.year 288 | 289 | params.all_jams.options.jams_by_year = year_tuples 290 | -------------------------------------------------------------------------------- /underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.6.0 2 | // http://underscorejs.org 3 | // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | (function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?void(this._wrapped=n):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.6.0";var A=j.each=j.forEach=function(n,t,e){if(null==n)return n;if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return;return n};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var O="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},j.find=j.detect=function(n,t,r){var e;return k(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var k=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:k(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,j.property(t))},j.where=function(n,t){return j.filter(n,j.matches(t))},j.findWhere=function(n,t){return j.find(n,j.matches(t))},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);var e=-1/0,u=-1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;o>u&&(e=n,u=o)}),e},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);var e=1/0,u=1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;u>o&&(e=n,u=o)}),e},j.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=j.random(r++),e[r-1]=e[t],e[t]=n}),e},j.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=j.values(n)),n[j.random(n.length-1)]):j.shuffle(n).slice(0,Math.max(0,t))};var E=function(n){return null==n?j.identity:j.isFunction(n)?n:j.property(n)};j.sortBy=function(n,t,r){return t=E(t),j.pluck(j.map(n,function(n,e,u){return{value:n,index:e,criteria:t.call(r,n,e,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=E(r),A(t,function(i,a){var o=r.call(e,i,a,t);n(u,o,i)}),u}};j.groupBy=F(function(n,t,r){j.has(n,t)?n[t].push(r):n[t]=[r]}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=E(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])t?[]:o.call(n,0,t)},j.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},j.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},j.rest=j.tail=j.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},j.compact=function(n){return j.filter(n,j.identity)};var M=function(n,t,r){return t&&j.every(n,j.isArray)?c.apply(r,n):(A(n,function(n){j.isArray(n)||j.isArguments(n)?t?a.apply(r,n):M(n,t,r):r.push(n)}),r)};j.flatten=function(n,t){return M(n,t,[])},j.without=function(n){return j.difference(n,o.call(arguments,1))},j.partition=function(n,t){var r=[],e=[];return A(n,function(n){(t(n)?r:e).push(n)}),[r,e]},j.uniq=j.unique=function(n,t,r,e){j.isFunction(t)&&(e=r,r=t,t=!1);var u=r?j.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:j.contains(a,r))||(a.push(r),i.push(n[e]))}),i},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=function(n){var t=o.call(arguments,1);return j.filter(j.uniq(n),function(n){return j.every(t,function(t){return j.contains(t,n)})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===j&&(e[u]=arguments[r++]);for(;r=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u),e=u=null):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o,c=function(){var l=j.now()-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u),i=u=null))};return function(){i=this,u=arguments,a=j.now();var l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u),i=u=null),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return j.partial(t,n)},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=function(n){if(!j.isObject(n))return[];if(w)return w(n);var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o)&&"constructor"in n&&"constructor"in t)return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.constant=function(n){return function(){return n}},j.property=function(n){return function(t){return t[n]}},j.matches=function(n){return function(t){if(t===n)return!0;for(var r in n)if(n[r]!==t[r])return!1;return!0}},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},j.now=Date.now||function(){return(new Date).getTime()};var T={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};T.unescape=j.invert(T.escape);var I={escape:new RegExp("["+j.keys(T.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(T.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(I[n],function(t){return T[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),"function"==typeof define&&define.amd&&define("underscore",[],function(){return j})}).call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /jamhub.scss: -------------------------------------------------------------------------------- 1 | 2 | $primary_color: #5DCC92; 3 | $link_color: #5CCCC4; 4 | $cell_height: 40px; 5 | $label_height: 40px; 6 | $site_width: 640px; 7 | 8 | @mixin transition($args...) { 9 | -webkit-transition: $args; 10 | -moz-transition: $args; 11 | -ms-transition: $args; 12 | transition: $args; 13 | } 14 | 15 | @mixin unselectable { 16 | -moz-user-select: none; 17 | -webkit-user-select: none; 18 | user-select: none; 19 | cursor: default; 20 | } 21 | 22 | @mixin border_box { 23 | box-sizing: border-box; 24 | -moz-box-sizing: border-box; 25 | } 26 | 27 | @mixin single_line { 28 | white-space: nowrap; 29 | overflow: hidden; 30 | text-overflow: ellipsis; 31 | } 32 | 33 | body { 34 | background: #e6e6e6; 35 | font-family: sans-serif; 36 | margin: 0; 37 | color: #333; 38 | font-size: 16px; 39 | 40 | &.nice_fonts { 41 | font-family: lato, sans-serif; 42 | } 43 | 44 | &.dragging { 45 | @include unselectable; 46 | cursor: default; 47 | } 48 | } 49 | 50 | a { 51 | color: darken($link_color, 5%); 52 | 53 | &:hover { 54 | color: $link_color; 55 | } 56 | } 57 | 58 | .header { 59 | height: 200px; 60 | text-align: center; 61 | background: $primary_color; 62 | margin-bottom: 20px; 63 | color: white; 64 | overflow: hidden; 65 | 66 | .header_tools { 67 | position: absolute; 68 | top: 20px; 69 | right: 20px; 70 | } 71 | 72 | .multi_share { 73 | text-align: center; 74 | min-width: 110px; 75 | margin-top: 10px; 76 | 77 | border: 1px solid white; 78 | border-radius: 3px; 79 | overflow: hidden; 80 | 81 | height: 20px; 82 | 83 | @include transition(height 0.15s ease); 84 | 85 | &.open, &:hover { 86 | height: 113px; 87 | 88 | .top { 89 | @include transition(all 0.15s ease); 90 | background: rgba(255,255,255,0.8); 91 | color: $primary_color; 92 | } 93 | } 94 | 95 | .top { 96 | @include unselectable; 97 | text-align: center; 98 | height: 20px; 99 | line-height: 20px; 100 | font-size: 14px; 101 | color: white; 102 | } 103 | 104 | .button { 105 | display: block; 106 | border: 0; 107 | border-top: 1px solid white; 108 | border-radius: 0; 109 | text-align: center; 110 | font-size: 14px; 111 | height: 30px; 112 | line-height: 30px; 113 | } 114 | 115 | .row:last-child { 116 | .button { 117 | border-radius: 0 0 3px 3px; 118 | } 119 | } 120 | } 121 | 122 | .button { 123 | @include transition(all 0.15s ease); 124 | border: 1px solid white; 125 | border-radius: 3px; 126 | height: 40px; 127 | line-height: 40px; 128 | font-size: 18px; 129 | padding: 0 20px; 130 | display: inline-block; 131 | cursor: pointer; 132 | color: white; 133 | text-decoration: none; 134 | min-width: 110px; 135 | text-align: center; 136 | 137 | &:hover { 138 | color: $primary_color; 139 | background-color: white; 140 | } 141 | 142 | &:active { 143 | background-color: mix(white, $primary_color, 75%); 144 | } 145 | } 146 | 147 | h1 { 148 | margin: 0; 149 | margin-top: 52px; 150 | font-family: lato, sans-serif; 151 | font-weight: 200; 152 | font-size: 80px; 153 | line-height: 1.0; 154 | 155 | a { 156 | @include transition(border 0.2s ease); 157 | text-decoration: none; 158 | color: white; 159 | border-bottom: 1px solid rgba(255,255,255, 0); 160 | 161 | &:hover { 162 | border-bottom: 1px solid rgba(255,255,255, 0.5); 163 | } 164 | } 165 | } 166 | 167 | h2 { 168 | margin: 0; 169 | margin-top: 8px; 170 | font-size: 16px; 171 | font-weight: normal; 172 | letter-spacing: 0.10em; 173 | } 174 | } 175 | 176 | 177 | .jam_browser { 178 | margin: 0 20px; 179 | } 180 | 181 | .scrollbar_outer { 182 | @include unselectable; 183 | position: relative; 184 | height: 10px; 185 | margin-top: 6px; 186 | 187 | .scrollbar { 188 | position: absolute; 189 | background: #B8B8B8; 190 | top: 0; 191 | bottom: 0; 192 | border-radius: 24px; 193 | opacity: 0; 194 | @include transition(opacity 0.6s ease); 195 | 196 | &:hover, &.dragging { 197 | background: lighten(#B8B8B8, 3%); 198 | } 199 | 200 | &.visible { 201 | opacity: 1; 202 | } 203 | } 204 | } 205 | 206 | .calendar { 207 | overflow: hidden; 208 | cursor: move; 209 | 210 | .calendar_scrolling { 211 | height: 250px; 212 | position: relative; 213 | background: white; 214 | } 215 | 216 | .calendar_row { 217 | position: relative; 218 | height: $cell_height; 219 | margin: 3px 0; 220 | } 221 | 222 | .jam_cell { 223 | @include border_box; 224 | @include single_line; 225 | position: absolute; 226 | top: 0; 227 | bottom: 0; 228 | background: #A8A8A8; 229 | color: white; 230 | line-height: $cell_height; 231 | padding: 0 20px; 232 | 233 | &.after_end { 234 | opacity: 0.75; 235 | } 236 | 237 | &.small_text { 238 | font-size: 14px; 239 | } 240 | 241 | a { 242 | color: inherit; 243 | text-decoration: none; 244 | &:hover { 245 | text-decoration: underline; 246 | } 247 | } 248 | } 249 | 250 | .calendar_rows, .day_markers { 251 | position: absolute; 252 | top: 0; 253 | right: 0; 254 | bottom: 0; 255 | left: 0; 256 | } 257 | 258 | .elapsed_time { 259 | @include border_box; 260 | position: absolute; 261 | top: 0; 262 | bottom: 0; 263 | left: 0; 264 | width: 50%; 265 | background: #F5F5F5; 266 | border-right: 5px solid #E9E9E9; 267 | box-shadow: 0 0 0 1px #DEDEDE; 268 | } 269 | 270 | .day_markers { 271 | z-index: 1; 272 | @include unselectable; 273 | 274 | .day_marker { 275 | @include border_box; 276 | border-left: 1px solid #dadada; 277 | position: absolute; 278 | top: $label_height; 279 | bottom: 0; 280 | 281 | &:first-child { 282 | border-left: 0; 283 | } 284 | 285 | .day_ordinal, .day_name { 286 | position: absolute; 287 | left: 0; 288 | right: 0; 289 | height: $label_height; 290 | line-height: $label_height; 291 | padding-left: 20px; 292 | } 293 | 294 | .day_ordinal { 295 | top: 0; 296 | border-bottom: 1px solid #dadada; 297 | color: #666; 298 | font-weight: bold; 299 | } 300 | 301 | .day_name { 302 | bottom: 0; 303 | border-top: 1px solid #dadada; 304 | font-size: 13px; 305 | text-transform: uppercase; 306 | color: #777; 307 | } 308 | } 309 | } 310 | 311 | .calendar_rows { 312 | z-index: 2; 313 | top: $label_height * 2 + 2px; 314 | bottom: 30px; 315 | } 316 | 317 | .month_markers { 318 | @include unselectable; 319 | height: 20px; 320 | background: black; 321 | position: relative; 322 | z-index: 5; 323 | 324 | .month_marker { 325 | @include border_box; 326 | background: #B8B8B8; 327 | border-left: 1px solid darken(#B8B8B8, 10%); 328 | color: #444; 329 | 330 | position: absolute; 331 | top: 0; 332 | bottom: 0; 333 | height: $label_height; 334 | line-height: $label_height; 335 | padding: 0 20px; 336 | 337 | &:first-child { 338 | border-left: 0; 339 | } 340 | } 341 | } 342 | } 343 | 344 | 345 | .jam_list, .comments_outer { 346 | width: $site_width; 347 | margin: 0 auto; 348 | 349 | h2 { 350 | font-family: lato, sans-serif; 351 | font-weight: 200; 352 | color: #666; 353 | font-size: 48px; 354 | margin: 48px 0 24px 0; 355 | } 356 | } 357 | 358 | .tagged_jams { 359 | h2 { 360 | font-weight: normal; 361 | font-size: 20px; 362 | color: #555; 363 | } 364 | } 365 | 366 | .comments_outer { 367 | margin-top: 60px; 368 | margin-bottom: 60px; 369 | 370 | h3 { 371 | font-size: 20px; 372 | color: #555; 373 | } 374 | } 375 | 376 | 377 | .jam_box { 378 | background: white; 379 | overflow: hidden; 380 | margin-bottom: 24px; 381 | 382 | &.current_jam { 383 | margin-top: 48px; 384 | } 385 | 386 | &.has_image { 387 | overflow: hidden; 388 | 389 | h3, p { 390 | margin-right: 240px; 391 | } 392 | 393 | .progress_outer { 394 | clear: both; 395 | } 396 | 397 | .cover_image { 398 | float: right; 399 | background: #aaa; 400 | width: 200px; 401 | height: 160px; 402 | margin: 24px 20px 24px 0; 403 | background-size: cover; 404 | background-position: 50% 50%; 405 | } 406 | } 407 | 408 | h3 { 409 | font-weight: normal; 410 | font-size: 26px; 411 | margin: 24px 20px; 412 | color: #666; 413 | 414 | a { 415 | text-decoration: none; 416 | color: inherit; 417 | font-weight: inherit; 418 | 419 | &:hover { 420 | // text-decoration: underline; 421 | border-bottom: 2px solid #aaa; 422 | } 423 | } 424 | } 425 | 426 | p { 427 | margin: 24px 20px; 428 | line-height: 24px; 429 | } 430 | 431 | .jam_link { 432 | @include single_line; 433 | } 434 | 435 | .time_data { 436 | color: #777; 437 | 438 | strong { 439 | color: #888; 440 | } 441 | } 442 | 443 | .progress_outer { 444 | margin: 24px 20px; 445 | 446 | .time_labels { 447 | overflow: hidden; 448 | } 449 | 450 | .left_label, .right_label, .remaining_label { 451 | font-size: 16px; 452 | color: #777; 453 | } 454 | 455 | .left_label, .right_label { 456 | position: relative; 457 | margin-bottom: 16px; 458 | } 459 | 460 | .left_label { 461 | float: left; 462 | text-align: left; 463 | 464 | &:before { 465 | content: ""; 466 | width: 2px; 467 | height: 8px; 468 | background: #ccc; 469 | position: absolute; 470 | bottom: -11px; 471 | left: 0; 472 | } 473 | } 474 | 475 | .right_label { 476 | text-align: right; 477 | 478 | &:before { 479 | content: ""; 480 | width: 2px; 481 | height: 8px; 482 | background: #ccc; 483 | position: absolute; 484 | bottom: -11px; 485 | right: 0; 486 | } 487 | } 488 | 489 | .remaining_label { 490 | margin-top: 8px; 491 | text-align: right; 492 | } 493 | 494 | .progress { 495 | background: rgba(darken($primary_color, 10%), 0.3); 496 | height: 10px; 497 | position: relative; 498 | 499 | .progress_inner { 500 | position: absolute; 501 | top: 0; 502 | bottom: 0; 503 | left: 0; 504 | 505 | width: 50%; 506 | background: $primary_color; 507 | } 508 | } 509 | } 510 | 511 | .jam_tags { 512 | margin: 24px 20px; 513 | text-align: right; 514 | 515 | .jam_tag { 516 | position: relative; 517 | background: darken($link_color, 5%); 518 | color: white; 519 | display: inline-block; 520 | padding: 0px 10px 0 8px; 521 | height: 24px; 522 | line-height: 24px; 523 | font-size: 14px; 524 | margin-left: 22px; 525 | text-decoration: none; 526 | 527 | &:hover { 528 | background-color: $link_color; 529 | &:before { 530 | border-color:transparent $link_color transparent transparent; 531 | } 532 | } 533 | 534 | &:before { 535 | content: ""; 536 | position: absolute; 537 | left: -12px; 538 | border-color:transparent darken($link_color, 5%) transparent transparent; 539 | border-style: solid; 540 | border-width: 12px 12px 12px 0; 541 | } 542 | } 543 | } 544 | } 545 | 546 | .link_back { 547 | text-align: center; 548 | 549 | a { 550 | @include transition(background 0.2s ease); 551 | color: #666; 552 | border: 1px solid #B9B9B9; 553 | border-radius: 3px; 554 | height: 40px; 555 | line-height: 40px; 556 | padding: 0 20px; 557 | display: inline-block; 558 | font-size: 18px; 559 | text-decoration: none; 560 | 561 | &:hover { 562 | background: rgba(0,0,0,0.07); 563 | } 564 | 565 | &:active { 566 | background: rgba(0,0,0,0.10); 567 | } 568 | } 569 | } 570 | 571 | .footer { 572 | width: $site_width; 573 | margin: 20px auto; 574 | text-align: center; 575 | border-top: 1px solid #D3D3D3; 576 | padding-top: 10px; 577 | font-size: 14px; 578 | color: #aaa; 579 | 580 | a { 581 | color: #999; 582 | } 583 | } 584 | 585 | 586 | .jam_year, .jam_tag_list { 587 | ul { 588 | overflow: hidden; 589 | margin: 0; 590 | padding: 24px 20px; 591 | 592 | background: white; 593 | font-size: 16px; 594 | line-height: 1.5; 595 | 596 | .simple_date { 597 | background: #eee; 598 | display: inline-block; 599 | font-family: monospace; 600 | padding: 2px 8px; 601 | vertical-align: middle; 602 | text-align: left; 603 | min-width: 70px; 604 | font-size: 14px; 605 | margin-right: 10px; 606 | } 607 | 608 | li { 609 | list-style: none; 610 | padding: 0; 611 | margin: 0; 612 | margin-bottom: 5px; 613 | } 614 | } 615 | } 616 | 617 | 618 | -------------------------------------------------------------------------------- /jams/2011.json: -------------------------------------------------------------------------------- 1 | { 2 | "jams": [ 3 | { 4 | "name": "Experimental Gameplay Project - November", 5 | "start_date": "2011-11-01", 6 | "end_date": "2011-11-30", 7 | "description": "An event that is running all the time! On the first day of each month a new theme is announced and then you have 7 days to make a game based on that theme. No voting, everybody is a winner.", 8 | "local": false, 9 | "url": "http:\/\/experimentalgameplay.com", 10 | "tags": [ 11 | "experimental-gameplay-project" 12 | ], 13 | "themes": [ 14 | "upgrade" 15 | ], 16 | "image": "jams\/images\/394033884e81fcdd5c1342.40999022.png" 17 | }, 18 | { 19 | "name": "The Fourth Super Friendship Club Pageant", 20 | "start_date": "2012-01-01", 21 | "end_date": "2012-01-31", 22 | "description": "Super Friendship Club arranges pageants (game development competitions) every 2 months.", 23 | "local": false, 24 | "url": "http:\/\/superfriendshipclub.com", 25 | "tags": [ 26 | "super-friendship-club" 27 | ], 28 | "themes": [ 29 | "universe" 30 | ], 31 | "image": "jams\/images\/20407160144e81fc8ca13646.87700235.png" 32 | }, 33 | { 34 | "name": "Ludum Dare #22", 35 | "start_date": "2011-12-17 02:00:00 +0000", 36 | "end_date": "2011-12-19 02:00:00 +0000", 37 | "description": "Dual event with 48h competition and 72h jam. The competition has stricter rules than the jam and it's only for solo developers but otherwise they are the same.", 38 | "local": false, 39 | "url": "http:\/\/www.ludumdare.com\/compo\/", 40 | "tags": [ 41 | "ludum-dare" 42 | ], 43 | "themes": [ 44 | "alone" 45 | ], 46 | "image": "jams\/images\/2576340814e81fd09b7e248.82235325.png" 47 | }, 48 | { 49 | "name": "Klik of the Month Klub #53", 50 | "start_date": "2011-11-20 01:00:00 +0000", 51 | "end_date": "2011-11-20 03:00:00 +0000", 52 | "description": "A two hour event every month. Using Klik & Play is highly recommended.", 53 | "local": false, 54 | "url": "http:\/\/www.glorioustrainwrecks.com", 55 | "tags": [ 56 | "klik-of-the-month-klub", 57 | "glorious-trainwrecks" 58 | ], 59 | "image": "jams\/images\/3709999234e81fd00a63371.60060855.png" 60 | }, 61 | { 62 | "name": "Blitzkast Monthly VII", 63 | "start_date": "2011-11-13", 64 | "end_date": "2011-11-13", 65 | "description": "You have 4 hours to build a game prototype within the timeframe. Using the announced theme is optional. Make the game you've always dreamed about.", 66 | "local": false, 67 | "url": "http:\/\/www.thepoppenkast.com", 68 | "tags": [ 69 | "blitzkast" 70 | ], 71 | "themes": [ 72 | "modularity-weird-occultism" 73 | ], 74 | "image": "jams\/images\/1818960464e81fd1bc94c14.96327136.png" 75 | }, 76 | { 77 | "name": "0h Game Jam, US & Canada", 78 | "start_date": "2011-11-06 02:00:00 +0000", 79 | "end_date": "2011-11-06 03:00:00 +0000", 80 | "description": "Zero hour game jam! In many countries clocks shift one hour to the past because of the DST change, which means that there's an extra hour that sould be used, of course, to make a game.\r\n\r\nWarning!<\/em> The time may not show correctly.", 81 | "local": true, 82 | "url": "http:\/\/0hgame.eu", 83 | "tags": [ 84 | "0h-game-jam" 85 | ], 86 | "image": "jams\/images\/16948013604ead9a1feb2934.png" 87 | }, 88 | { 89 | "name": "MiniLD #30", 90 | "start_date": "2011-11-05 02:00:00 +0000", 91 | "end_date": "2011-11-07 02:00:00 +0000", 92 | "description": "Mini Ludum Dares are here to fill the boring months without ordinary Ludum Dares. The host changes every time and so do the rules. It all depends on the host but MiniLDs are often relaxed compared to LDs.", 93 | "local": false, 94 | "url": "http:\/\/www.ludumdare.com\/compo\/", 95 | "tags": [ 96 | "minild", 97 | "ludum-dare" 98 | ], 99 | "themes": [ 100 | "adaptation" 101 | ], 102 | "image": "jams\/images\/2576340814e81fd09b7e248.82235325.png" 103 | }, 104 | { 105 | "name": "The Third Super Friendship Club Pageant", 106 | "start_date": "2011-11-01", 107 | "end_date": "2011-11-30", 108 | "description": "Super Friendship Club arranges pageants (game development competitions) every 2 months.", 109 | "local": false, 110 | "url": "http:\/\/superfriendshipclub.com", 111 | "tags": [ 112 | "super-friendship-club" 113 | ], 114 | "themes": [ 115 | "editor" 116 | ], 117 | "image": "jams\/images\/20407160144e81fc8ca13646.87700235.png" 118 | }, 119 | { 120 | "name": "0h Game Jam, EU", 121 | "start_date": "2011-10-30 02:00:00 +0000", 122 | "end_date": "2011-10-30 03:00:00 +0000", 123 | "description": "Zero hour game jam! In many countries clocks shift one hour to the past because of the DST change, which means that there's an extra hour that sould be used, of course, to make a game.\r\n\r\nWarning!<\/em> The time may not show correctly.", 124 | "local": false, 125 | "url": "http:\/\/0hgame.eu", 126 | "tags": [ 127 | "0h-game-jam" 128 | ], 129 | "image": "jams\/images\/16948013604ead9a1feb2934.png" 130 | }, 131 | { 132 | "name": "#GPCv9", 133 | "start_date": "2011-10-10 08:00:00 +0000", 134 | "end_date": "2011-10-18 08:00:00 +0000", 135 | "description": "Game Prototype Challenge is about taking two themes and mashing up them into a game prototype.", 136 | "local": false, 137 | "url": "http:\/\/gameprototypechallenge.com", 138 | "tags": [ 139 | "game-prototype-challenge" 140 | ], 141 | "image": "jams\/images\/5881530114e81fce6e265e9.02648622.png" 142 | }, 143 | { 144 | "name": "Experimental Gameplay Project - October", 145 | "start_date": "2011-10-01", 146 | "end_date": "2011-10-31", 147 | "description": "An event that is running all the time! On the first day of each month a new theme is announced and then you have 7 days to make a game based on that theme. No voting, everybody is a winner.", 148 | "local": false, 149 | "url": "http:\/\/experimentalgameplay.com", 150 | "tags": [ 151 | "experimental-gameplay-project" 152 | ], 153 | "themes": [ 154 | "slicing" 155 | ], 156 | "image": "jams\/images\/394033884e81fcdd5c1342.40999022.png" 157 | }, 158 | { 159 | "name": "Ludum Dare - The October Challenge", 160 | "start_date": "2011-10-01", 161 | "end_date": "2011-10-31", 162 | "description": "The point of The October Challenge is to make a game and then sell it one way or another. No specific rules, you can start any time you want.", 163 | "local": false, 164 | "url": "http:\/\/www.ludumdare.com\/compo\/", 165 | "tags": [ 166 | "ludum-dare-the-october-challenge", 167 | "ludum-dare" 168 | ], 169 | "image": "jams\/images\/2576340814e81fd09b7e248.82235325.png" 170 | }, 171 | { 172 | "name": "Fall Folklore TIGER Assault", 173 | "start_date": "2011-10-03 10:01:00 +0000", 174 | "end_date": "2011-10-31 08:00:00 +0000", 175 | "description": "A free form competition. Everything goes as long as the game works on Windows.", 176 | "local": false, 177 | "url": "http:\/\/forums.tigsource.com\/index.php?topic=22023.0", 178 | "tags": [ 179 | "tigforums" 180 | ], 181 | "themes": [ 182 | "folklore", 183 | "urban-regional-legends" 184 | ], 185 | "image": "jams\/images\/5813508324ec80ddb9370b8.82371048.png" 186 | }, 187 | { 188 | "name": "Scary Four Digits 2011", 189 | "start_date": "2011-10-07 12:00:00 +0000", 190 | "end_date": "2011-10-30 12:00:00 +0000", 191 | "description": "64digits is a small, close-knit community focused on game development and artistic endeavours. A few times a year, they host competitions to hone their skills, express ideas, and just to have fun! The contest is held entirely online and everyone is encouraged to participate.", 192 | "local": false, 193 | "url": "http:\/\/64digits.com\/users\/index.php?userid=Toast&cmd=comments&id=271479", 194 | "tags": [ 195 | "64digits" 196 | ], 197 | "themes": [ 198 | "halloween-horror" 199 | ], 200 | "image": "jams\/images\/14398886984e81fd1418e4f9.82238073.png" 201 | }, 202 | { 203 | "name": "#GPCv10", 204 | "start_date": "2011-12-05 05:00:00 +0000", 205 | "end_date": "2011-12-13 04:59:00 +0000", 206 | "description": "Game Prototype Challenge is about taking two themes and mashing up them into a game prototype.", 207 | "local": false, 208 | "url": "http:\/\/gameprototypechallenge.com", 209 | "tags": [ 210 | "game-prototype-challenge" 211 | ], 212 | "themes": [ 213 | "dreams", 214 | "collectibles" 215 | ], 216 | "image": "jams\/images\/5881530114e81fce6e265e9.02648622.png" 217 | }, 218 | { 219 | "name": "Blitzkast Monthly IX", 220 | "start_date": "2011-12-11", 221 | "end_date": "2011-12-11", 222 | "description": "You have 4 hours to build a game prototype within the timeframe. Using the announced theme is optional. Make the game you've always dreamed about.", 223 | "local": false, 224 | "url": "http:\/\/www.thepoppenkast.com", 225 | "tags": [ 226 | "blitzkast" 227 | ], 228 | "themes": [ 229 | "pyramid" 230 | ], 231 | "image": "jams\/images\/1818960464e81fd1bc94c14.96327136.png" 232 | }, 233 | { 234 | "name": "2012: THE END IS UPON US", 235 | "start_date": "2011-12-01", 236 | "end_date": "2012-01-01", 237 | "description": "The world is going to end in 2012, make a game that illustrates this. No engine, platform or team restrictions.", 238 | "local": false, 239 | "url": "http:\/\/forums.tigsource.com\/index.php?topic=22859.0", 240 | "tags": [ 241 | "tigforums" 242 | ], 243 | "themes": [ 244 | "apocalypse" 245 | ], 246 | "image": "jams\/images\/5813508324ec80ddb9370b8.82371048.png" 247 | }, 248 | { 249 | "name": "Java4K 2012", 250 | "start_date": "2011-12-01", 251 | "end_date": "2012-02-29", 252 | "description": "A competition for Java games that are maximum of 4096 bytes in size.", 253 | "local": false, 254 | "url": "http:\/\/www.java4k.com", 255 | "tags": [ 256 | "java4k" 257 | ], 258 | "image": "jams\/images\/1142016024ec90d328f6348.64394634.png" 259 | }, 260 | { 261 | "name": "Braingale Competition 2011", 262 | "start_date": "2011-11-01 05:00:00 +0000", 263 | "end_date": "2011-12-24 05:00:00 +0000", 264 | "description": "A contest that ends just before Christmas. Prizes for the best three games. ", 265 | "local": false, 266 | "url": "http:\/\/braingale.net\/forum\/index.php?topic=123.0", 267 | "tags": [ 268 | "braingale" 269 | ], 270 | "themes": [ 271 | "arcade" 272 | ], 273 | "image": "jams\/images\/5056893384ec919f008ff74.18114017.png" 274 | }, 275 | { 276 | "name": "2012 Independent Propeller Awards Competition", 277 | "start_date": "2011-11-15 05:00:00 +0000", 278 | "end_date": "2011-12-16 04:59:00 +0000", 279 | "description": "Game can be started and finished before the competition. Big prizes!", 280 | "local": false, 281 | "url": "http:\/\/contest.indiepub.com\/?q=contest", 282 | "tags": [ 283 | "indiepub" 284 | ], 285 | "image": "jams\/images\/20363448984ec933b019dee5.26597249.png" 286 | }, 287 | { 288 | "name": "The Newgrounds Game Jam 6", 289 | "start_date": "2011-12-02", 290 | "end_date": "2011-12-04", 291 | "description": "Newgrounds Game Jams are for randomly generated teams of four or less, and they last for one weekend.", 292 | "local": false, 293 | "url": "http:\/\/austinbreed.newgrounds.com\/news\/post\/657704", 294 | "tags": [ 295 | "game-jam", 296 | "newgrounds" 297 | ], 298 | "themes": [ 299 | "hallucinations" 300 | ], 301 | "image": "jams\/images\/9357150184ed42c5861d735.08548510.png" 302 | }, 303 | { 304 | "name": "Timezone Lottery Klik Jam #9", 305 | "start_date": "2011-12-04 07:00:00 +0000", 306 | "end_date": "2011-12-04 09:00:00 +0000", 307 | "description": "A two hour event on the first Saturday of each month. Time is chosen randomly. Using Klik & Play is highly recommended.", 308 | "local": false, 309 | "url": "http:\/\/www.glorioustrainwrecks.com\/node\/2066", 310 | "tags": [ 311 | "timezone-lottery-klik-jam", 312 | "glorious-trainwrecks" 313 | ], 314 | "image": "jams\/images\/3709999234e81fd00a63371.60060855.png" 315 | }, 316 | { 317 | "name": "Klik of the Month Klub #54", 318 | "start_date": "2011-12-18 12:00:00 +0000", 319 | "end_date": "2011-12-18 02:00:00 +0000", 320 | "description": "A two hour event every month. Using Klik & Play is highly recommended.", 321 | "local": false, 322 | "url": "http:\/\/www.glorioustrainwrecks.com\/node\/2065", 323 | "tags": [ 324 | "klik-of-the-month-klub", 325 | "glorious-trainwrecks" 326 | ], 327 | "image": "jams\/images\/3709999234e81fd00a63371.60060855.png" 328 | }, 329 | { 330 | "name": "Experimental Gameplay Project - 5 Buttons Competition", 331 | "start_date": "2011-12-01 03:00:00 +0000", 332 | "end_date": "2012-01-31 07:59:00 +0000", 333 | "description": "This time EGP is partnering with 02L > Outside Standing Level<\/a> to bring you a real competition with cash prizes! Games must be Windows executables.", 334 | "local": false, 335 | "url": "http:\/\/experimentalgameplay.com\/blog\/2011\/12\/5-buttons-competition-in-decemberjanuary\/", 336 | "tags": [ 337 | "experimental-gameplay-project" 338 | ], 339 | "themes": [ 340 | "5-buttons" 341 | ], 342 | "image": "jams\/images\/394033884e81fcdd5c1342.40999022.png" 343 | }, 344 | { 345 | "name": "Flash in a Flash Creation Contest", 346 | "start_date": "2011-12-22 04:00:00 +0000", 347 | "end_date": "2012-01-06 07:59:00 +0000", 348 | "description": "Create a Flash game with Unity 3.5 beta and win $20,000!", 349 | "local": false, 350 | "url": "http:\/\/unity3d.com\/unity\/preview\/contest", 351 | "tags": [ 352 | "unity" 353 | ], 354 | "image": "jams\/images\/5547059584ef4cba2eb7b79.79793277.png" 355 | }, 356 | { 357 | "name": "Level Up 2011", 358 | "start_date": "2011-11-29 08:01:00 +0000", 359 | "end_date": "2012-03-20 07:59:00 +0000", 360 | "description": "A competition for Windows game demos. The grand prize is $10,000 and the finalists will be featured on Steam. Note that you must be at least 18 years old.", 361 | "local": false, 362 | "url": "http:\/\/software.intel.com\/sites\/campaigns\/levelup2011\/", 363 | "tags": [ 364 | "level-up" 365 | ], 366 | "image": "jams\/images\/553949174f2bd02caa84e1.40172513.png" 367 | } 368 | ] 369 | } -------------------------------------------------------------------------------- /jamhub.coffee: -------------------------------------------------------------------------------- 1 | J = {} 2 | 3 | global = (typeof exports == "undefined" && window || exports) 4 | global.J = J 5 | 6 | $ = global.$ || { easing: {}, fn: {} } 7 | _ = global._ || { template: -> } 8 | moment = global.moment || require "moment" 9 | 10 | $.easing.easeInOutQuad = (x, t, b, c, d) -> 11 | return c/2*t*t + b if ((t/=d/2) < 1) 12 | return -c/2 * ((--t)*(t-2) - 1) + b 13 | 14 | $.fn.draggable = (opts={}) -> 15 | touch_enabled = 'ontouchstart' of document 16 | 17 | # TODO: add touchstart, etc 18 | body = $ document.body 19 | html = $ "html" 20 | 21 | mouse_x = 0 22 | mouse_y = 0 23 | 24 | drag_stop = (e) => 25 | body.removeClass "dragging" 26 | @removeClass "dragging" 27 | html.off "mousemove touchmove", drag_move 28 | opts.stop?() 29 | 30 | drag_move = (e, _x, _y) => 31 | dx = _x - mouse_x 32 | dy = _y - mouse_y 33 | mouse_x += dx 34 | mouse_y += dy 35 | opts.move? dx, dy 36 | 37 | drag_start = (e, _x, _y) => 38 | return if body.is ".dragging" 39 | return if opts.skip_drag? e 40 | 41 | body.addClass "dragging" 42 | @addClass "dragging" 43 | mouse_x = _x 44 | mouse_y = _y 45 | opts.start?() 46 | true 47 | 48 | # start, stop, move 49 | if touch_enabled 50 | @on "touchstart", (e) => 51 | {pageX: x, pageY: y } = e.originalEvent.targetTouches[0] 52 | if drag_start e, x, y 53 | html.one "touchend", drag_stop 54 | 55 | drag_move = do (move=drag_move) => 56 | (e) => 57 | {pageX: x, pageY: y } = e.originalEvent.targetTouches[0] 58 | move e, x, y 59 | 60 | html.on "touchmove", drag_move 61 | 62 | false 63 | else 64 | @on "mousedown", (e) => 65 | if drag_start e, e.pageX, e.pageY 66 | html.one "mouseup", drag_stop 67 | 68 | drag_move = do (move=drag_move) => 69 | (e) => move e, e.pageX, e.pageY 70 | 71 | html.on "mousemove", drag_move 72 | 73 | 74 | J.parse_jam_timestamp = do -> 75 | patterns = [ 76 | "YYYY-MM-DD HH:mm:ss Z" 77 | "YYYY-MM-DD HH:mm Z" 78 | "YYYY-MM-DD" 79 | ] 80 | 81 | loose_patterns = { 82 | "YYYY-MM-DD": true 83 | } 84 | 85 | (timestamp) -> 86 | for p in patterns 87 | d = moment timestamp, p, true 88 | break if d.isValid() 89 | 90 | d = moment "#{timestamp} +0000", p, true 91 | break if d.isValid() 92 | 93 | [d.isValid() && d.toDate(), loose_patterns[p]] 94 | 95 | J.slugify = (str) -> 96 | str.toLowerCase() 97 | .replace(/\+/g, " plus ") 98 | .replace(/\s+/g, "-") 99 | .replace(/[^\w-]+/g, "") 100 | .replace(/--+/g, "-") 101 | .replace(/^-/, "") 102 | .replace(/-$/, "") 103 | 104 | class J.Jams 105 | # get all active jam.json 106 | @jam_urls: -> 107 | today = moment() 108 | start_year = today.subtract("month", 1).get "year" 109 | end_year = today.add("month", 2).get "year" 110 | 111 | urls = ["jams/" + start_year + ".json"] 112 | if end_year != start_year 113 | urls.push "jams/" + end_year + ".json" 114 | 115 | urls 116 | 117 | @fetch: (fn) -> 118 | urls = @jam_urls() 119 | @_deferred ||= $.when(($.get(url) for url in urls)...).then => 120 | all_jams = [] 121 | if urls.length > 1 122 | for res in arguments 123 | all_jams = all_jams.concat res[0].jams 124 | else 125 | all_jams = arguments[0].jams 126 | 127 | @slugify_jams all_jams 128 | new J.Jams all_jams 129 | 130 | @_deferred.done fn 131 | 132 | @slugify_jams: (jams, jams_by_slug={}) -> 133 | for jam in jams 134 | jam.slug = J.slugify jam.name 135 | [start_date] = J.parse_jam_timestamp jam.start_date 136 | start_date = moment start_date 137 | 138 | # name taken 139 | if jams_by_slug[jam.slug] 140 | jam.slug += "-#{start_date.year()}-#{start_date.format("MMMM")}".toLowerCase() 141 | 142 | # name still taken, add day 143 | if jams_by_slug[jam.slug] 144 | jam.slug += "-#{start_date.date()}".toLowerCase() 145 | 146 | if jams_by_slug[jam.slug] 147 | throw "jam name still taken" 148 | 149 | jams_by_slug[jam.slug] = jam 150 | jam.local_url = "jams/#{start_date.year()}/#{jam.slug}" 151 | 152 | if jam.tags 153 | for i of jam.tags 154 | jam.tags[i] = J.slugify jam.tags[i] 155 | 156 | jams_by_slug 157 | 158 | constructor: (data) -> 159 | @jams = for jam_data in data 160 | new J.Jam jam_data 161 | 162 | truncate: (time) -> 163 | @jams = _.reject @jams, (jam) => jam.end_date() < time 164 | 165 | find_in_progress: -> 166 | _.filter @jams, (jam) => jam.in_progress() 167 | 168 | find_in_before_start: -> 169 | _.filter @jams, (jam) => jam.before_start() 170 | 171 | find_in_range: (start, end) -> 172 | _.filter @jams, (jam) => jam.collides_with start, end 173 | 174 | class J.Jam 175 | box_tpl: _.template """ 176 |
177 | <% if (image) { %> 178 | 179 |
180 |
181 | <% } %> 182 | 183 |

184 | <% if (url) { %> 185 | <%- name %> 186 | <% } else { %> 187 | <%- name %> 188 | <% }%> 189 |

190 | 191 | <% if (url) { %> 192 | 195 | <% }%> 196 |

<%- description %>

197 | <%= time_data %> 198 | <% if (tags && tags.length) {%> 199 |
200 | <% _.each(tags, function(tag) {%> 201 | <%- tag %> 202 | <% }) %> 203 |
204 | <% } %> 205 |
206 | """ 207 | 208 | in_progress_tpl: _.template """ 209 |
210 |
211 |
<%- start_label %>
212 |
<%- end_label %>
213 |
214 | 215 |
216 |
217 |
218 | 219 |
<%- remaining_label %> left
220 |
221 | """ 222 | 223 | time_tpl: _.template """ 224 |
225 |

<%= time_label %>

226 |
227 | """ 228 | 229 | calendar_template: _.template """ 230 |
235 | """ 236 | 237 | constructor: (@data) -> 238 | 239 | length: -> 240 | @end_date() - @start_date() 241 | 242 | render_for_calendar: -> 243 | $(@calendar_template @data) 244 | .data("jam", @) 245 | .toggleClass("after_end", @after_end()) 246 | 247 | render: -> 248 | tags = [].concat(@data.themes || []).concat(@data.tags || []) 249 | $ @box_tpl $.extend { image: false }, @data, { 250 | tags: tags 251 | time_data: @render_time_data() 252 | } 253 | 254 | render_time_data: -> 255 | if @in_progress() 256 | progress = (new Date() - @start_date()) / (@end_date() - @start_date()) 257 | @in_progress_tpl { 258 | percent_complete: Math.floor progress * 100 259 | start_label: @date_format @start_date(), "start" 260 | end_label: @date_format @end_date(), "end" 261 | remaining_label: moment(@end_date()).fromNow true 262 | } 263 | else if @before_start() 264 | relative = moment(@start_date()).fromNow true 265 | begin = @date_format @start_date(), "start" 266 | end = @date_format @end_date(), "end" 267 | 268 | @time_tpl { 269 | time_label: "Starts in #{relative} · #{begin} to #{end}" 270 | } 271 | else if @after_end() 272 | @time_tpl { 273 | time_label: "Ended #{moment(@end_date()).fromNow true} ago" 274 | } 275 | 276 | date_format: (date, name) -> 277 | is_loose = @["_#{name}_date_loose"] 278 | 279 | f = "ll" 280 | f = "#{f} H:mm" unless is_loose 281 | moment(date).format(f) 282 | 283 | collides_with: (range_start, range_end) -> 284 | return false if +@start_date() > +range_end 285 | return false if +@end_date() < +range_start 286 | true 287 | 288 | in_progress: -> 289 | now = +new Date() 290 | now >= +@start_date() && now <= +@end_date() 291 | 292 | before_start: -> 293 | now = +new Date() 294 | now < +@start_date() 295 | 296 | after_end: -> 297 | now = +new Date() 298 | now > +@end_date() 299 | 300 | start_date: -> 301 | unless @_start_date 302 | [@_start_date, @_start_date_loose] = J.parse_jam_timestamp @data.start_date 303 | @_start_date 304 | 305 | end_date: -> 306 | unless @_end_date 307 | [@_end_date, @_end_date_loose] = J.parse_jam_timestamp @data.end_date 308 | if @_end_date_loose 309 | @_end_date = moment(@_end_date).endOf("day").toDate() 310 | 311 | @_end_date 312 | 313 | share_message: => 314 | "#{@data.name} - #{@date_format @start_date()} to #{@date_format @end_date()} #compohub" 315 | 316 | class J.List 317 | constructor: (el) -> 318 | J.list = @ 319 | @el = $ el 320 | 321 | J.Jams.fetch (@jams) => 322 | @render_in_progress() 323 | @render_upcoming() 324 | 325 | render_in_progress: -> 326 | jams = @jams.find_in_progress() 327 | return unless jams.length 328 | 329 | @el.append "

Jams in progress

" 330 | jams.sort (a,b) -> 331 | a_remaining = +new Date() - +a.start_date() 332 | b_remaining = +new Date() - +b.start_date() 333 | a_remaining - b_remaining 334 | 335 | for jam in jams 336 | @el.append jam.render() 337 | 338 | render_upcoming: -> 339 | jams = @jams.find_in_before_start() 340 | 341 | return unless jams.length 342 | 343 | @el.append "

Upcoming

" 344 | 345 | jams.sort (a,b) -> 346 | a.start_date() - b.start_date() 347 | 348 | # remove dupes 349 | seen = {} 350 | jams = for jam in jams 351 | continue if seen[jam.data.name] 352 | seen[jam.data.name] = true 353 | jam 354 | 355 | for jam in jams 356 | @el.append jam.render() 357 | 358 | show_jam: (jam) -> 359 | new_jam = jam.render() 360 | .addClass("current_jam") 361 | 362 | if @current 363 | @current.fadeOut => 364 | @el.find(".current_jam").remove() 365 | new_jam.prependTo(@el) 366 | .hide() 367 | .fadeIn() 368 | else 369 | new_jam.prependTo(@el) 370 | .hide() 371 | .slideDown() 372 | 373 | @current = new_jam 374 | 375 | class J.Calendar 376 | default_color: [149, 52, 58] 377 | day_width: 120 378 | 379 | constructor: (el) -> 380 | J.calendar = @ 381 | @el = $ el 382 | @setup_events() 383 | 384 | J.Jams.fetch (@jams) => 385 | @jams.truncate @start_date() 386 | 387 | @render_jams() 388 | @render_day_markers() 389 | @render_month_markers() 390 | @render_elapsed_time() 391 | 392 | @setup_scrollbar() 393 | @setup_fixed_labels() 394 | @scroll_to_date new Date() 395 | 396 | @setup_dragging() 397 | 398 | @list = new J.List $ ".jam_list" 399 | 400 | setup_events: -> 401 | @el.on "click", ".jam_cell a", (e) => 402 | target = $(e.currentTarget).closest ".jam_cell" 403 | jam = target.data "jam" 404 | @list.show_jam jam 405 | e.preventDefault() 406 | 407 | setup_scrollbar: -> 408 | scrollbar_outer = $(""" 409 |
410 |
411 |
412 | """).appendTo(@el) 413 | 414 | @scrollbar = scrollbar_outer.find(".scrollbar") 415 | setTimeout (=> @scrollbar.addClass "visible"), 0 416 | 417 | update_scroll = => 418 | left = @calendar.scrollLeft() 419 | width = @calendar.width() 420 | inner_width = @scroller.width() 421 | 422 | @scrollbar.css { 423 | left: "#{Math.floor (left / inner_width) * width}px" 424 | right: "#{Math.floor ((inner_width - (left + width)) / inner_width) * width}px" 425 | } 426 | 427 | @calendar.on "scroll", update_scroll 428 | update_scroll() 429 | 430 | move_calendar: (dx, dy) -> 431 | @calendar.scrollLeft @calendar.scrollLeft() - dx 432 | @update_labels?() 433 | 434 | setup_dragging: (el) -> 435 | @calendar.draggable { 436 | skip_drag: (e) => 437 | return true if $(e.target).closest("a").length 438 | 439 | move: (dx, dy) => 440 | @move_calendar dx, dy 441 | } 442 | 443 | @el.find(".scrollbar").draggable { 444 | move: (dx, dy) => 445 | scale = @scroller.width() / @calendar.width() 446 | @move_calendar dx * -scale, dy 447 | } 448 | 449 | @el.on "click", ".scrollbar_outer", (e) => 450 | return if $(e.target).is ".scrollbar" 451 | left = $(e.currentTarget).find(".scrollbar").offset().left 452 | left_mouse = e.pageX 453 | width = Math.floor @scroller.width() / 10 454 | 455 | if left_mouse < left 456 | @move_calendar width, 0 457 | else 458 | @move_calendar -width, 0 459 | 460 | setup_fixed_labels: -> 461 | @update_labels = => 462 | viewport_left = @calendar.scrollLeft() 463 | viewport_right = viewport_left + @calendar.width() 464 | 465 | @fixed_labels ||= ($(el) for el in @calendar.find ".fixed_label") 466 | 467 | for label in @fixed_labels 468 | parent = label.parent() 469 | left = parent.position().left 470 | right = left + parent.width() 471 | visible = right >= viewport_left && left <= viewport_right 472 | parent.toggleClass "visible", visible 473 | 474 | label_width = label.outerWidth() 475 | 476 | margin_left = viewport_left - left 477 | 478 | margin_left = if margin_left > 0 479 | max_right = (right - left) - label_width 480 | margin_left = Math.min margin_left, max_right 481 | "#{margin_left}px" 482 | else 483 | "" 484 | 485 | label.css "marginLeft", margin_left 486 | 487 | @update_labels() 488 | 489 | # centers on date 490 | scroll_to_date: (date) -> 491 | @calendar.animate { 492 | scrollLeft: @x_scale date - (@calendar.width() / 2 / @x_ratio()) 493 | }, { 494 | duration: 600 495 | easing: "easeInOutQuad" 496 | progress: => 497 | @update_labels?() 498 | } 499 | 500 | # pixels per ms 501 | x_ratio: -> 502 | @scroller.width() / (@end_date() - @start_date()) 503 | 504 | # date to x coordiante 505 | x_scale: (date) -> 506 | Math.floor (date - +@start_date()) * @x_ratio() 507 | 508 | x_scale_truncated: (date) -> 509 | Math.min @scroller.width(), Math.max 0, @x_scale(date) 510 | 511 | jam_color: (jam, dh=0, ds=0, dl=0) -> 512 | unless jam.color 513 | @default_color[0] += 27 514 | jam.color = [@default_color[0], @default_color[1], @default_color[2]] 515 | 516 | [h,s,l] = jam.color 517 | s /= 6 if jam.after_end() 518 | "hsl(#{h + dh}, #{s + ds}%, #{l + dl}%)" 519 | 520 | render_elapsed_time: -> 521 | el = $("""
""") 522 | .css("width", @x_scale(new Date)) 523 | .appendTo @scroller 524 | 525 | render_month_markers: -> 526 | markers = $("
") 527 | .appendTo(@scroller) 528 | 529 | curr = moment(@start_date()) 530 | .date(1).hours(0).minutes(0).seconds(0).milliseconds(0) 531 | 532 | end = +@end_date() 533 | while +curr.toDate() < end 534 | curr_end = curr.clone().add("month", 1) 535 | 536 | left = @x_scale_truncated curr.toDate() 537 | right = @x_scale_truncated curr_end.toDate() 538 | 539 | marker = $(""" 540 |
541 | 542 | #{curr.format("MMMM")} 543 | 544 |
545 | """) 546 | .css({ 547 | left: "#{left}px" 548 | width: "#{right - left}px" 549 | }) 550 | .appendTo(markers) 551 | 552 | curr = curr_end 553 | 554 | render_day_markers: -> 555 | day_length = 1000 * 60 * 60 * 24 556 | 557 | markers = $("
") 558 | .appendTo(@scroller) 559 | 560 | curr = moment @start_date() 561 | 562 | end = +@end_date() 563 | while +curr.toDate() < end 564 | curr_end = curr.clone().add("day", 1) 565 | 566 | left = @x_scale_truncated curr.toDate() 567 | right = @x_scale_truncated curr_end.toDate() 568 | 569 | marker = $(""" 570 |
571 |
#{curr.format "Do"}
572 |
#{curr.format "ddd"}
573 |
574 | """) 575 | .css({ 576 | width: "#{right - left}px" 577 | left: "#{left}px" 578 | }) 579 | .appendTo(markers) 580 | 581 | curr = curr_end 582 | 583 | render_jams: -> 584 | @calendar = @el.find(".calendar") 585 | unless @calendar.length 586 | @calendar = $("
").appendTo(@el) 587 | 588 | @calendar.empty() 589 | 590 | jams = @jams.find_in_range @start_date(), @end_date() 591 | stacked = @stack_jams jams 592 | 593 | total_days = (@end_date() - @start_date()) / (1000 * 60 * 60 * 24) 594 | outer_width = @day_width * total_days 595 | 596 | @scroller = $("
") 597 | .width(outer_width) 598 | .height(40*3 + 6 + stacked.length * (40+3)) 599 | .appendTo(@calendar) 600 | 601 | rows_el = $("
") 602 | .appendTo(@scroller) 603 | 604 | for row in stacked 605 | row_el = $("
") 606 | .appendTo(rows_el) 607 | 608 | for jam in row 609 | left = @x_scale_truncated jam.start_date() 610 | width = @x_scale_truncated(jam.end_date()) - left 611 | 612 | jam_el = jam.render_for_calendar() 613 | .appendTo(row_el) 614 | .css({ 615 | backgroundColor: @jam_color(jam) 616 | textShadow: "1px 1px 1px #{@jam_color(jam, 0, 0, -10)}" 617 | left: "#{left}px" 618 | width: "#{width}px" 619 | }) 620 | 621 | if jam_el.find(".fixed_label").width() > jam_el.width() 622 | jam_el.addClass "small_text" 623 | 624 | sort_by_length: (jams) -> 625 | jams.sort (a,b) -> 626 | b.length() - a.length() 627 | 628 | stack_jams: (jams) -> 629 | rows = [] 630 | @sort_by_length jams 631 | 632 | for jam in jams 633 | placed = false 634 | 635 | for row in rows 636 | collided = false 637 | for other_jam in row 638 | collided = jam.collides_with other_jam.start_date(), other_jam.end_date() 639 | break if collided 640 | 641 | unless collided 642 | row.push jam 643 | placed = true 644 | break 645 | 646 | unless placed 647 | rows.push [jam] 648 | 649 | rows 650 | 651 | _today: -> 652 | moment().hours(0).minutes(0).seconds(0).milliseconds(0) 653 | 654 | start_date: -> 655 | @_today().subtract("month", 1).toDate() 656 | 657 | end_date: -> 658 | @_today().add("month", 2).toDate() 659 | 660 | class J.Header 661 | constructor: (el) -> 662 | @constructor.instance = @ 663 | 664 | @el = $ el 665 | @el.on "click", ".multi_share .top", (e) => 666 | $(e.currentTarget).closest(".multi_share").toggleClass "open" 667 | 668 | @el.on "click", ".multi_share a", (e) => 669 | link = $ e.currentTarget 670 | 671 | w = 600 672 | h = 500 673 | 674 | win = $(window) 675 | win_x = window.screenLeft ? window.screenX 676 | win_y = window.screenTop ? window.screenY 677 | 678 | left = win_x + (win.width() - w) / 2 679 | top = win_y + (win.height() - h) / 2 680 | 681 | popup = window.open(link.attr("href"), 'Share', 'width='+w+',height='+h+',top=' + top + ',left=' + left) 682 | 683 | if popup 684 | popup.focus() if window.focus 685 | e.preventDefault() 686 | 687 | update_share_links: (jam) -> 688 | msg = jam.share_message() 689 | url = jam.data.url 690 | 691 | @el.find(".twitter_share").attr "href", "http://twitter.com/share?" + $.param { 692 | url: url 693 | text: msg 694 | } 695 | 696 | @el.find(".facebook_share").attr "href", "http://www.facebook.com/sharer.php?" + $.param { 697 | s: "100" 698 | "p[title]": jam.name 699 | "p[summary]": msg 700 | "p[url]": url 701 | } 702 | 703 | @el.find(".google_plus_share").attr "href", "https://plusone.google.com/_/+1/confirm?" + $.param { 704 | hl: "en" 705 | url: url 706 | } 707 | 708 | class J.SingleJam 709 | constructor: (el="body") -> 710 | @el = $ el 711 | @jam = new J.Jam @el.find(".jam_box").data("jam") 712 | @el.find(".progress_outer").replaceWith @jam.render_time_data() 713 | J.Header.instance.update_share_links @jam 714 | -------------------------------------------------------------------------------- /moment.min.js: -------------------------------------------------------------------------------- 1 | //! moment.js 2 | //! version : 2.5.1 3 | //! authors : Tim Wood, Iskren Chernev, Moment.js contributors 4 | //! license : MIT 5 | //! momentjs.com 6 | (function(a){function b(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function c(a,b){return function(c){return k(a.call(this,c),b)}}function d(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function e(){}function f(a){w(a),h(this,a)}function g(a){var b=q(a),c=b.year||0,d=b.month||0,e=b.week||0,f=b.day||0,g=b.hour||0,h=b.minute||0,i=b.second||0,j=b.millisecond||0;this._milliseconds=+j+1e3*i+6e4*h+36e5*g,this._days=+f+7*e,this._months=+d+12*c,this._data={},this._bubble()}function h(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function i(a){var b,c={};for(b in a)a.hasOwnProperty(b)&&qb.hasOwnProperty(b)&&(c[b]=a[b]);return c}function j(a){return 0>a?Math.ceil(a):Math.floor(a)}function k(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.lengthd;d++)(c&&a[d]!==b[d]||!c&&s(a[d])!==s(b[d]))&&g++;return g+f}function p(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=Tb[a]||Ub[b]||b}return a}function q(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=p(c),b&&(d[b]=a[c]));return d}function r(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}db[b]=function(e,f){var g,h,i=db.fn._lang[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=db().utc().set(d,a);return i.call(db.fn._lang,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function s(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function t(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function u(a){return v(a)?366:365}function v(a){return a%4===0&&a%100!==0||a%400===0}function w(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[jb]<0||a._a[jb]>11?jb:a._a[kb]<1||a._a[kb]>t(a._a[ib],a._a[jb])?kb:a._a[lb]<0||a._a[lb]>23?lb:a._a[mb]<0||a._a[mb]>59?mb:a._a[nb]<0||a._a[nb]>59?nb:a._a[ob]<0||a._a[ob]>999?ob:-1,a._pf._overflowDayOfYear&&(ib>b||b>kb)&&(b=kb),a._pf.overflow=b)}function x(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function y(a){return a?a.toLowerCase().replace("_","-"):a}function z(a,b){return b._isUTC?db(a).zone(b._offset||0):db(a).local()}function A(a,b){return b.abbr=a,pb[a]||(pb[a]=new e),pb[a].set(b),pb[a]}function B(a){delete pb[a]}function C(a){var b,c,d,e,f=0,g=function(a){if(!pb[a]&&rb)try{require("./lang/"+a)}catch(b){}return pb[a]};if(!a)return db.fn._lang;if(!m(a)){if(c=g(a))return c;a=[a]}for(;f0;){if(c=g(e.slice(0,b).join("-")))return c;if(d&&d.length>=b&&o(e,d,!0)>=b-1)break;b--}f++}return db.fn._lang}function D(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function E(a){var b,c,d=a.match(vb);for(b=0,c=d.length;c>b;b++)d[b]=Yb[d[b]]?Yb[d[b]]:D(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function F(a,b){return a.isValid()?(b=G(b,a.lang()),Vb[b]||(Vb[b]=E(b)),Vb[b](a)):a.lang().invalidDate()}function G(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(wb.lastIndex=0;d>=0&&wb.test(a);)a=a.replace(wb,c),wb.lastIndex=0,d-=1;return a}function H(a,b){var c,d=b._strict;switch(a){case"DDDD":return Ib;case"YYYY":case"GGGG":case"gggg":return d?Jb:zb;case"Y":case"G":case"g":return Lb;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?Kb:Ab;case"S":if(d)return Gb;case"SS":if(d)return Hb;case"SSS":if(d)return Ib;case"DDD":return yb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Cb;case"a":case"A":return C(b._l)._meridiemParse;case"X":return Fb;case"Z":case"ZZ":return Db;case"T":return Eb;case"SSSS":return Bb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?Hb:xb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return xb;default:return c=new RegExp(P(O(a.replace("\\","")),"i"))}}function I(a){a=a||"";var b=a.match(Db)||[],c=b[b.length-1]||[],d=(c+"").match(Qb)||["-",0,0],e=+(60*d[1])+s(d[2]);return"+"===d[0]?-e:e}function J(a,b,c){var d,e=c._a;switch(a){case"M":case"MM":null!=b&&(e[jb]=s(b)-1);break;case"MMM":case"MMMM":d=C(c._l).monthsParse(b),null!=d?e[jb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[kb]=s(b));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=s(b));break;case"YY":e[ib]=s(b)+(s(b)>68?1900:2e3);break;case"YYYY":case"YYYYY":case"YYYYYY":e[ib]=s(b);break;case"a":case"A":c._isPm=C(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[lb]=s(b);break;case"m":case"mm":e[mb]=s(b);break;case"s":case"ss":e[nb]=s(b);break;case"S":case"SS":case"SSS":case"SSSS":e[ob]=s(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=I(b);break;case"w":case"ww":case"W":case"WW":case"d":case"dd":case"ddd":case"dddd":case"e":case"E":a=a.substr(0,1);case"gg":case"gggg":case"GG":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=b)}}function K(a){var b,c,d,e,f,g,h,i,j,k,l=[];if(!a._d){for(d=M(a),a._w&&null==a._a[kb]&&null==a._a[jb]&&(f=function(b){var c=parseInt(b,10);return b?b.length<3?c>68?1900+c:2e3+c:c:null==a._a[ib]?db().weekYear():a._a[ib]},g=a._w,null!=g.GG||null!=g.W||null!=g.E?h=Z(f(g.GG),g.W||1,g.E,4,1):(i=C(a._l),j=null!=g.d?V(g.d,i):null!=g.e?parseInt(g.e,10)+i._week.dow:0,k=parseInt(g.w,10)||1,null!=g.d&&ju(e)&&(a._pf._overflowDayOfYear=!0),c=U(e,0,a._dayOfYear),a._a[jb]=c.getUTCMonth(),a._a[kb]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=l[b]=d[b];for(;7>b;b++)a._a[b]=l[b]=null==a._a[b]?2===b?1:0:a._a[b];l[lb]+=s((a._tzm||0)/60),l[mb]+=s((a._tzm||0)%60),a._d=(a._useUTC?U:T).apply(null,l)}}function L(a){var b;a._d||(b=q(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],K(a))}function M(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function N(a){a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=C(a._l),h=""+a._i,i=h.length,j=0;for(d=G(a._f,g).match(vb)||[],b=0;b0&&a._pf.unusedInput.push(f),h=h.slice(h.indexOf(c)+c.length),j+=c.length),Yb[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),J(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=i-j,h.length>0&&a._pf.unusedInput.push(h),a._isPm&&a._a[lb]<12&&(a._a[lb]+=12),a._isPm===!1&&12===a._a[lb]&&(a._a[lb]=0),K(a),w(a)}function O(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function P(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function Q(a){var c,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,a._d=new Date(0/0),void 0;for(f=0;fg)&&(e=g,d=c));h(a,d||c)}function R(a){var b,c,d=a._i,e=Mb.exec(d);if(e){for(a._pf.iso=!0,b=0,c=Ob.length;c>b;b++)if(Ob[b][1].exec(d)){a._f=Ob[b][0]+(e[6]||" ");break}for(b=0,c=Pb.length;c>b;b++)if(Pb[b][1].exec(d)){a._f+=Pb[b][0];break}d.match(Db)&&(a._f+="Z"),N(a)}else a._d=new Date(d)}function S(b){var c=b._i,d=sb.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?R(b):m(c)?(b._a=c.slice(0),K(b)):n(c)?b._d=new Date(+c):"object"==typeof c?L(b):b._d=new Date(c)}function T(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function U(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function V(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function W(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function X(a,b,c){var d=hb(Math.abs(a)/1e3),e=hb(d/60),f=hb(e/60),g=hb(f/24),h=hb(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",hb(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,W.apply({},i)}function Y(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=db(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function Z(a,b,c,d,e){var f,g,h=U(a,0,1).getUTCDay();return c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:u(a-1)+g}}function $(a){var b=a._i,c=a._f;return null===b?db.invalid({nullInput:!0}):("string"==typeof b&&(a._i=b=C().preparse(b)),db.isMoment(b)?(a=i(b),a._d=new Date(+b._d)):c?m(c)?Q(a):N(a):S(a),new f(a))}function _(a,b){db.fn[a]=db.fn[a+"s"]=function(a){var c=this._isUTC?"UTC":"";return null!=a?(this._d["set"+c+b](a),db.updateOffset(this),this):this._d["get"+c+b]()}}function ab(a){db.duration.fn[a]=function(){return this._data[a]}}function bb(a,b){db.duration.fn["as"+a]=function(){return+this/b}}function cb(a){var b=!1,c=db;"undefined"==typeof ender&&(a?(gb.moment=function(){return!b&&console&&console.warn&&(b=!0,console.warn("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.")),c.apply(null,arguments)},h(gb.moment,c)):gb.moment=db)}for(var db,eb,fb="2.5.1",gb=this,hb=Math.round,ib=0,jb=1,kb=2,lb=3,mb=4,nb=5,ob=6,pb={},qb={_isAMomentObject:null,_i:null,_f:null,_l:null,_strict:null,_isUTC:null,_offset:null,_pf:null,_lang:null},rb="undefined"!=typeof module&&module.exports&&"undefined"!=typeof require,sb=/^\/?Date\((\-?\d+)/i,tb=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,ub=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,vb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,wb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,xb=/\d\d?/,yb=/\d{1,3}/,zb=/\d{1,4}/,Ab=/[+\-]?\d{1,6}/,Bb=/\d+/,Cb=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Db=/Z|[\+\-]\d\d:?\d\d/gi,Eb=/T/i,Fb=/[\+\-]?\d+(\.\d{1,3})?/,Gb=/\d/,Hb=/\d\d/,Ib=/\d{3}/,Jb=/\d{4}/,Kb=/[+-]?\d{6}/,Lb=/[+-]?\d+/,Mb=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Nb="YYYY-MM-DDTHH:mm:ssZ",Ob=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],Pb=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],Qb=/([\+\-]|\d\d)/gi,Rb="Date|Hours|Minutes|Seconds|Milliseconds".split("|"),Sb={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},Tb={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},Ub={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},Vb={},Wb="DDD w W M D d".split(" "),Xb="M D H h m s w W".split(" "),Yb={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return k(this.year()%100,2)},YYYY:function(){return k(this.year(),4)},YYYYY:function(){return k(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+k(Math.abs(a),6)},gg:function(){return k(this.weekYear()%100,2)},gggg:function(){return k(this.weekYear(),4)},ggggg:function(){return k(this.weekYear(),5)},GG:function(){return k(this.isoWeekYear()%100,2)},GGGG:function(){return k(this.isoWeekYear(),4)},GGGGG:function(){return k(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return s(this.milliseconds()/100)},SS:function(){return k(s(this.milliseconds()/10),2)},SSS:function(){return k(this.milliseconds(),3)},SSSS:function(){return k(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+k(s(a/60),2)+":"+k(s(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+k(s(a/60),2)+k(s(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},Zb=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];Wb.length;)eb=Wb.pop(),Yb[eb+"o"]=d(Yb[eb],eb);for(;Xb.length;)eb=Xb.pop(),Yb[eb+eb]=c(Yb[eb],2);for(Yb.DDDD=c(Yb.DDD,3),h(e.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=db.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=db([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return Y(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),db=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=c,g._f=d,g._l=e,g._strict=f,g._isUTC=!1,g._pf=b(),$(g)},db.utc=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=c,g._f=d,g._strict=f,g._pf=b(),$(g).utc()},db.unix=function(a){return db(1e3*a)},db.duration=function(a,b){var c,d,e,f=a,h=null;return db.isDuration(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(h=tb.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:s(h[kb])*c,h:s(h[lb])*c,m:s(h[mb])*c,s:s(h[nb])*c,ms:s(h[ob])*c}):(h=ub.exec(a))&&(c="-"===h[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},f={y:e(h[2]),M:e(h[3]),d:e(h[4]),h:e(h[5]),m:e(h[6]),s:e(h[7]),w:e(h[8])}),d=new g(f),db.isDuration(a)&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},db.version=fb,db.defaultFormat=Nb,db.updateOffset=function(){},db.lang=function(a,b){var c;return a?(b?A(y(a),b):null===b?(B(a),a="en"):pb[a]||C(a),c=db.duration.fn._lang=db.fn._lang=C(a),c._abbr):db.fn._lang._abbr},db.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),C(a)},db.isMoment=function(a){return a instanceof f||null!=a&&a.hasOwnProperty("_isAMomentObject")},db.isDuration=function(a){return a instanceof g},eb=Zb.length-1;eb>=0;--eb)r(Zb[eb]);for(db.normalizeUnits=function(a){return p(a)},db.invalid=function(a){var b=db.utc(0/0);return null!=a?h(b._pf,a):b._pf.userInvalidated=!0,b},db.parseZone=function(a){return db(a).parseZone()},h(db.fn=f.prototype,{clone:function(){return db(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=db(this).utc();return 00:!1},parsingFlags:function(){return h({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=F(this,a||db.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?db.duration(+b,a):db.duration(a,b),l(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?db.duration(+b,a):db.duration(a,b),l(this,c,-1),this},diff:function(a,b,c){var d,e,f=z(a,this),g=6e4*(this.zone()-f.zone());return b=p(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-db(this).startOf("month")-(f-db(f).startOf("month")))/d,e-=6e4*(this.zone()-db(this).startOf("month").zone()-(f.zone()-db(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:j(e)},from:function(a,b){return db.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(db(),a)},calendar:function(){var a=z(db(),this).startOf("day"),b=this.diff(a,"days",!0),c=-6>b?"sameElse":-1>b?"lastWeek":0>b?"lastDay":1>b?"sameDay":2>b?"nextDay":7>b?"nextWeek":"sameElse";return this.format(this.lang().calendar(c,this))},isLeapYear:function(){return v(this.year())},isDST:function(){return this.zone()+db(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+db(a).startOf(b)},isSame:function(a,b){return b=b||"ms",+this.clone().startOf(b)===+z(a,this).startOf(b)},min:function(a){return a=db.apply(null,arguments),this>a?this:a},max:function(a){return a=db.apply(null,arguments),a>this?this:a},zone:function(a){var b=this._offset||0;return null==a?this._isUTC?b:this._d.getTimezoneOffset():("string"==typeof a&&(a=I(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,b!==a&&l(this,db.duration(b-a,"m"),1,!0),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?db(a).zone():0,(this.zone()-a)%60===0},daysInMonth:function(){return t(this.year(),this.month())},dayOfYear:function(a){var b=hb((db(this).startOf("day")-db(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},quarter:function(){return Math.ceil((this.month()+1)/3)},weekYear:function(a){var b=Y(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=Y(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=Y(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this.day()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},get:function(a){return a=p(a),this[a]()},set:function(a,b){return a=p(a),"function"==typeof this[a]&&this[a](b),this},lang:function(b){return b===a?this._lang:(this._lang=C(b),this)}}),eb=0;eb