diff --git a/.bundle/config b/.bundle/config new file mode 100755 index 0000000..6cc775b --- /dev/null +++ b/.bundle/config @@ -0,0 +1,3 @@ +--- +BUNDLE_PATH: "/Users/saggar/.gem/ruby/2.6.0/bin/bundle/." +BUNDLE_DISABLE_SHARED_GEMS: "true" diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..019e77d --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Environment files +environment* + +# Compiled site +_site/ + +# Jekyll metadata +.jekyll-metadata + +# Other files +.DS_Store diff --git a/2025-03-10-shaun-psy.md b/2025-03-10-shaun-psy.md new file mode 100644 index 0000000..037865e --- /dev/null +++ b/2025-03-10-shaun-psy.md @@ -0,0 +1,17 @@ +--- +layout: paper +title: Revealing Changes in Linear and Nonlinear Functional Connectivity After Psilocybin and Escitalopram Treatment in Patients with Depression +image: /images/papers/shaun-psi.png +authors: Quah S.K.L., Glick C., Roseman L., Pasquini L., Carhart-Harris R.L., Saggar M. +year: 2025 +ref: Quah S.K.L., Glick C., Roseman L., Pasquini L., Carhart-Harris R.L., Saggar M. (2025) BioRxiv +journal: "BioRxiv" +doi: 10.1101/2025.03.05.641592 +github: +pdf: /pdfs/papers/shaun-psi.pdf +biorxiv: https://www.biorxiv.org/content/10.1101/2025.03.05.641592v1 +--- + +# Abstract +Major Depressive Disorder (MDD) is typically characterized by altered linear functional connectivity (FC) across large-scale brain networks. Yet, it is unclear whether similar alterations are observed when nonlinear FC is examined. This study investigated how antidepressant treatment (i.e., psilocybin and escitalopram) modulates both linear FC and nonlinear FC in individuals with MDD. Here, we focused specifically on five key canonical brain networks: the Default Mode Network (DMN), Frontoparietal Network (FPN), Salience Network (SAL), Dorsal Attention Network (DAN), and Ventral Attention Network (VAN). Across both treatments, using resting-state fMRI data, we first compared changes in linear and nonlinear FC between responders and non-responders. Responders exhibited increased linear FC within the VAN and greater nonlinear FC within the DMN and VAN than non-responders. We also observed more between-network linear FC for DMN-DAN and nonlinear FC for DMN-VAN in responders than non-responders. Next, we compared treatments and observed that Psilocybin responders showed greater connectivity between FPN-VAN (linear FC), DMN-VAN (nonlinear FC), and SAL-VAN (nonlinear FC) integration than Escitalopram responders, reflecting enhanced coordination and integration between higher-order networks. Conversely, Escitalopram responders exhibited reduced within-network linear FC within the DMN and SAL and between the DMN and VAN, consistent with a dampening of self-referential and salience processing and altered attentional control. These findings highlight potentially distinct mechanisms of action for psilocybin and escitalopram. Incorporating both linear and nonlinear FC analyses provided a novel characterization of these effects, emphasizing the role of these different interactions in antidepressant response. Future studies should investigate the long-term stability of these network changes and their relationship to clinical outcomes. + diff --git a/ExitButton.pde b/ExitButton.pde new file mode 100755 index 0000000..9030dce --- /dev/null +++ b/ExitButton.pde @@ -0,0 +1,63 @@ +class ExitButton { + + int myWidth;// = 15; + int myHeight;// = 15; + PVector myPos;// = new PVector(5,5); + String t;// = ""; + + ExitButton () { + //println("exit button created"); + myWidth = 15; + myHeight = 15; + myPos = new PVector(5,5); + t = ""; + } + + void display() { + + strokeWeight(2); + noStroke(); + if (over()) { + stroke(hue2,satHI,valHI); + } + + fill(hue2,100,40); + rectMode(CORNER); + rect(myPos.x,myPos.y,myWidth,myHeight); + + if (over()) { + if(!ratingShapes) { + stroke(0,0,0); + line(myPos.x+myWidth/2,myPos.y,myPos.x+myWidth,myPos.y+myHeight/2); + line(myPos.x+myWidth,myPos.y+myHeight/2,myPos.x+myWidth/2,myPos.y+myHeight); + line(myPos.x,myPos.y+myHeight/2,myPos.x+myWidth/2,myPos.y+myHeight/2); + line(myPos.x+myWidth/2,myPos.y,myPos.x+myWidth/2,myPos.y+myHeight); + } + else if (ratingShapes) { + stroke(0,0,0); + line(myPos.x,myPos.y,myPos.x+myWidth,myPos.y+myHeight); + line(myPos.x+myWidth,myPos.y,myPos.x,myPos.y+myHeight); + } + fill(hue1,100,100); + if(notGotDemosYet) { + textAlign(LEFT, BOTTOM); + text(t,myPos.x+myWidth,myPos.y+textAscent()+textDescent()); + } else { + textAlign(RIGHT, BOTTOM); + text(t,myPos.x,myPos.y+textAscent()+textDescent()); + } + } + + } + + boolean over() { + + if (mouseX>myPos.x && mouseX<(myPos.x+myWidth) && mouseY>myPos.y && mouseY<(myPos.y+myHeight)) { + return true; + } else { + return false; + } + + } + +} \ No newline at end of file diff --git a/GallerySpace.pde b/GallerySpace.pde new file mode 100755 index 0000000..63e606c --- /dev/null +++ b/GallerySpace.pde @@ -0,0 +1,112 @@ +class GallerySpace { + + PVector myPos;// = new PVector(0,0); + PVector myCentroid;// = new PVector(0,0); + int [] myMinoLayout;// = null; + float mySize; + float tileSize; + String t;// = ""; + boolean selected;// = false; + + + GallerySpace(int x, int y, float gssize, String s) { + myPos = new PVector(0,0); + myCentroid = new PVector(0,0); + myMinoLayout = null; + t = ""; + selected = false; + myPos.x = x; + myPos.y = y; + mySize = gssize; + tileSize = mySize/(minoSize+1); + t = s; + } + + void display() { + + rectMode(CORNER); + fill(0,0,50); + if (selected) { + fill(hue2,100,50); + stroke(hue2,100,100); + strokeWeight(2); + rect(myPos.x,myPos.y,mySize-2,mySize-2); + } else { + stroke(0,0,15); + } + if (over() && !carrying) { + strokeWeight(2); + stroke(15,100,80); +// textAlign(RIGHT, BOTTOM); +// fill(hue1,100,100); +// text(t,width,myPos.y+mySize+textAscent()+textDescent()); +// noFill(); +// fill(0,0,50); + } + strokeWeight(2); + rect(myPos.x,myPos.y,mySize-2,mySize-2); + + strokeWeight(1); + stroke(0,0,15); + if (myMinoLayout != null) drawMyMino(); + + } + + void drawMyMino() { + + fill(hue1,satHI,80); +// int tileSize = mySize/(minoSize); + +// findMyCentroid(); + + rectMode(CENTER); + + pushMatrix(); + translate(myPos.x+mySize/2-myCentroid.x,myPos.y+mySize/2-myCentroid.y); + + for (int j=0; jmyPos.x && mouseX<(myPos.x+mySize) && mouseY>myPos.y && mouseY<(myPos.y+mySize)) { + return true; + } else { + return false; + } + + } + +} \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..19a04fc --- /dev/null +++ b/Gemfile @@ -0,0 +1,14 @@ +source 'https://rubygems.org' + +# jekyll +gem "jekyll", "4.2.0" + +# katex +gem "execjs" + +# octokit +gem 'octokit' +gem 'netrc' + +# Twitter +gem 'jekyll-twitter-plugin' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100755 index 0000000..f04f32c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,87 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + colorator (1.1.0) + concurrent-ruby (1.1.8) + em-websocket (0.5.2) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) + eventmachine (1.2.7) + execjs (2.7.0) + faraday (1.3.0) + faraday-net_http (~> 1.0) + multipart-post (>= 1.2, < 3) + ruby2_keywords + faraday-net_http (1.0.1) + ffi (1.15.0) + forwardable-extended (2.6.0) + http_parser.rb (0.6.0) + i18n (1.8.10) + concurrent-ruby (~> 1.0) + jekyll (4.2.0) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (~> 2.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.4.0) + pathutil (~> 0.9) + rouge (~> 3.0) + safe_yaml (~> 1.0) + terminal-table (~> 2.0) + jekyll-sass-converter (2.1.0) + sassc (> 2.0.1, < 3.0) + jekyll-twitter-plugin (2.1.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.3.1) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.3) + listen (3.5.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.4.0) + multipart-post (2.1.1) + netrc (0.11.0) + octokit (4.20.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (4.0.6) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.5) + rouge (3.26.0) + ruby2_keywords (0.0.4) + safe_yaml (1.0.5) + sassc (2.4.0) + ffi (~> 1.9) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (2.0.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + execjs + jekyll (= 4.2.0) + jekyll-twitter-plugin + netrc + octokit + +BUNDLED WITH + 2.1.4 diff --git a/Gemfile.old b/Gemfile.old new file mode 100755 index 0000000..4bb58e0 --- /dev/null +++ b/Gemfile.old @@ -0,0 +1,16 @@ +source 'https://rubygems.org' + +# jekyll +gem "jekyll", "3.1.1" +gem "redcarpet" + +# compiling less +gem 'therubyracer' +gem 'less' + +# minifying +gem 'jekyll-press' + +# octokit +gem 'octokit' +gem 'netrc' diff --git a/LeapsCentroid.pde b/LeapsCentroid.pde new file mode 100755 index 0000000..b058488 --- /dev/null +++ b/LeapsCentroid.pde @@ -0,0 +1,1020 @@ +float hue1;// = 25; +float hue2;// = 0; +float satHI;// = 95; +float satLO;// = 30; +float valHI;// = 70; +float valMID;// = 50; +float valLO;// = 30; + +int minoSize;// = 10; +Tile [] tiles; + +int appHeight;// = 600; +int gallerySize;// = 1; +int rightPanel;// = appHeight/5;//gallerySize; +int appWidth;// = appHeight;// + rightPanel; + +int [] currentMinoLayout; +int sessionID;// = (int) random(0,1000000); +int ratingCount;// = 0; +String sessionString;// = sessionID+"-"+year()+nf(month(),2)+nf(day(),2)+"-"+nf(hour(),2)+nf(minute(),2)+nf(second(),2); +float maxSessionTime;// = 25*60*1000; +ExitButton e;// = new ExitButton(); +ExitButton d;// = new ExitButton(); +ExitButton s;// = new ExitButton(); +PFont font; +PFont smallFont; +boolean notStartedYet;// = false; +boolean notGotDemosYet;// = true; +boolean ratingShapes;// = false; +boolean needRatingShapesMessage;// = true; +boolean gallerySelection = false; +TextField tf1; +//TextField tf2; +RadioButton r1; + +ArrayList uMinos;// = new ArrayList(); +ArrayList selectedMinos;// = new ArrayList(); +ArrayList trajectory;// = new ArrayList(); +//IO post;// = new IO(); + +PVector minoCentroid;// = new PVector(0,0); + +boolean carrying;// = false; + +Tile carried;// = null; + +int visitedCount; + +color bg; + +GallerySpace [] gallery;// = new GallerySpace[gallerySize]; +GallerySpace [] ratingGallery; + +void setup() { + +// println("moo"); + hue1 = 25; + hue2 = 0; + satHI = 95; + satLO = 30; + valHI = 90; + valMID = 50; + valLO = 30; + minoSize = 10; + tiles = new Tile[minoSize]; + appHeight = 600; + gallerySize = 1; + rightPanel = appHeight/5;//gallerySize; + appWidth = appHeight;// + rightPanel; + sessionID = (int) random(0,1000000); + ratingCount = 0; + sessionString = sessionID+"-"+year()+nf(month(),2)+nf(day(),2)+"-"+nf(hour(),2)+nf(minute(),2)+nf(second(),2); + maxSessionTime = 25*60*1000; + e = new ExitButton(); + d = new ExitButton(); + s = new ExitButton(); + notStartedYet = false; + notGotDemosYet = true; + ratingShapes = false; + needRatingShapesMessage = true; + uMinos = new ArrayList(); + selectedMinos = new ArrayList(); + trajectory = new ArrayList(); + //post = new IO(); + minoCentroid = new PVector(0,0); + carrying = false; + carried = null; + gallery = new GallerySpace[gallerySize]; + + + + try { + //InetAddress thisIp = InetAddress.getLocalHost(); + //String ipString = ""+thisIp.getHostAddress()+" "+thisIp.isLoopbackAddress(); + //println(ipString); + //trajectory.add(ipString); + } + catch(Exception e) { + e.printStackTrace(); + } + + colorMode(HSB, 100); + + bg = color(hue1,0,valLO); + + size(appWidth,appHeight); + smooth(); + + font = loadFont("ArialUnicodeMS-48.vlw"); + smallFont = loadFont("ArialUnicodeMS-22.vlw"); + + for (int i=0; imaxSessionTime) { + endSession(); + } +} + +void endSession() { + + sendData(); + //draw end screen + noLoop(); + background(0); + fill(0); + rectMode(CORNER); + rect(0,0,width,height); + fill(0,0,100); + textFont(smallFont,22); + textAlign(LEFT); + String message = "Thank you for playing!\n\n\nYour session number is\n"+sessionString+"\n\nTo play again refresh page"; + text(message,50,height/2); + exit(); +} + +void displayTiles() { + + for (int i=0; i 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.right == null && mousePos.dist(r) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.above == null && mousePos.dist(a) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2); + } + if (t.below == null && mousePos.dist(b) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + + popMatrix(); + } +} + +void tileJoiner() { + + float x = mouseX - (width/*-rightPanel*/)/2 + minoCentroid.x; + float y = mouseY - height/2 + minoCentroid.y; + PVector mousePos = new PVector(x,y); + boolean joined = false; + + // Tile closestTile = tiles[0]; + // float minDistance = mousePos.dist(closestTile.myMinoPos); + + Tile closestTile = null; + float minDistance = 999999; + + for (int i = 0; i 0.45*t.mySize) { + t.left = carried; + carried.right = t; + joined = true; + // println("joined at right "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.right == null && carried.myMinoPos.dist(r) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.right = carried; + carried.left = t; + joined = true; + // println("joined at left "+t.ID); + // line(t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.above == null && carried.myMinoPos.dist(a) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.above = carried; + carried.below = t; + joined = true; + // println("joined at bottom "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2); + } + if (t.below == null && carried.myMinoPos.dist(b) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.below = carried; + carried.above = t; + joined = true; + // println("joined at top "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + + + popMatrix(); + } + + if(joined) { + // println(" "); + Tile temp = carried; + carried.carried = false; + carried = null; + carrying = false; + updatePositions(); + temp.spreadActivation(); + temp = null; + // displayTiles(); + isRemovable(); + } +} + +void checkForUniqueMino() { + + boolean unique = false; + + currentMinoLayout = tilesToLayout(); + + for (int i=0; i bottomRightBound.x) { + bottomRightBound.x = tilePos.x; + } + if(tilePos.y > bottomRightBound.y) { + bottomRightBound.y = tilePos.y; + } + } + + float tileSize = (float) tiles[0].mySize; + + int[] layout = new int[minoSize]; + + for (int i = 0; i0) { + notGotDemosYet = false; + trajectory.add("Age\t"+tf1.field); + // trajectory.add("Gender\t"+tf2.field); + if (r1.m) trajectory.add("Gender\t"+"male"); + if (r1.f) trajectory.add("Gender\t"+"female"); + if (!r1.m && !r1.f) notGotDemosYet = true; + } + } + + if (r1.over() && notGotDemosYet) { + r1.setFlag(); + } + + if (tf1.over() && !tf1.focus && notGotDemosYet) { + tf1.focus = !tf1.focus; + // tf2.focus = false; + } + + // if (tf2.over() && !tf2.focus && notGotDemosYet) { + // tf2.focus = !tf2.focus; + // tf1.focus = false; + // } + + if (ratingShapes && !needRatingShapesMessage && gallerySelection) { + for (int i=0; i 4 && !ratingGallery[i].selected) { +// textAlign(CENTER); +// text("Maximum of 5 selections.\nDeselect another shape in order to select this one.",width/2,height/2); +// systemMessage = "Maximum of 5 selections.\nDeselect another shape in order to select this one.",5000,width/2,height/2); +// ratingGallery[i].t = "Maximum of 5 selections.\nDeselect another shape in order to select this one."; + } + } + } + } + + if (s.over() && !notStartedYet && !notGotDemosYet && ratingShapes && gallerySelection) { + recordFinalGalleryTrajectory(); + endSession(); + } + + if (ratingShapes && !needRatingShapesMessage && !gallerySelection) { + loop(); + mousePressed = false; + gallerySelection = true; + } + + if (!notGotDemosYet && !ratingShapes) { + + for (int i=0; imyPos.x && mouseX<(myPos.x+myWidth) && mouseY>myPos.y && mouseY<(myPos.y+myHeight)) { + return true; + } else { + return false; + } + + } + + void setFlag() { + + if (over() && mouseX<=(myPos.x+myWidth/2)) { + m = true; + f = false; + } + if (over() && mouseX>(myPos.x+myWidth/2)) { + m = false; + f = true; + } + + + } + +} \ No newline at end of file diff --git a/TextField.pde b/TextField.pde new file mode 100755 index 0000000..3a1826f --- /dev/null +++ b/TextField.pde @@ -0,0 +1,80 @@ +class TextField { + + PVector pos;// = new PVector(0,0); + PVector dim;// = new PVector(100,20); + String label;// = ""; + String field;// = ""; + PFont font; + + boolean focus;// = false; + + TextField(int x, int y, String l) { + pos = new PVector(0,0); + dim = new PVector(100,20); + field = ""; + focus = false; + + font = loadFont("ArialUnicodeMS-22.vlw"); + textFont(font,22); + dim.y = textAscent() + textDescent() + 6; + dim.x = textWidth("female")+5; + + pos.x = x; + pos.y = y; + label = l; + + } + + void display() { + + fill(50,0,50); + rectMode(CORNER); + strokeWeight(1); + stroke(50,0,150); + if(focus) stroke(25,100,100); + if(over()) stroke(15,100,100); + rect(pos.x,pos.y,dim.x,dim.y); + + textAlign(LEFT, BOTTOM); + fill(hue1,100,100); + text(label,pos.x,pos.y-textDescent()); + textAlign(RIGHT, BOTTOM); + fill(0,0,100); + text(field,pos.x+dim.x,pos.y+dim.y); + + } + + void processKeyPress() { + + if (key == BACKSPACE || key == DELETE) { + if(field.length()> 0){ + field = field.substring(0,field.length()-1); + } + } + + else if(key != RETURN && key != ENTER) { + if (textWidth(""+field+key)pos.x && mouseXpos.y && mouseY 0 ) { + spreadActivation(); + fill(hue1+10,satHI,valHI,75); + // rectMode(CENTER); + rect(myMinoPos.x,myMinoPos.y,mySize-5,mySize-5); + } + + } + + boolean over() { + + float x0 = myMinoPos.x - mySize/2 + (width/*-rightPanel*/)/2 - minoCentroid.x; + float x1 = myMinoPos.x + mySize/2 + (width/*-rightPanel*/)/2 - minoCentroid.x; + float y0 = myMinoPos.y - mySize/2 + height/2 - minoCentroid.y; + float y1 = myMinoPos.y + mySize/2 + height/2 - minoCentroid.y; + + return mouseX > x0 && mouseX < x1 && mouseY > y0 && mouseY < y1; + + } + + void animateSeparability() { + + animationCounter = (animationCounter + 1)%60; + if (animationCounter < 30) { + fill(hue1,satHI,valHI-animationCounter); + // println(100+animationCounter); + } + else { + fill(hue1,satHI,valHI-60+animationCounter); + // println(250-animationCounter); + } + + } + + void spreadActivation() { + + notSpreadYet = false; + activationCounter += 1; + if (activationCounter > 4) { + if(left != null && left.notSpreadYet) { + left.spreadActivation(); + } + if(right != null && right.notSpreadYet) { + right.spreadActivation(); + } + if(above != null && above.notSpreadYet) { + above.spreadActivation(); + } + if(below != null && below.notSpreadYet) { + below.spreadActivation(); + } + activationCounter = 0; + } + + } + +} + + + + diff --git a/__MACOSX/_includes/._base.html.old.html b/__MACOSX/_includes/._base.html.old.html new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/_includes/._base.html.old.html differ diff --git a/__MACOSX/images/._bdl-campus.png b/__MACOSX/images/._bdl-campus.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/._bdl-campus.png differ diff --git a/__MACOSX/images/._bdl-logo-text.png b/__MACOSX/images/._bdl-logo-text.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/._bdl-logo-text.png differ diff --git a/__MACOSX/images/._bdl-logo.png b/__MACOSX/images/._bdl-logo.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/._bdl-logo.png differ diff --git a/__MACOSX/images/._favicon.png b/__MACOSX/images/._favicon.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/._favicon.png differ diff --git a/__MACOSX/images/about/._dept-logo.png b/__MACOSX/images/about/._dept-logo.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/about/._dept-logo.png differ diff --git a/__MACOSX/images/blog/._saggar-tda-mapper-cme-cs.png b/__MACOSX/images/blog/._saggar-tda-mapper-cme-cs.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/blog/._saggar-tda-mapper-cme-cs.png differ diff --git a/__MACOSX/images/blog/._saggar-tda-mapper-cme-perf.png b/__MACOSX/images/blog/._saggar-tda-mapper-cme-perf.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/blog/._saggar-tda-mapper-cme-perf.png differ diff --git a/__MACOSX/images/blog/._saggar-tda-mapper-cme-ts.png b/__MACOSX/images/blog/._saggar-tda-mapper-cme-ts.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/blog/._saggar-tda-mapper-cme-ts.png differ diff --git a/__MACOSX/images/blog/._saggar-tda-mapper-cme.png b/__MACOSX/images/blog/._saggar-tda-mapper-cme.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/blog/._saggar-tda-mapper-cme.png differ diff --git a/__MACOSX/images/collaborators/._Saggar_poster_SOBP_20182.pdf b/__MACOSX/images/collaborators/._Saggar_poster_SOBP_20182.pdf new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/collaborators/._Saggar_poster_SOBP_20182.pdf differ diff --git a/__MACOSX/images/collaborators/._gary.png b/__MACOSX/images/collaborators/._gary.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/collaborators/._gary.png differ diff --git a/__MACOSX/images/collaborators/._peter.png b/__MACOSX/images/collaborators/._peter.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/collaborators/._peter.png differ diff --git a/__MACOSX/images/collaborators/._risto.png b/__MACOSX/images/collaborators/._risto.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/collaborators/._risto.png differ diff --git a/__MACOSX/images/papers/._baker-liu-sex-differences-sci-reports.png b/__MACOSX/images/papers/._baker-liu-sex-differences-sci-reports.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._baker-liu-sex-differences-sci-reports.png differ diff --git a/__MACOSX/images/papers/._bott-quintin-saggar-dkefs.png b/__MACOSX/images/papers/._bott-quintin-saggar-dkefs.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._bott-quintin-saggar-dkefs.png differ diff --git a/__MACOSX/images/papers/._bruno-hosseini-saggar-cerebral-cortex.png b/__MACOSX/images/papers/._bruno-hosseini-saggar-cerebral-cortex.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._bruno-hosseini-saggar-cerebral-cortex.png differ diff --git a/__MACOSX/images/papers/._dyneusr.jpg b/__MACOSX/images/papers/._dyneusr.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._dyneusr.jpg differ diff --git a/__MACOSX/images/papers/._fung-pet.png b/__MACOSX/images/papers/._fung-pet.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._fung-pet.png differ diff --git a/__MACOSX/images/papers/._green-saggar-cerebral-cortex.png b/__MACOSX/images/papers/._green-saggar-cerebral-cortex.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._green-saggar-cerebral-cortex.png differ diff --git a/__MACOSX/images/papers/._green-williams-syndrome.png b/__MACOSX/images/papers/._green-williams-syndrome.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._green-williams-syndrome.png differ diff --git a/__MACOSX/images/papers/._kienitz-quintin-saggar-ttct.png b/__MACOSX/images/papers/._kienitz-quintin-saggar-ttct.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._kienitz-quintin-saggar-ttct.png differ diff --git a/__MACOSX/images/papers/._klabunde-saggar-fxs-math.png b/__MACOSX/images/papers/._klabunde-saggar-fxs-math.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._klabunde-saggar-fxs-math.png differ diff --git a/__MACOSX/images/papers/._klabunde-saggar-pws-hbm.png b/__MACOSX/images/papers/._klabunde-saggar-pws-hbm.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._klabunde-saggar-pws-hbm.png differ diff --git a/__MACOSX/images/papers/._leikauf-adhd-clustering.png b/__MACOSX/images/papers/._leikauf-adhd-clustering.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._leikauf-adhd-clustering.png differ diff --git a/__MACOSX/images/papers/._mengsen-saggar.png b/__MACOSX/images/papers/._mengsen-saggar.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._mengsen-saggar.png differ diff --git a/__MACOSX/images/papers/._saggar-creativity-cerebral-cortex.png b/__MACOSX/images/papers/._saggar-creativity-cerebral-cortex.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-creativity-cerebral-cortex.png differ diff --git a/__MACOSX/images/papers/._saggar-eneuro.png b/__MACOSX/images/papers/._saggar-eneuro.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-eneuro.png differ diff --git a/__MACOSX/images/papers/._saggar-genetic-algorithms-ieee-smc.png b/__MACOSX/images/papers/._saggar-genetic-algorithms-ieee-smc.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-genetic-algorithms-ieee-smc.png differ diff --git a/__MACOSX/images/papers/._saggar-ind-con-ni.png b/__MACOSX/images/papers/._saggar-ind-con-ni.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-ind-con-ni.png differ diff --git a/__MACOSX/images/papers/._saggar-kids-creativity.png b/__MACOSX/images/papers/._saggar-kids-creativity.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-kids-creativity.png differ diff --git a/__MACOSX/images/papers/._saggar-mean-field-meditation-ni.png b/__MACOSX/images/papers/._saggar-mean-field-meditation-ni.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-mean-field-meditation-ni.png differ diff --git a/__MACOSX/images/papers/._saggar-meditation-fhns.png b/__MACOSX/images/papers/._saggar-meditation-fhns.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-meditation-fhns.png differ diff --git a/__MACOSX/images/papers/._saggar-modeling-hh-ijcnn.png b/__MACOSX/images/papers/._saggar-modeling-hh-ijcnn.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-modeling-hh-ijcnn.png differ diff --git a/__MACOSX/images/papers/._saggar-modeling-memory-br.png b/__MACOSX/images/papers/._saggar-modeling-memory-br.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-modeling-memory-br.png differ diff --git a/__MACOSX/images/papers/._saggar-modeling-memory-cogsci.png b/__MACOSX/images/papers/._saggar-modeling-memory-cogsci.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-modeling-memory-cogsci.png differ diff --git a/__MACOSX/images/papers/._saggar-modeling-motivation-cogsci.png b/__MACOSX/images/papers/._saggar-modeling-motivation-cogsci.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-modeling-motivation-cogsci.png differ diff --git a/__MACOSX/images/papers/._saggar-pascal-neuropsych.png b/__MACOSX/images/papers/._saggar-pascal-neuropsych.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-pascal-neuropsych.png differ diff --git a/__MACOSX/images/papers/._saggar-pictionary-sci-reports.png b/__MACOSX/images/papers/._saggar-pictionary-sci-reports.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-pictionary-sci-reports.png differ diff --git a/__MACOSX/images/papers/._saggar-robots-lncs.png b/__MACOSX/images/papers/._saggar-robots-lncs.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-robots-lncs.png differ diff --git a/__MACOSX/images/papers/._saggar-social-fmri-ni.png b/__MACOSX/images/papers/._saggar-social-fmri-ni.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-social-fmri-ni.png differ diff --git a/__MACOSX/images/papers/._saggar-tda-mapper-cme.png b/__MACOSX/images/papers/._saggar-tda-mapper-cme.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-tda-mapper-cme.png differ diff --git a/__MACOSX/images/papers/._saggar-tsalikian-diabetes.png b/__MACOSX/images/papers/._saggar-tsalikian-diabetes.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._saggar-tsalikian-diabetes.png differ diff --git a/__MACOSX/images/papers/._singh-bipolar-disorder.png b/__MACOSX/images/papers/._singh-bipolar-disorder.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._singh-bipolar-disorder.png differ diff --git a/__MACOSX/images/papers/._xie-3phs.png b/__MACOSX/images/papers/._xie-3phs.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/papers/._xie-3phs.png differ diff --git a/__MACOSX/images/team/._caleb.jpg b/__MACOSX/images/team/._caleb.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._caleb.jpg differ diff --git a/__MACOSX/images/team/._kmonlux.png b/__MACOSX/images/team/._kmonlux.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._kmonlux.png differ diff --git a/__MACOSX/images/team/._manish.jpg b/__MACOSX/images/team/._manish.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._manish.jpg differ diff --git a/__MACOSX/images/team/._manish.png b/__MACOSX/images/team/._manish.png new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._manish.png differ diff --git a/__MACOSX/images/team/._mengsen-sq.jpg b/__MACOSX/images/team/._mengsen-sq.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._mengsen-sq.jpg differ diff --git a/__MACOSX/images/team/._missing-photo.jpg b/__MACOSX/images/team/._missing-photo.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._missing-photo.jpg differ diff --git a/__MACOSX/images/team/._oliver.jpg b/__MACOSX/images/team/._oliver.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._oliver.jpg differ diff --git a/__MACOSX/images/team/._raphael.jpg b/__MACOSX/images/team/._raphael.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._raphael.jpg differ diff --git a/__MACOSX/images/team/._samir.jpg b/__MACOSX/images/team/._samir.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._samir.jpg differ diff --git a/__MACOSX/images/team/._tingshan.jpg b/__MACOSX/images/team/._tingshan.jpg new file mode 100755 index 0000000..c3015da Binary files /dev/null and b/__MACOSX/images/team/._tingshan.jpg differ diff --git a/_config.yml b/_config.yml new file mode 100755 index 0000000..55e7c2e --- /dev/null +++ b/_config.yml @@ -0,0 +1,54 @@ +name: Brain Dynamics Lab +description: Capturing and quantifying transitions in brain activity at the single participant level +url: https://braindynamicslab.github.io +baseurl: / + +permalink: /:categories/:title/ +future: true + +highlighter: rouge +markdown: kramdown +kramdown: + input: GFM + auto_ids: true + syntax_highlighter: rouge + +sass: + sass_dir: css + +plugins: ['jekyll-twitter-plugin'] + +exclude: + - "*.branches" + - "*.class" + - "*.cpp" + - "*.csv" + - "*.fasta" + - "*.gz" + - "*.h" + - "*.hh" + - "*.ipynb" + - "*.jar" + - "*.java" + - "*.kml" + - "*.log" + - "*.mcc" + - "*.nb" + - "*.newick" + - "*.nex" + - "*.py" + - "*.R" + - "*.rb" + - "*.Rmd" + - "*.tiff" + - "*.tips" + - "*.trees" + - "*.tsv" + - "*.txt" + - "*.xml" + - "*.zip" + - "Gemfile" + - "Gemfile.lock" + +projects: + diff --git a/_config.yml.old b/_config.yml.old new file mode 100755 index 0000000..c68423a --- /dev/null +++ b/_config.yml.old @@ -0,0 +1,52 @@ +name: Brain Dynamics Lab +description: Capturing and quantifying transitions in brain activity at the single participant level +url: "https://web.stanford.edu/group" +baseurl: "/bdl" + +markdown: redcarpet +permalink: /:categories/:title/ +future: true + +redcarpet: + extensions: + - tables + - no_intra_emphasis + - autolink + - superscript + - strikethrough + +exclude: + - "*.class" + - "*.cpp" + - "*.h" + - "*.hh" + - "*.ipynb" + - "*.jar" + - "*.java" + - "*.nb" + - "*.py" + - "*.R" + - "*.rb" + - "*.Rmd" + - "*.branches" + - "*.csv" + - "*.fasta" + - "*.kml" + - "*.log" + - "*.mcc" + - "*.newick" + - "*.nex" + - "*.tsv" + - "*.tips" + - "*.trees" + - "*.txt" + - "*.zip" + - "*.gz" + - "*.tiff" + - "*.xml" + - "Gemfile" + - "Gemfile.lock" + + +projects: + diff --git a/_data/.gitignore b/_data/.gitignore new file mode 100755 index 0000000..5e7d273 --- /dev/null +++ b/_data/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/_includes/base.html b/_includes/base.html new file mode 100755 index 0000000..a201df7 --- /dev/null +++ b/_includes/base.html @@ -0,0 +1,8 @@ + +{% assign base = '.' %} +{% assign depth = page.url | split: '/' | size | minus: 1 %} +{% if depth < 1 %}{% assign base = '.' %} +{% elsif depth == 1 %}{% assign base = '..' %} +{% elsif depth == 2 %}{% assign base = '../..' %} +{% elsif depth == 3 %}{% assign base = '../../..' %} +{% endif %} diff --git a/_includes/base.html.old.html b/_includes/base.html.old.html new file mode 100755 index 0000000..cdf9b8e --- /dev/null +++ b/_includes/base.html.old.html @@ -0,0 +1,9 @@ + +{% assign base = '' %} +{% assign depth = page.url | split: '/' | size | minus: 1 %} +{% if depth < 1 %}{% assign base = '.' %} +{% elsif depth == 1 %}{% assign base = '..' %} +{% elsif depth == 2 %}{% assign base = '../..' %} +{% elsif depth == 3 %}{% assign base = '../../..' %} +{% endif %} + diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100755 index 0000000..da98259 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,113 @@ + + + + + + {{ page.title }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {{ content }} + +
+ + + + + + diff --git a/_layouts/error.html b/_layouts/error.html new file mode 100755 index 0000000..9f58d76 --- /dev/null +++ b/_layouts/error.html @@ -0,0 +1,23 @@ +--- +layout: default +--- + + +
+
+
+
+
+ {{ page.title }} +
+
+
+ {{ content }} +
+
+
+
+ + + + diff --git a/_layouts/member.html b/_layouts/member.html new file mode 100755 index 0000000..e510a76 --- /dev/null +++ b/_layouts/member.html @@ -0,0 +1,183 @@ +--- +layout: default +--- + +{% assign member = page %} + +
+
+
+ {% if member.image %} + + {% endif %} +
+
+ {{ member.title }} +
+

+

+ {{ member.position }} +
+
+
+
+
+ +
+ +
+
+ {% if member.cv %} +
+ CV +
+ +
+ {% endif %} + {% if member.twitter %} +
+ Twitter +
+ +
+ {% endif %} + {% if member.github %} +
+ GitHub +
+ +
+ {% endif %} + {% if member.scholar %} +
+ Google Scholar +
+ +
+ {% endif %} + {% if member.calendar %} +
+ Calendar +
+ +
+ {% endif %} + {% if member.email %} + {% assign emailarray = member.email | split: '@' %} +
+ Email +
+
+
+ + {{ emailarray.first }}obfuscate@{{ emailarray.last }} +
+
+ {% endif %} +
+
+
+ {{ content }} +
+ + {% assign lastname = member.title | split: ' ' | last %} + {% assign firstinitial = member.title | split: ' ' | first | slice: 0 %} + {% assign searchstring = lastname | append: ' ' | append: firstinitial %} + + {% for paper in site.categories.papers %} + {% if paper.authors contains searchstring %} + {% assign papersq = true %} + {% endif %} + {% endfor %} + + {% if papersq == true %} +
+
Papers
+
+ {% for paper in site.categories.papers %} + {% if paper.authors contains searchstring %} +

{{ paper.title }} ({{paper.year}}). {{ paper.journal}} + {% endif %} + {% endfor %} + {% endif %} + + {% for project in site.categories.projects %} + {% if project.authors contains searchstring %} + {% assign projectsq = true %} + {% endif %} + {% endfor %} + + {% if projectsq == true %} +

+
Projects
+
+ {% for project in site.categories.projects %} + {% if project.authors contains searchstring %} +

{{ project.title }} + {% endif %} + {% endfor %} + {% endif %} + + + {% for post in site.categories.blog %} + {% if post.author %} + {% if member.title == post.author %} + {% assign postsq = true %} + {% endif %} + {% endif %} + {% if post.authors %} + {% for author in post.authors %} + {% if member.title == author %} + {% assign postsq = true %} + {% endif %} + {% endfor %} + {% endif %} + {% endfor %} + + {% if postsq == true %} +

+
Posts
+
+ {% for post in site.categories.blog %} + {% if post.author %} + {% if member.title == post.author %} +

{{ post.title }} + {% endif %} + {% endif %} + {% if post.authors %} + {% assign found = false %} + {% for author in post.authors %} + {% if member.title == author %} + {% assign found = true %} + {% endif %} + {% endfor %} + {% if found %} +

{{ post.title }} + {% endif %} + {% endif %} + {% endfor %} + {% endif %} + +

+
+
diff --git a/_layouts/misc.html b/_layouts/misc.html new file mode 100755 index 0000000..5627cb3 --- /dev/null +++ b/_layouts/misc.html @@ -0,0 +1,28 @@ +--- +layout: default +--- + +
+
+
+ {{ page.title }} +
+
+
+ +
+ +
+
+
+
+
+ {{ content }} +
+
+
+
+ + + + diff --git a/_layouts/paper.html b/_layouts/paper.html new file mode 100755 index 0000000..cc754d0 --- /dev/null +++ b/_layouts/paper.html @@ -0,0 +1,96 @@ +--- +layout: default +--- + + +
+
+
+ {% if page.image %} + + {% endif %} +
+
+ {{ page.title }} +
+

+

+ {{ page.authors }} + {{ page.year }}. + {{ page.journal }} +
+
+
+
+
+ +
+ +
+
+
+
+ {% if page.pdf %} +
+ PDF +
+ +
+ {% endif %} + {% if page.supplement %} +
+ Supplement +
+ +
+ {% endif %} + {% if page.doi %} +
+ DOI +
+
+
+ + {{ page.doi }} +
+
+ {% endif %} + {% if page.github %} +
+ GitHub +
+ +
+ {% endif %} + {% if page.biorxiv %} +
+ BioRxiv +
+ +
+ {% endif %} +
+
+
+
+ {{ content }} +
+
+
+
diff --git a/_layouts/paper.html.old b/_layouts/paper.html.old new file mode 100755 index 0000000..177619b --- /dev/null +++ b/_layouts/paper.html.old @@ -0,0 +1,97 @@ +--- +layout: default +--- +{% include base.html %} +{% assign paper = page %} + +
+
+
+ {% if paper.image %} + + {% endif %} +
+
+ {{ paper.title }} +
+

+

+ {{ paper.authors }} + {{ paper.year }}. + {{ paper.journal }} +
+
+
+
+
+ +
+ +
+
+
+
+ {% if paper.pdf %} +
+ PDF +
+ +
+ {% endif %} + {% if paper.supplement %} +
+ Supplement +
+ +
+ {% endif %} + {% if paper.doi %} +
+ DOI +
+
+
+ + {{ paper.doi }} +
+
+ {% endif %} + {% if paper.github %} +
+ GitHub +
+ +
+ {% endif %} + {% if paper.movie %} +
+ Movie +
+ +
+ {% endif %} +
+
+
+
+ {{ content }} +
+
+
+
diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100755 index 0000000..404eaaa --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,81 @@ +--- +layout: default +--- + +
+
+
+
+
+
+ +

+

+ {{ page.date | date: "%-d %b %Y" }} + {% if page.author %} + by + {{ page.author }} + + {% endif %} + {% if page.authors %} + by + + {{ page.authors.first }} + + and + + {{ page.authors.last }} + + {% endif %} +
+
+
+
+
+
+ +
+ +
+
+
+ {% if page.image %} + {% if page.link %} + + + + {% else %} + + {% endif %} + {% endif %} +
+ {{ content }} +
+
+
+
+ +
+
+ +
diff --git a/_layouts/project.html b/_layouts/project.html new file mode 100755 index 0000000..dadc710 --- /dev/null +++ b/_layouts/project.html @@ -0,0 +1,97 @@ +--- +layout: default +--- + +{% assign project = page %} + +
+
+
+ {% if project.image %} + + {% endif %} +
+
+ {{ project.title }} +
+

+

+ {{ project.authors }} + {{ project.year }}. + {{ project.journal }} +
+
+
+
+
+ +
+ +
+
+
+
+ {% if project.pdf %} +
+ PDF +
+ +
+ {% endif %} + {% if project.supplement %} +
+ Supplement +
+ +
+ {% endif %} + {% if project.doi %} +
+ DOI +
+ +
+ {% endif %} + {% if project.github %} +
+ GitHub +
+ +
+ {% endif %} + {% if project.movie %} +
+ Movie +
+ +
+ {% endif %} +
+
+
+
+ {{ content }} +
+
+
+
diff --git a/_layouts/project.html_old b/_layouts/project.html_old new file mode 100755 index 0000000..d673cb6 --- /dev/null +++ b/_layouts/project.html_old @@ -0,0 +1,124 @@ +--- +layout: default +categories: + - projects +--- + +{% for test in site.data.projects %} + {% if test.title == page.project %} + {% assign project = test %} + {% endif %} +{% endfor %} + +
+
+
+ +
+

+

+ {{ project.description }} +
+
+
+ +
+ +
+
+
+
+ Source code +
+ +
+
+ Contributors +
+
+ {% for contributor in project.contributors %} +
+ + {% endfor %} +
+
+
+ Latest commits +
+
+ +
+
+ + {% for page in site.pages %} + {% if page.project == project.title %} + + {% endif %} + {% endfor %} + + {% if pagecount > 1 %} +
+ Pages +
+
+ +
+
+ {% endif %} + +
+
+
+

+ {{ content }} +

+
+
+
diff --git a/_layouts/talk.html b/_layouts/talk.html new file mode 100755 index 0000000..5c6f00f --- /dev/null +++ b/_layouts/talk.html @@ -0,0 +1,57 @@ + + + + + + + {{ page.title }} + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + +
+ + {{ content }} + +
+ +
+ + + + + + + + + + + + diff --git a/_layouts/talk_reveal3.html b/_layouts/talk_reveal3.html new file mode 100755 index 0000000..59ac22d --- /dev/null +++ b/_layouts/talk_reveal3.html @@ -0,0 +1,52 @@ + + + + + + + {{ page.title }} + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + +
+ + {{ content }} + +
+ +
+ + + + + + + diff --git a/_layouts/talk_reveal3_controls.html b/_layouts/talk_reveal3_controls.html new file mode 100755 index 0000000..536a617 --- /dev/null +++ b/_layouts/talk_reveal3_controls.html @@ -0,0 +1,56 @@ + + + + + + + {{ page.title }} + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + +
+ + {{ content }} + +
+ +
+ + + + + + + + + diff --git a/_plugins/breadcrumb-array-filter.rb b/_plugins/breadcrumb-array-filter.rb new file mode 100755 index 0000000..ef7270b --- /dev/null +++ b/_plugins/breadcrumb-array-filter.rb @@ -0,0 +1,23 @@ +# construct breadcrumb array from page path +# Examples +# stem/data/ -> [ stem/, stem/data/ ] +# dynamics-practical/02-prepare-a-skyline-analysis -> [ dynamics-practical/, dynamics-practical/02-prepare-a-skyline-analysis ] + +module Jekyll + module BreadcrumbArray + def breadcrumb_array(input) + parts = input.split(/\//) + paths = Array.new + for i in (0...parts.size) do + path = parts[0..i].join('/') + if i < parts.size - 1 || input.end_with?('/') + path += '/' + end + paths = paths.push(path) + end + paths + end + end +end + +Liquid::Template.register_filter(Jekyll::BreadcrumbArray) \ No newline at end of file diff --git a/_plugins/eq.rb b/_plugins/eq.rb new file mode 100755 index 0000000..a941d63 --- /dev/null +++ b/_plugins/eq.rb @@ -0,0 +1,34 @@ +# Author: Trevor Bedford +# License: MIT + +module Jekyll + class Eq < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + @markup = "#{markup}".strip + end + def render(context) + + require 'execjs' + + parsed = Liquid::Template.parse(@markup).render context + + katexsrc = open("./js/katex.min.js").read + @katex = ExecJS.compile(katexsrc) + + style = "text-align: center; margin-top: 0.5em; margin-bottom: 0.5em;" + div_open = "
" + parsed = "\\displaystyle " + parsed + div_close = "
" + output = div_open + eqn_to_html(parsed) + div_close + + return output + + end + def eqn_to_html(string) + return @katex.call("katex.renderToString", string, { displayMode: true }) + end + end +end + +Liquid::Template.register_tag('eq', Jekyll::Eq) diff --git a/_plugins/eqinline.rb b/_plugins/eqinline.rb new file mode 100755 index 0000000..098f974 --- /dev/null +++ b/_plugins/eqinline.rb @@ -0,0 +1,27 @@ +# Author: Trevor Bedford +# License: MIT + +module Jekyll + class EqInline < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + @markup = "#{markup}".strip + end + def render(context) + + require 'execjs' + + parsed = Liquid::Template.parse(@markup).render context + + katexsrc = open("./js/katex.min.js").read + @katex = ExecJS.compile(katexsrc) + return eqn_to_html(parsed) + + end + def eqn_to_html(string) + return @katex.call("katex.renderToString", string) + end + end +end + +Liquid::Template.register_tag('eqinline', Jekyll::EqInline) diff --git a/_plugins/jekyll-press-plugin.rb b/_plugins/jekyll-press-plugin.rb new file mode 100755 index 0000000..a20757b --- /dev/null +++ b/_plugins/jekyll-press-plugin.rb @@ -0,0 +1,2 @@ +# _plugins/jekyll-press-plugin.rb +require 'jekyll-press' diff --git a/_plugins/less-converter.rb b/_plugins/less-converter.rb new file mode 100755 index 0000000..98c12ac --- /dev/null +++ b/_plugins/less-converter.rb @@ -0,0 +1,37 @@ +# less converter via https://gist.github.com/KBalderson/5689220 + +module Jekyll + class LessConverter < Converter + safe true + priority :high + + def setup + return if @setup + require 'less' + @setup = true + rescue LoadError + STDERR.puts 'You are missing the library required for less. Please run:' + STDERR.puts ' $ [sudo] gem install less' + raise FatalException.new("Missing dependency: less and/or therubyracer") + end + + def matches(ext) + ext =~ /less|lcss/i + end + + def output_ext(ext) + ".css" + end + + def convert(content) + setup + begin + parser = Less::Parser.new + parser = parser.parse(content).to_css + rescue => e + puts "Less Exception: #{e.message}" + end + end + + end +end \ No newline at end of file diff --git a/_plugins/trackback.rb b/_plugins/trackback.rb new file mode 100755 index 0000000..5dc3f1b --- /dev/null +++ b/_plugins/trackback.rb @@ -0,0 +1,43 @@ +# Author: Trevor Bedford +# License: MIT + +# Examples: +# {% trackback url %} +# {% trackback {{page.url}} %} + +require 'json' +require 'open-uri' + +module Jekyll + class Trackback < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + @markup = "#{markup}".strip + end + def render(context) + + url = Liquid::Template.parse(@markup).render context + if url =~ /^\// + url = "http://bdl.stanford.edu" + url + end + json_object = JSON.parse(open("http://urls.api.twitter.com/1/urls/count.json?url=#{url}").read) + count = json_object["count"] + topsy_url = url.gsub(/:/, '%3A').gsub(/\//, '%2F') + + html = "" + if count > 0 + html += "" + html += " " + html += "" + html += "#{count}" + html += "" + html += "" + end + + html + + end + end +end + +Liquid::Template.register_tag('trackback', Jekyll::Trackback) \ No newline at end of file diff --git a/_plugins/tweet.rb b/_plugins/tweet.rb new file mode 100755 index 0000000..94bfc5d --- /dev/null +++ b/_plugins/tweet.rb @@ -0,0 +1,36 @@ +# Author: Trevor Bedford +# License: MIT + +# Examples: +# {% tweet url description %} +# {% tweet {{page.url}} {{page.title}} %} + + +module Jekyll + class Tweet < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + @markup = "#{markup}".strip + end + def render(context) + + parsed = Liquid::Template.parse(@markup).render context + url = parsed.split(/ /).first + if url =~ /^\// + url = "http://bdl.stanford.edu" + url + end + text = parsed.split(/ /).drop(1).join(' ') + html = "" + url.gsub!(/ /, '%20') + text.gsub!(/ /, '%20') + html += " " + html += "" + html += "tweet" + html += "" + html + + end + end +end + +Liquid::Template.register_tag('tweet', Jekyll::Tweet) \ No newline at end of file diff --git a/_scripts/generate-project-data.rb b/_scripts/generate-project-data.rb new file mode 100755 index 0000000..b2376cb --- /dev/null +++ b/_scripts/generate-project-data.rb @@ -0,0 +1,123 @@ +# Preprocessing script +# Run before `jekyll build` to go through _config.yml and use octokit to fill out metadata +# +# Example: +# - repo: trvrb/coaltrace +# - owner: trvrb +# - title: coaltrace +# - description: Simulating genealogies using charged particles +# - url: /projects/coaltrace/ +# - date: 2013-10-19 04:12:17 UTC +# - contributors: +# - login: trvrb +# - avatar: https://2.gravatar.com/avatar/ab7fe2db559c7924316c4391ba00b3f0 +# - url: https://github.com/trvrb +# - commits: +# - date: 2013-10-19T04:12:06Z +# - message: Update readme. +# - url: https://github.com/trvrb/coaltrace/commit/ebb95806f989d8fd6ecbf6aa8308647298dd21ad + +require 'octokit' +require 'yaml' + +module Projects + + def self.generate_data(config_file) + + project_data = {} + + config = YAML.load_file(config_file) + projects_array = config["projects"] + + puts "Generating projects" + # create octokit client + client = Octokit::Client.new(:netrc => true, :access_token => ENV['GITHUB_TOKEN']) + + project_data = Array.new + if projects_array.length > 0 + projects_array.each do |repo| + + puts "\tGenerating #{repo}" + + # load repo metadata + octokit_repo = client.repository(repo) + project_title = octokit_repo.name + project_owner = octokit_repo.owner.login + project_description = octokit_repo.description + project_url = "/projects/#{project_title}/" + project_date = octokit_repo.updated_at + + # load contributor metadata + octokit_contributors = client.contributors(repo) + project_contributors = Array.new + for i in 0 ... [octokit_contributors.size, 5].min + contributor = octokit_contributors[i] + contributor_login = contributor.login + contributor_avatar = contributor.rels[:avatar].href + "&s=50" + contributor_url = contributor.rels[:html].href + project_contributors = project_contributors.push( + "login" => contributor_login, + "avatar" => contributor_avatar, + "url" => contributor_url + ) + end + + # load commit metadata + octokit_commits = client.commits(repo) + project_commits = Array.new + counter = 0 + for i in 0 ... octokit_commits.size + commit = octokit_commits[i] + commit_date = commit.commit.author.date + commit_message = commit.commit.message + commit_url = commit.rels[:html].href + if commit.author != nil then + commit_author_login = commit.author.login + commit_author_url = commit.author.rels[:html].href + project_commits = project_commits.push( + "date" => commit_date, + "message" => commit_message, + "url" => commit_url, + "author_login" => commit_author_login, + "author_url" => commit_author_url + ) + counter += 1 + if counter == 5 then + break + end + end + + end + + # assemble metadata + project_data = project_data.push( + "repo" => repo, + "title" => project_title, + "owner" => project_owner, + "description" => project_description, + "url" => project_url, + "contributors" => project_contributors, + "commits" => project_commits + ) + + # sort by date + project_data.sort! { |x, y| y["commits"].first["date"] <=> x["commits"].first["date"] } + + end + end + + return project_data + + end + + def self.write_data(project_data, data_file) + + puts "Writing project data" + File.write(data_file, project_data.to_yaml) + + end + +end + +project_data = Projects.generate_data("_config.yml") +Projects.write_data(project_data, "_data/projects.yml") diff --git a/_scripts/preprocess-markdown.rb b/_scripts/preprocess-markdown.rb new file mode 100755 index 0000000..1b5bd4e --- /dev/null +++ b/_scripts/preprocess-markdown.rb @@ -0,0 +1,74 @@ +# Preprocessing script +# Run before `jekyll build` to walk through directories and add YAML front matter to Markdown files +# and to rename readme.md files to index.md + +# collect mapping of project name to repo via _config.yml +name_to_repo = Hash.new +require 'yaml' +$basedir = Dir.pwd +config = YAML.load_file("_config.yml") +config["projects"].each do |repo| + name = repo.split('/').drop(1).join('') + name_to_repo[name] = repo +end + +# collect all markdown files +mdarray = Dir.glob("projects/**/*.md") + +# go through each markdown file +mdarray.each { |md| + + basename = File.basename(md) + full_directory = File.dirname(md) + "/" + + # if readme.md, rename to index.md + # if index.html already exists, remove + if basename =~ /readme/i + if File.exists?(full_directory + "index.html") + File.delete(full_directory + "index.html") + end + indexmd = full_directory + "index.md" + File.rename(md, indexmd) + md = indexmd + end + + # get project name if possible + project_name = nil + dirarray = full_directory.split('/') + temp_name = dirarray[dirarray.index("projects") + 1] + if temp_name =~ /^[^_]/ + project_name = temp_name + end + + repo = name_to_repo[project_name] + within_project_directory = full_directory[/projects\/#{project_name}\/(.*)/, 1] + + # if file is lacking YAML front matter, add some + contents = File.open(md, "r").read + out = File.new(md, "w") + if contents !~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m + out.puts "---" + out.puts "layout: project" + if project_name != nil + title = md.sub(/^.*projects\//, '').sub(/.md$/, '').sub(/index$/, '') + out.puts "title: #{title}" + out.puts "project: #{project_name}" + out.puts "repo: #{repo}" + out.puts "permalink: /:path/:basename:output_ext" + end + out.puts "---" + out.puts + end + + # go through file and replace all links that point to .md files with the equivalent .html file + contents.gsub!(/\((\S+)\.md\)/, "(\\1.html)") + + # go through file and replace all links that point to source code files with equivalent GitHub links + filetypes = ['class', 'cpp', 'h', 'hh', 'ipynb', 'jar', 'java', 'nb', 'py', 'R', 'rb', 'Rmd', 'branches', 'csv', 'fasta', 'json', 'kml', 'log', 'mcc', 'newick', 'nex', 'tsv', 'tips', 'trees', 'txt', 'xml'] + filetypes.each {|filetype| + contents.gsub!(/\((\S+)\.#{filetype}\)/, "(https://github.com/#{repo}/tree/master/#{within_project_directory}\\1.#{filetype})") + } + + out.puts contents + +} diff --git a/_scripts/update-and-preprocess.rb b/_scripts/update-and-preprocess.rb new file mode 100755 index 0000000..991e2df --- /dev/null +++ b/_scripts/update-and-preprocess.rb @@ -0,0 +1,22 @@ +# go through projects and clean and update + +require 'yaml' + +$basedir = Dir.pwd +config = YAML.load_file("_config.yml") + +config["projects"].each do |repo| + name = repo.split('/').drop(1).join('') + Dir.chdir($basedir + "/projects") + if !Dir.exists?(name) # clone project repo + `git clone https://github.com/#{repo}.git` + end + Dir.chdir($basedir + "/projects/" + name) # drop into blotter dir + `git clean -f` # remove untracked files, but keep directories + `git reset --hard HEAD` # bring back to head state + `git pull origin master` # git pull +end + +Dir.chdir($basedir) +`ruby _scripts/preprocess-markdown.rb` +`ruby _scripts/generate-project-data.rb` diff --git a/_site/ExitButton.pde b/_site/ExitButton.pde new file mode 100755 index 0000000..9030dce --- /dev/null +++ b/_site/ExitButton.pde @@ -0,0 +1,63 @@ +class ExitButton { + + int myWidth;// = 15; + int myHeight;// = 15; + PVector myPos;// = new PVector(5,5); + String t;// = ""; + + ExitButton () { + //println("exit button created"); + myWidth = 15; + myHeight = 15; + myPos = new PVector(5,5); + t = ""; + } + + void display() { + + strokeWeight(2); + noStroke(); + if (over()) { + stroke(hue2,satHI,valHI); + } + + fill(hue2,100,40); + rectMode(CORNER); + rect(myPos.x,myPos.y,myWidth,myHeight); + + if (over()) { + if(!ratingShapes) { + stroke(0,0,0); + line(myPos.x+myWidth/2,myPos.y,myPos.x+myWidth,myPos.y+myHeight/2); + line(myPos.x+myWidth,myPos.y+myHeight/2,myPos.x+myWidth/2,myPos.y+myHeight); + line(myPos.x,myPos.y+myHeight/2,myPos.x+myWidth/2,myPos.y+myHeight/2); + line(myPos.x+myWidth/2,myPos.y,myPos.x+myWidth/2,myPos.y+myHeight); + } + else if (ratingShapes) { + stroke(0,0,0); + line(myPos.x,myPos.y,myPos.x+myWidth,myPos.y+myHeight); + line(myPos.x+myWidth,myPos.y,myPos.x,myPos.y+myHeight); + } + fill(hue1,100,100); + if(notGotDemosYet) { + textAlign(LEFT, BOTTOM); + text(t,myPos.x+myWidth,myPos.y+textAscent()+textDescent()); + } else { + textAlign(RIGHT, BOTTOM); + text(t,myPos.x,myPos.y+textAscent()+textDescent()); + } + } + + } + + boolean over() { + + if (mouseX>myPos.x && mouseX<(myPos.x+myWidth) && mouseY>myPos.y && mouseY<(myPos.y+myHeight)) { + return true; + } else { + return false; + } + + } + +} \ No newline at end of file diff --git a/_site/GallerySpace.pde b/_site/GallerySpace.pde new file mode 100755 index 0000000..63e606c --- /dev/null +++ b/_site/GallerySpace.pde @@ -0,0 +1,112 @@ +class GallerySpace { + + PVector myPos;// = new PVector(0,0); + PVector myCentroid;// = new PVector(0,0); + int [] myMinoLayout;// = null; + float mySize; + float tileSize; + String t;// = ""; + boolean selected;// = false; + + + GallerySpace(int x, int y, float gssize, String s) { + myPos = new PVector(0,0); + myCentroid = new PVector(0,0); + myMinoLayout = null; + t = ""; + selected = false; + myPos.x = x; + myPos.y = y; + mySize = gssize; + tileSize = mySize/(minoSize+1); + t = s; + } + + void display() { + + rectMode(CORNER); + fill(0,0,50); + if (selected) { + fill(hue2,100,50); + stroke(hue2,100,100); + strokeWeight(2); + rect(myPos.x,myPos.y,mySize-2,mySize-2); + } else { + stroke(0,0,15); + } + if (over() && !carrying) { + strokeWeight(2); + stroke(15,100,80); +// textAlign(RIGHT, BOTTOM); +// fill(hue1,100,100); +// text(t,width,myPos.y+mySize+textAscent()+textDescent()); +// noFill(); +// fill(0,0,50); + } + strokeWeight(2); + rect(myPos.x,myPos.y,mySize-2,mySize-2); + + strokeWeight(1); + stroke(0,0,15); + if (myMinoLayout != null) drawMyMino(); + + } + + void drawMyMino() { + + fill(hue1,satHI,80); +// int tileSize = mySize/(minoSize); + +// findMyCentroid(); + + rectMode(CENTER); + + pushMatrix(); + translate(myPos.x+mySize/2-myCentroid.x,myPos.y+mySize/2-myCentroid.y); + + for (int j=0; jmyPos.x && mouseX<(myPos.x+mySize) && mouseY>myPos.y && mouseY<(myPos.y+mySize)) { + return true; + } else { + return false; + } + + } + +} \ No newline at end of file diff --git a/_site/LeapsCentroid.pde b/_site/LeapsCentroid.pde new file mode 100755 index 0000000..b058488 --- /dev/null +++ b/_site/LeapsCentroid.pde @@ -0,0 +1,1020 @@ +float hue1;// = 25; +float hue2;// = 0; +float satHI;// = 95; +float satLO;// = 30; +float valHI;// = 70; +float valMID;// = 50; +float valLO;// = 30; + +int minoSize;// = 10; +Tile [] tiles; + +int appHeight;// = 600; +int gallerySize;// = 1; +int rightPanel;// = appHeight/5;//gallerySize; +int appWidth;// = appHeight;// + rightPanel; + +int [] currentMinoLayout; +int sessionID;// = (int) random(0,1000000); +int ratingCount;// = 0; +String sessionString;// = sessionID+"-"+year()+nf(month(),2)+nf(day(),2)+"-"+nf(hour(),2)+nf(minute(),2)+nf(second(),2); +float maxSessionTime;// = 25*60*1000; +ExitButton e;// = new ExitButton(); +ExitButton d;// = new ExitButton(); +ExitButton s;// = new ExitButton(); +PFont font; +PFont smallFont; +boolean notStartedYet;// = false; +boolean notGotDemosYet;// = true; +boolean ratingShapes;// = false; +boolean needRatingShapesMessage;// = true; +boolean gallerySelection = false; +TextField tf1; +//TextField tf2; +RadioButton r1; + +ArrayList uMinos;// = new ArrayList(); +ArrayList selectedMinos;// = new ArrayList(); +ArrayList trajectory;// = new ArrayList(); +//IO post;// = new IO(); + +PVector minoCentroid;// = new PVector(0,0); + +boolean carrying;// = false; + +Tile carried;// = null; + +int visitedCount; + +color bg; + +GallerySpace [] gallery;// = new GallerySpace[gallerySize]; +GallerySpace [] ratingGallery; + +void setup() { + +// println("moo"); + hue1 = 25; + hue2 = 0; + satHI = 95; + satLO = 30; + valHI = 90; + valMID = 50; + valLO = 30; + minoSize = 10; + tiles = new Tile[minoSize]; + appHeight = 600; + gallerySize = 1; + rightPanel = appHeight/5;//gallerySize; + appWidth = appHeight;// + rightPanel; + sessionID = (int) random(0,1000000); + ratingCount = 0; + sessionString = sessionID+"-"+year()+nf(month(),2)+nf(day(),2)+"-"+nf(hour(),2)+nf(minute(),2)+nf(second(),2); + maxSessionTime = 25*60*1000; + e = new ExitButton(); + d = new ExitButton(); + s = new ExitButton(); + notStartedYet = false; + notGotDemosYet = true; + ratingShapes = false; + needRatingShapesMessage = true; + uMinos = new ArrayList(); + selectedMinos = new ArrayList(); + trajectory = new ArrayList(); + //post = new IO(); + minoCentroid = new PVector(0,0); + carrying = false; + carried = null; + gallery = new GallerySpace[gallerySize]; + + + + try { + //InetAddress thisIp = InetAddress.getLocalHost(); + //String ipString = ""+thisIp.getHostAddress()+" "+thisIp.isLoopbackAddress(); + //println(ipString); + //trajectory.add(ipString); + } + catch(Exception e) { + e.printStackTrace(); + } + + colorMode(HSB, 100); + + bg = color(hue1,0,valLO); + + size(appWidth,appHeight); + smooth(); + + font = loadFont("ArialUnicodeMS-48.vlw"); + smallFont = loadFont("ArialUnicodeMS-22.vlw"); + + for (int i=0; imaxSessionTime) { + endSession(); + } +} + +void endSession() { + + sendData(); + //draw end screen + noLoop(); + background(0); + fill(0); + rectMode(CORNER); + rect(0,0,width,height); + fill(0,0,100); + textFont(smallFont,22); + textAlign(LEFT); + String message = "Thank you for playing!\n\n\nYour session number is\n"+sessionString+"\n\nTo play again refresh page"; + text(message,50,height/2); + exit(); +} + +void displayTiles() { + + for (int i=0; i 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.right == null && mousePos.dist(r) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.above == null && mousePos.dist(a) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2); + } + if (t.below == null && mousePos.dist(b) < t.mySize/1.5 && mousePos.dist(t.myMinoPos) > 0.45*t.mySize) { + line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + + popMatrix(); + } +} + +void tileJoiner() { + + float x = mouseX - (width/*-rightPanel*/)/2 + minoCentroid.x; + float y = mouseY - height/2 + minoCentroid.y; + PVector mousePos = new PVector(x,y); + boolean joined = false; + + // Tile closestTile = tiles[0]; + // float minDistance = mousePos.dist(closestTile.myMinoPos); + + Tile closestTile = null; + float minDistance = 999999; + + for (int i = 0; i 0.45*t.mySize) { + t.left = carried; + carried.right = t; + joined = true; + // println("joined at right "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.right == null && carried.myMinoPos.dist(r) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.right = carried; + carried.left = t; + joined = true; + // println("joined at left "+t.ID); + // line(t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + if (t.above == null && carried.myMinoPos.dist(a) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.above = carried; + carried.below = t; + joined = true; + // println("joined at bottom "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y-t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y-t.mySize/2); + } + if (t.below == null && carried.myMinoPos.dist(b) < t.mySize/1.5 && carried.myMinoPos.dist(t.myMinoPos) > 0.45*t.mySize) { + t.below = carried; + carried.above = t; + joined = true; + // println("joined at top "+t.ID); + // line(t.myMinoPos.x-t.mySize/2,t.myMinoPos.y+t.mySize/2,t.myMinoPos.x+t.mySize/2,t.myMinoPos.y+t.mySize/2); + } + + + popMatrix(); + } + + if(joined) { + // println(" "); + Tile temp = carried; + carried.carried = false; + carried = null; + carrying = false; + updatePositions(); + temp.spreadActivation(); + temp = null; + // displayTiles(); + isRemovable(); + } +} + +void checkForUniqueMino() { + + boolean unique = false; + + currentMinoLayout = tilesToLayout(); + + for (int i=0; i bottomRightBound.x) { + bottomRightBound.x = tilePos.x; + } + if(tilePos.y > bottomRightBound.y) { + bottomRightBound.y = tilePos.y; + } + } + + float tileSize = (float) tiles[0].mySize; + + int[] layout = new int[minoSize]; + + for (int i = 0; i0) { + notGotDemosYet = false; + trajectory.add("Age\t"+tf1.field); + // trajectory.add("Gender\t"+tf2.field); + if (r1.m) trajectory.add("Gender\t"+"male"); + if (r1.f) trajectory.add("Gender\t"+"female"); + if (!r1.m && !r1.f) notGotDemosYet = true; + } + } + + if (r1.over() && notGotDemosYet) { + r1.setFlag(); + } + + if (tf1.over() && !tf1.focus && notGotDemosYet) { + tf1.focus = !tf1.focus; + // tf2.focus = false; + } + + // if (tf2.over() && !tf2.focus && notGotDemosYet) { + // tf2.focus = !tf2.focus; + // tf1.focus = false; + // } + + if (ratingShapes && !needRatingShapesMessage && gallerySelection) { + for (int i=0; i 4 && !ratingGallery[i].selected) { +// textAlign(CENTER); +// text("Maximum of 5 selections.\nDeselect another shape in order to select this one.",width/2,height/2); +// systemMessage = "Maximum of 5 selections.\nDeselect another shape in order to select this one.",5000,width/2,height/2); +// ratingGallery[i].t = "Maximum of 5 selections.\nDeselect another shape in order to select this one."; + } + } + } + } + + if (s.over() && !notStartedYet && !notGotDemosYet && ratingShapes && gallerySelection) { + recordFinalGalleryTrajectory(); + endSession(); + } + + if (ratingShapes && !needRatingShapesMessage && !gallerySelection) { + loop(); + mousePressed = false; + gallerySelection = true; + } + + if (!notGotDemosYet && !ratingShapes) { + + for (int i=0; imyPos.x && mouseX<(myPos.x+myWidth) && mouseY>myPos.y && mouseY<(myPos.y+myHeight)) { + return true; + } else { + return false; + } + + } + + void setFlag() { + + if (over() && mouseX<=(myPos.x+myWidth/2)) { + m = true; + f = false; + } + if (over() && mouseX>(myPos.x+myWidth/2)) { + m = false; + f = true; + } + + + } + +} \ No newline at end of file diff --git a/_site/TextField.pde b/_site/TextField.pde new file mode 100755 index 0000000..3a1826f --- /dev/null +++ b/_site/TextField.pde @@ -0,0 +1,80 @@ +class TextField { + + PVector pos;// = new PVector(0,0); + PVector dim;// = new PVector(100,20); + String label;// = ""; + String field;// = ""; + PFont font; + + boolean focus;// = false; + + TextField(int x, int y, String l) { + pos = new PVector(0,0); + dim = new PVector(100,20); + field = ""; + focus = false; + + font = loadFont("ArialUnicodeMS-22.vlw"); + textFont(font,22); + dim.y = textAscent() + textDescent() + 6; + dim.x = textWidth("female")+5; + + pos.x = x; + pos.y = y; + label = l; + + } + + void display() { + + fill(50,0,50); + rectMode(CORNER); + strokeWeight(1); + stroke(50,0,150); + if(focus) stroke(25,100,100); + if(over()) stroke(15,100,100); + rect(pos.x,pos.y,dim.x,dim.y); + + textAlign(LEFT, BOTTOM); + fill(hue1,100,100); + text(label,pos.x,pos.y-textDescent()); + textAlign(RIGHT, BOTTOM); + fill(0,0,100); + text(field,pos.x+dim.x,pos.y+dim.y); + + } + + void processKeyPress() { + + if (key == BACKSPACE || key == DELETE) { + if(field.length()> 0){ + field = field.substring(0,field.length()-1); + } + } + + else if(key != RETURN && key != ENTER) { + if (textWidth(""+field+key)pos.x && mouseXpos.y && mouseY 0 ) { + spreadActivation(); + fill(hue1+10,satHI,valHI,75); + // rectMode(CENTER); + rect(myMinoPos.x,myMinoPos.y,mySize-5,mySize-5); + } + + } + + boolean over() { + + float x0 = myMinoPos.x - mySize/2 + (width/*-rightPanel*/)/2 - minoCentroid.x; + float x1 = myMinoPos.x + mySize/2 + (width/*-rightPanel*/)/2 - minoCentroid.x; + float y0 = myMinoPos.y - mySize/2 + height/2 - minoCentroid.y; + float y1 = myMinoPos.y + mySize/2 + height/2 - minoCentroid.y; + + return mouseX > x0 && mouseX < x1 && mouseY > y0 && mouseY < y1; + + } + + void animateSeparability() { + + animationCounter = (animationCounter + 1)%60; + if (animationCounter < 30) { + fill(hue1,satHI,valHI-animationCounter); + // println(100+animationCounter); + } + else { + fill(hue1,satHI,valHI-60+animationCounter); + // println(250-animationCounter); + } + + } + + void spreadActivation() { + + notSpreadYet = false; + activationCounter += 1; + if (activationCounter > 4) { + if(left != null && left.notSpreadYet) { + left.spreadActivation(); + } + if(right != null && right.notSpreadYet) { + right.spreadActivation(); + } + if(above != null && above.notSpreadYet) { + above.spreadActivation(); + } + if(below != null && below.notSpreadYet) { + below.spreadActivation(); + } + activationCounter = 0; + } + + } + +} + + + + diff --git a/_site/all-posts.json b/_site/all-posts.json new file mode 100755 index 0000000..dc5b259 --- /dev/null +++ b/_site/all-posts.json @@ -0,0 +1 @@ +{ "posts" : [ "/blog/tda-cme-paper/", "/blog/welcome/" ] } \ No newline at end of file diff --git a/_site/blog/archive/index.html b/_site/blog/archive/index.html new file mode 100755 index 0000000..349a911 --- /dev/null +++ b/_site/blog/archive/index.html @@ -0,0 +1,5 @@ +brain dynamics lab / blog / archive \ No newline at end of file diff --git a/_site/blog/index.html b/_site/blog/index.html new file mode 100755 index 0000000..ae67906 --- /dev/null +++ b/_site/blog/index.html @@ -0,0 +1,5 @@ +brain dynamics lab / blog

Quick Summary

We just had our paper accepted in Nature Communications, which presents a new method to examine the brain dynamics at a single participant level. Here, we used Topological Data Analysis (TDA) based Mapper to reveal the overall organization of brain dynamics without arbitrarily collapsing data in time and space early in the analysis. The generated shape graphs provide interpretable visualizations of how the brain traverses its dynamical landscape—namely data-driven abstractions that attempt to capture the stream of thought originally proposed by William James (Chapter IX) — and permit quantification of these dynamic trajectories in behaviorally and clinically relevant ways that allow comparisons across conditions, participants, and populations.

Brief Background

How our brain dynamically adapts to perform different tasks is vital to understanding the neural basis of cognition. Understanding the brain’s dynamical organization is crucial for finding causes, cures and effective treatments for neurobiological disorders. The brain’s inability to dynamically adjust to environmental demands and aberrant brain dynamics have been previously associated with disorders such as schizophrenia, depression, attention deficiency and anxiety disorders. However, the high spatiotemporal dimensionality and complexity of neuroimaging data make the study of whole-brain dynamics a challenging endeavor.

Researchers and clinicians alike demand novel methods that are aimed at distilling complex high dimensional data into simple—yet vibrant and behaviorally relevant—representations that can be interactively explored to discover new aspects of the data. Ideally, such representations could also be quantified to allow for statistical inferences and to provide the basis of biomarkers and treatment response factors at the single-subject level.

With these goals in sight, we used TDA-based Mapper tool to:

  1. distill high dimensional neuroimaging data into behaviorally relevant representations

  2. circumvent arbitrary averaging of data in space (over regions/nodes) or time (over 30 s windows or scan sessions)

  3. make statistical inferences at the level of single participants.

Key Findings

Without arbitrarily collapsing data in space or time, our TDA-based approach generates graphical representations of how the brain navigates through different functional configurations during a scanning session—i.e., a data-driven representation of the stream of mind (see movie) that unfolds as participants lie in the scanner

These representations, when computed on a continuous multitask dataset, revealed the temporal arrangement of whole-brain activation maps as a hybrid of two mesoscale structures, i.e., community and core−periphery organization.

Remarkably, the community structure was found to be essential for the overall task performance, while the core−periphery arrangement revealed that brain activity patterns during evoked tasks were aggregated as a core while patterns during resting state were located in the periphery.

Neurophysiologically, the core represented taskspecific (task-positive) brain activations, while the periphery represented task-unrelated (task-negative) activations. This neurophysiological insight indicates higher similarity of whole-brain activation patterns when participants are actively engaged in cognitively demanding tasks compared to when allowed to freely mind-wander during rest periods, which is a well-established hallmark of brain dynamics.

Lastly, by projecting shape graphs into the time domain, we were able to pinpoint between- as well as within-task transitions at the temporal resolution of a few time frames.

Next steps

Application of the developed methods to study abberant brain dynamics in patients with mental health disorders.

Movie


Collaborators

Funding

  • NIMH (K99/R00 award to M.S.) and Brain & Behavior Foundation (NARSAD Young Investigator Award to M.S.)

10 Apr 2018 by Manish Saggar

Welcome. I created this site to host our lab's work. Check out the papers tab for articles on large projects. The blog posts, in this section of the website, will provide a quick introduction to the papers and pointers to future and other related work.

\ No newline at end of file diff --git a/_site/blog/tda-cme-paper/index.html b/_site/blog/tda-cme-paper/index.html new file mode 100755 index 0000000..8a787dc --- /dev/null +++ b/_site/blog/tda-cme-paper/index.html @@ -0,0 +1,269 @@ + + + + + + + + + + + Topological Data Analysis of fMRI data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+
+
+
+
+ +

+

+ 11 Apr 2018 + + by + Manish Saggar + + + +
+
+
+
+
+
+ +
+ +
+
+
+ + + + + + + +
+ + +

Quick Summary

+ +

We just had our paper accepted in Nature Communications, which presents a new method to examine the brain dynamics at a single participant level. Here, we used Topological Data Analysis (TDA) based Mapper to reveal the overall organization of brain dynamics without arbitrarily collapsing data in time and space early in the analysis. The generated shape graphs provide interpretable visualizations of how the brain traverses its dynamical landscape—namely data-driven abstractions that attempt to capture the stream of thought originally proposed by William James (Chapter IX) — and permit quantification of these dynamic trajectories in behaviorally and clinically relevant ways that allow comparisons across conditions, participants, and populations.

+ +

Brief Background

+ +

How our brain dynamically adapts to perform different tasks is vital to understanding the neural basis of cognition. Understanding the brain’s dynamical organization is crucial for finding causes, cures and effective treatments for neurobiological disorders. The brain’s inability to dynamically adjust to environmental demands and aberrant brain dynamics have been previously associated with disorders such as schizophrenia, depression, attention deficiency and anxiety disorders. However, the high spatiotemporal dimensionality and complexity of neuroimaging data make the study of whole-brain dynamics a challenging endeavor.

+ +

Researchers and clinicians alike demand novel methods that are aimed at distilling complex high dimensional data into simple—yet vibrant and behaviorally relevant—representations that can be interactively explored to discover new aspects of the data. Ideally, such representations could also be quantified to allow for statistical inferences and to provide the basis of biomarkers and treatment response factors at the single-subject level.

+ +

With these goals in sight, we used TDA-based Mapper tool to:

+ +
    +
  1. distill high dimensional neuroimaging data into behaviorally relevant representations

  2. +
  3. circumvent arbitrary averaging of data in space (over regions/nodes) or time (over 30 s windows or scan sessions)

  4. +
  5. make statistical inferences at the level of single participants.

  6. +
+ +

Key Findings

+ +

Without arbitrarily collapsing data in space or time, our TDA-based approach generates graphical representations of how the brain navigates through different functional configurations during a scanning session—i.e., a data-driven representation of the stream of mind (see movie) that unfolds as participants lie in the scanner

+ +
+ +
+ +

These representations, when computed on a continuous multitask dataset, revealed the temporal arrangement of whole-brain activation maps as a hybrid of two mesoscale structures, i.e., community and core−periphery organization.

+ +

Remarkably, the community structure was found to be essential for the overall task performance, while the core−periphery arrangement revealed that brain activity patterns during evoked tasks were aggregated as a core while patterns during resting state were located in the periphery.

+ +

Neurophysiologically, the core represented taskspecific (task-positive) brain activations, while the periphery represented task-unrelated (task-negative) activations. This neurophysiological insight indicates higher similarity of whole-brain activation patterns when participants are actively engaged in cognitively demanding tasks compared to when allowed to freely mind-wander during rest periods, which is a well-established hallmark of brain dynamics.

+ +

Lastly, by projecting shape graphs into the time domain, we were able to pinpoint between- as well as within-task transitions at the temporal resolution of a few time frames.

+ +
+ +
+ +

Next steps

+ +

Application of the developed methods to study abberant brain dynamics in patients with mental health disorders.

+ +

Movie

+ +
+ +
+ +


+ +

Collaborators

+ + + +

Funding

+ +
    +
  • NIMH (K99/R00 award to M.S.) and Brain & Behavior Foundation (NARSAD Young Investigator Award to M.S.)
  • +
+ +
+
+
+
+ +
+
+ +
+ + +
+ + + + + + diff --git a/_site/blog/welcome/index.html b/_site/blog/welcome/index.html new file mode 100755 index 0000000..4de0b11 --- /dev/null +++ b/_site/blog/welcome/index.html @@ -0,0 +1,196 @@ + + + + + + + + + + + Welcome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+ Welcome +
+

+

+ 10 Apr 2018 + + by + Manish Saggar + + + +
+
+
+
+
+
+ +
+ +
+
+
+ +
+

Welcome. I created this site to host our lab's work. Check out the papers tab for articles on large projects. The blog posts, in this section of the website, will provide a quick introduction to the papers and pointers to future and other related work.

+ +
+
+
+
+ +
+
+ +
+ + +
+ + + + + + diff --git a/_site/css/bootstrap/alerts.less b/_site/css/bootstrap/alerts.less new file mode 100755 index 0000000..c4199db --- /dev/null +++ b/_site/css/bootstrap/alerts.less @@ -0,0 +1,73 @@ +// +// Alerts +// -------------------------------------------------- + + +// Base styles +// ------------------------- + +.alert { + padding: @alert-padding; + margin-bottom: @line-height-computed; + border: 1px solid transparent; + border-radius: @alert-border-radius; + + // Headings for larger alerts + h4 { + margin-top: 0; + // Specified for the h4 to prevent conflicts of changing @headings-color + color: inherit; + } + + // Provide class for links that match alerts + .alert-link { + font-weight: @alert-link-font-weight; + } + + // Improve alignment and spacing of inner content + > p, + > ul { + margin-bottom: 0; + } + + > p + p { + margin-top: 5px; + } +} + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. +.alert-dismissible { + padding-right: (@alert-padding + 20); + + // Adjust close link position + .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } +} + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); +} + +.alert-info { + .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); +} + +.alert-warning { + .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); +} + +.alert-danger { + .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); +} diff --git a/_site/css/bootstrap/badges.less b/_site/css/bootstrap/badges.less new file mode 100755 index 0000000..c70bb93 --- /dev/null +++ b/_site/css/bootstrap/badges.less @@ -0,0 +1,66 @@ +// +// Badges +// -------------------------------------------------- + + +// Base class +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: @font-size-small; + font-weight: @badge-font-weight; + color: @badge-color; + line-height: @badge-line-height; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: @badge-bg; + border-radius: @badge-border-radius; + + // Empty badges collapse automatically (not available in IE8) + &:empty { + display: none; + } + + // Quick fix for badges in buttons + .btn & { + position: relative; + top: -1px; + } + + .btn-xs &, + .btn-group-xs > .btn & { + top: 0; + padding: 1px 5px; + } + + // Hover state, but only for links + a& { + &:hover, + &:focus { + color: @badge-link-hover-color; + text-decoration: none; + cursor: pointer; + } + } + + // Account for badges in navs + .list-group-item.active > &, + .nav-pills > .active > a > & { + color: @badge-active-color; + background-color: @badge-active-bg; + } + + .list-group-item > & { + float: right; + } + + .list-group-item > & + & { + margin-right: 5px; + } + + .nav-pills > li > a > & { + margin-left: 3px; + } +} diff --git a/_site/css/bootstrap/bootstrap.less b/_site/css/bootstrap/bootstrap.less new file mode 100755 index 0000000..d4eaded --- /dev/null +++ b/_site/css/bootstrap/bootstrap.less @@ -0,0 +1,50 @@ +// Core variables and mixins +@import "variables.less"; +@import "mixins.less"; + +// Reset and dependencies +@import "normalize.less"; +@import "print.less"; +@import "glyphicons.less"; + +// Core CSS +@import "scaffolding.less"; +@import "type.less"; +@import "code.less"; +@import "grid.less"; +@import "tables.less"; +@import "forms.less"; +@import "buttons.less"; + +// Components +@import "component-animations.less"; +@import "dropdowns.less"; +@import "button-groups.less"; +@import "input-groups.less"; +@import "navs.less"; +@import "navbar.less"; +@import "breadcrumbs.less"; +@import "pagination.less"; +@import "pager.less"; +@import "labels.less"; +@import "badges.less"; +//@import "jumbotron.less"; +@import "thumbnails.less"; +//@import "alerts.less"; +//@import "progress-bars.less"; +@import "media.less"; +@import "list-group.less"; +@import "panels.less"; +@import "responsive-embed.less"; +@import "wells.less"; +@import "close.less"; + +// Components w/ JavaScript +//@import "modals.less"; +//@import "tooltip.less"; +//import "popovers.less"; +//@import "carousel.less"; + +// Utility classes +@import "utilities.less"; +@import "responsive-utilities.less"; diff --git a/_site/css/bootstrap/breadcrumbs.less b/_site/css/bootstrap/breadcrumbs.less new file mode 100755 index 0000000..cb01d50 --- /dev/null +++ b/_site/css/bootstrap/breadcrumbs.less @@ -0,0 +1,26 @@ +// +// Breadcrumbs +// -------------------------------------------------- + + +.breadcrumb { + padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; + margin-bottom: @line-height-computed; + list-style: none; + background-color: @breadcrumb-bg; + border-radius: @border-radius-base; + + > li { + display: inline-block; + + + li:before { + content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space + padding: 0 5px; + color: @breadcrumb-color; + } + } + + > .active { + color: @breadcrumb-active-color; + } +} diff --git a/_site/css/bootstrap/button-groups.less b/_site/css/bootstrap/button-groups.less new file mode 100755 index 0000000..13c1800 --- /dev/null +++ b/_site/css/bootstrap/button-groups.less @@ -0,0 +1,243 @@ +// +// Button groups +// -------------------------------------------------- + +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; // match .btn alignment given font-size hack above + > .btn { + position: relative; + float: left; + // Bring the "active" button to the front + &:hover, + &:focus, + &:active, + &.active { + z-index: 2; + } + } +} + +// Prevent double borders when buttons are next to each other +.btn-group { + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -1px; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-left: -5px; // Offset the first child's margin + &:extend(.clearfix all); + + .btn-group, + .input-group { + float: left; + } + > .btn, + > .btn-group, + > .input-group { + margin-left: 5px; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + &:not(:last-child):not(.dropdown-toggle) { + .border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + .border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + .border-right-radius(0); + } +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + .border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-xs > .btn { &:extend(.btn-xs); } +.btn-group-sm > .btn { &:extend(.btn-sm); } +.btn-group-lg > .btn { &:extend(.btn-lg); } + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + .box-shadow(none); + } +} + + +// Reposition the caret +.btn .caret { + margin-left: 0; +} +// Carets in other button sizes +.btn-lg .caret { + border-width: @caret-width-large @caret-width-large 0; + border-bottom-width: 0; +} +// Upside down carets for .dropup +.dropup .btn-lg .caret { + border-width: 0 @caret-width-large @caret-width-large; +} + + +// Vertical button groups +// ---------------------- + +.btn-group-vertical { + > .btn, + > .btn-group, + > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + + // Clear floats so dropdown menus can be properly placed + > .btn-group { + &:extend(.clearfix all); + > .btn { + float: none; + } + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + border-top-right-radius: @border-radius-base; + .border-bottom-radius(0); + } + &:last-child:not(:first-child) { + border-bottom-left-radius: @border-radius-base; + .border-top-radius(0); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + .border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + .border-top-radius(0); +} + + +// Justified button groups +// ---------------------- + +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; + > .btn, + > .btn-group { + float: none; + display: table-cell; + width: 1%; + } + > .btn-group .btn { + width: 100%; + } + + > .btn-group .dropdown-menu { + left: auto; + } +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/_site/css/bootstrap/buttons.less b/_site/css/bootstrap/buttons.less new file mode 100755 index 0000000..5a74604 --- /dev/null +++ b/_site/css/bootstrap/buttons.less @@ -0,0 +1,160 @@ +// +// Buttons +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +.btn { + display: inline-block; + margin-bottom: 0; // For input.btn + font-weight: @btn-font-weight; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid transparent; + white-space: nowrap; + .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base); + .user-select(none); + + &, + &:active, + &.active { + &:focus, + &.focus { + .tab-focus(); + } + } + + &:hover, + &:focus, + &.focus { + color: @btn-default-color; + text-decoration: none; + } + + &:active, + &.active { + outline: 0; + background-image: none; + .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + } + + &.disabled, + &[disabled], + fieldset[disabled] & { + cursor: @cursor-disabled; + pointer-events: none; // Future-proof disabling of clicks + .opacity(.65); + .box-shadow(none); + } +} + + +// Alternate buttons +// -------------------------------------------------- + +.btn-default { + .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); +} +.btn-primary { + .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); +} +// Success appears as green +.btn-success { + .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); +} +// Info appears as blue-green +.btn-info { + .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); +} +// Warning appears as orange +.btn-warning { + .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); +} +// Danger and error appear as red +.btn-danger { + .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); +} + + +// Link buttons +// ------------------------- + +// Make a button look and behave like a link +.btn-link { + color: @link-color; + font-weight: normal; + border-radius: 0; + + &, + &:active, + &.active, + &[disabled], + fieldset[disabled] & { + background-color: transparent; + .box-shadow(none); + } + &, + &:hover, + &:focus, + &:active { + border-color: transparent; + } + &:hover, + &:focus { + color: @link-hover-color; + text-decoration: @link-hover-decoration; + background-color: transparent; + } + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus { + color: @btn-link-disabled-color; + text-decoration: none; + } + } +} + + +// Button Sizes +// -------------------------------------------------- + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); +} +.btn-xs { + .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small); +} + + +// Block button +// -------------------------------------------------- + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/_site/css/bootstrap/carousel.less b/_site/css/bootstrap/carousel.less new file mode 100755 index 0000000..4bbe946 --- /dev/null +++ b/_site/css/bootstrap/carousel.less @@ -0,0 +1,269 @@ +// +// Carousel +// -------------------------------------------------- + + +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; + + > .item { + display: none; + position: relative; + .transition(.6s ease-in-out left); + + // Account for jankitude on images + > img, + > a > img { + &:extend(.img-responsive); + line-height: 1; + } + + // WebKit CSS3 transforms for supported devices + @media all and (transform-3d), (-webkit-transform-3d) { + .transition-transform(~'0.6s ease-in-out'); + .backface-visibility(~'hidden'); + .perspective(1000); + + &.next, + &.active.right { + .translate3d(100%, 0, 0); + left: 0; + } + &.prev, + &.active.left { + .translate3d(-100%, 0, 0); + left: 0; + } + &.next.left, + &.prev.right, + &.active { + .translate3d(0, 0, 0); + left: 0; + } + } + } + + > .active, + > .next, + > .prev { + display: block; + } + + > .active { + left: 0; + } + + > .next, + > .prev { + position: absolute; + top: 0; + width: 100%; + } + + > .next { + left: 100%; + } + > .prev { + left: -100%; + } + > .next.left, + > .prev.right { + left: 0; + } + + > .active.left { + left: -100%; + } + > .active.right { + left: 100%; + } + +} + +// Left/right controls for nav +// --------------------------- + +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: @carousel-control-width; + .opacity(@carousel-control-opacity); + font-size: @carousel-control-font-size; + color: @carousel-control-color; + text-align: center; + text-shadow: @carousel-text-shadow; + // We can't have this transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Set gradients for backgrounds + &.left { + #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); + } + &.right { + left: auto; + right: 0; + #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); + } + + // Hover/focus state + &:hover, + &:focus { + outline: 0; + color: @carousel-control-color; + text-decoration: none; + .opacity(.9); + } + + // Toggles + .icon-prev, + .icon-next, + .glyphicon-chevron-left, + .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + } + .icon-prev, + .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; + } + .icon-next, + .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; + } + .icon-prev, + .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + line-height: 1; + font-family: serif; + } + + + .icon-prev { + &:before { + content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) + } + } + .icon-next { + &:before { + content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) + } + } +} + +// Optional indicator pips +// +// Add an unordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; + + li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid @carousel-indicator-border-color; + border-radius: 10px; + cursor: pointer; + + // IE8-9 hack for event handling + // + // Internet Explorer 8-9 does not support clicks on elements without a set + // `background-color`. We cannot use `filter` since that's not viewed as a + // background color by the browser. Thus, a hack is needed. + // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer + // + // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we + // set alpha transparency for the best results possible. + background-color: #000 \9; // IE8 + background-color: rgba(0,0,0,0); // IE9 + } + .active { + margin: 0; + width: 12px; + height: 12px; + background-color: @carousel-indicator-active-bg; + } +} + +// Optional captions +// ----------------------------- +// Hidden by default for smaller viewports +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: @carousel-caption-color; + text-align: center; + text-shadow: @carousel-text-shadow; + & .btn { + text-shadow: none; // No shadow for button elements in carousel-caption + } +} + + +// Scale up controls for tablets and up +@media screen and (min-width: @screen-sm-min) { + + // Scale up the controls a smidge + .carousel-control { + .glyphicon-chevron-left, + .glyphicon-chevron-right, + .icon-prev, + .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .glyphicon-chevron-left, + .icon-prev { + margin-left: -15px; + } + .glyphicon-chevron-right, + .icon-next { + margin-right: -15px; + } + } + + // Show and left align the captions + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + + // Move up the indicators + .carousel-indicators { + bottom: 20px; + } +} diff --git a/_site/css/bootstrap/close.less b/_site/css/bootstrap/close.less new file mode 100755 index 0000000..6d5bfe0 --- /dev/null +++ b/_site/css/bootstrap/close.less @@ -0,0 +1,34 @@ +// +// Close icons +// -------------------------------------------------- + + +.close { + float: right; + font-size: (@font-size-base * 1.5); + font-weight: @close-font-weight; + line-height: 1; + color: @close-color; + text-shadow: @close-text-shadow; + .opacity(.2); + + &:hover, + &:focus { + color: @close-color; + text-decoration: none; + cursor: pointer; + .opacity(.5); + } + + // Additional properties for button version + // iOS requires the button element instead of an anchor tag. + // If you want the anchor version, it requires `href="#"`. + // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile + button& { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + } +} diff --git a/_site/css/bootstrap/code.less b/_site/css/bootstrap/code.less new file mode 100755 index 0000000..a08b4d4 --- /dev/null +++ b/_site/css/bootstrap/code.less @@ -0,0 +1,69 @@ +// +// Code (inline and block) +// -------------------------------------------------- + + +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: @font-family-monospace; +} + +// Inline code +code { + padding: 2px 4px; + font-size: 90%; + color: @code-color; + background-color: @code-bg; + border-radius: @border-radius-base; +} + +// User input typically entered via keyboard +kbd { + padding: 2px 4px; + font-size: 90%; + color: @kbd-color; + background-color: @kbd-bg; + border-radius: @border-radius-small; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); + + kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; + } +} + +// Blocks of code +pre { + display: block; + padding: ((@line-height-computed - 1) / 2); + margin: 0 0 (@line-height-computed / 2); + font-size: (@font-size-base - 1); // 14px to 13px + line-height: @line-height-base; + word-break: break-all; + word-wrap: break-word; + color: @pre-color; + background-color: @pre-bg; + border: 1px solid @pre-border-color; + border-radius: @border-radius-base; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: @pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/_site/css/bootstrap/component-animations.less b/_site/css/bootstrap/component-animations.less new file mode 100755 index 0000000..0bcee91 --- /dev/null +++ b/_site/css/bootstrap/component-animations.less @@ -0,0 +1,33 @@ +// +// Component animations +// -------------------------------------------------- + +// Heads up! +// +// We don't use the `.opacity()` mixin here since it causes a bug with text +// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. + +.fade { + opacity: 0; + .transition(opacity .15s linear); + &.in { + opacity: 1; + } +} + +.collapse { + display: none; + + &.in { display: block; } + tr&.in { display: table-row; } + tbody&.in { display: table-row-group; } +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + .transition-property(~"height, visibility"); + .transition-duration(.35s); + .transition-timing-function(ease); +} diff --git a/_site/css/bootstrap/dropdowns.less b/_site/css/bootstrap/dropdowns.less new file mode 100755 index 0000000..af34460 --- /dev/null +++ b/_site/css/bootstrap/dropdowns.less @@ -0,0 +1,214 @@ +// +// Dropdown menus +// -------------------------------------------------- + + +// Dropdown arrow/caret +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: @caret-width-base dashed; + border-right: @caret-width-base solid transparent; + border-left: @caret-width-base solid transparent; +} + +// The dropdown wrapper (div) +.dropup, +.dropdown { + position: relative; +} + +// Prevent the focus on the dropdown toggle when closing dropdowns +.dropdown-toggle:focus { + outline: 0; +} + +// The dropdown menu (ul) +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: @zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; // override default ul + list-style: none; + font-size: @font-size-base; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + background-color: @dropdown-bg; + border: 1px solid @dropdown-fallback-border; // IE8 fallback + border: 1px solid @dropdown-border; + border-radius: @border-radius-base; + .box-shadow(0 6px 12px rgba(0,0,0,.175)); + background-clip: padding-box; + + // Aligns the dropdown menu to right + // + // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` + &.pull-right { + right: 0; + left: auto; + } + + // Dividers (basically an hr) within the dropdown + .divider { + .nav-divider(@dropdown-divider-bg); + } + + // Links within the dropdown menu + > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: @line-height-base; + color: @dropdown-link-color; + white-space: nowrap; // prevent links from randomly breaking onto new lines + } +} + +// Hover/Focus state +.dropdown-menu > li > a { + &:hover, + &:focus { + text-decoration: none; + color: @dropdown-link-hover-color; + background-color: @dropdown-link-hover-bg; + } +} + +// Active state +.dropdown-menu > .active > a { + &, + &:hover, + &:focus { + color: @dropdown-link-active-color; + text-decoration: none; + outline: 0; + background-color: @dropdown-link-active-bg; + } +} + +// Disabled state +// +// Gray out text and ensure the hover/focus state remains gray + +.dropdown-menu > .disabled > a { + &, + &:hover, + &:focus { + color: @dropdown-link-disabled-color; + } + + // Nuke hover/focus effects + &:hover, + &:focus { + text-decoration: none; + background-color: transparent; + background-image: none; // Remove CSS gradient + .reset-filter(); + cursor: @cursor-disabled; + } +} + +// Open state for the dropdown +.open { + // Show the menu + > .dropdown-menu { + display: block; + } + + // Remove the outline when :focus is triggered + > a { + outline: 0; + } +} + +// Menu positioning +// +// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown +// menu with the parent. +.dropdown-menu-right { + left: auto; // Reset the default from `.dropdown-menu` + right: 0; +} +// With v3, we enabled auto-flipping if you have a dropdown within a right +// aligned nav component. To enable the undoing of that, we provide an override +// to restore the default dropdown menu alignment. +// +// This is only for left-aligning a dropdown menu within a `.navbar-right` or +// `.pull-right` nav component. +.dropdown-menu-left { + left: 0; + right: auto; +} + +// Dropdown section headers +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: @font-size-small; + line-height: @line-height-base; + color: @dropdown-header-color; + white-space: nowrap; // as with > li > a +} + +// Backdrop to catch body clicks on mobile, etc. +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: (@zindex-dropdown - 10); +} + +// Right aligned dropdowns +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +// Allow for dropdowns to go bottom up (aka, dropup-menu) +// +// Just add .dropup after the standard .dropdown class and you're set, bro. +// TODO: abstract this so that the navbar fixed styles are not placed here? + +.dropup, +.navbar-fixed-bottom .dropdown { + // Reverse the caret + .caret { + border-top: 0; + border-bottom: @caret-width-base solid; + content: ""; + } + // Different positioning for bottom up menu + .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; + } +} + + +// Component alignment +// +// Reiterate per navbar.less and the modified component alignment there. + +@media (min-width: @grid-float-breakpoint) { + .navbar-right { + .dropdown-menu { + .dropdown-menu-right(); + } + // Necessary for overrides of the default right aligned menu. + // Will remove come v4 in all likelihood. + .dropdown-menu-left { + .dropdown-menu-left(); + } + } +} diff --git a/_site/css/bootstrap/forms.less b/_site/css/bootstrap/forms.less new file mode 100755 index 0000000..e4b5062 --- /dev/null +++ b/_site/css/bootstrap/forms.less @@ -0,0 +1,574 @@ +// +// Forms +// -------------------------------------------------- + + +// Normalize non-controls +// +// Restyle and baseline non-control form elements. + +fieldset { + padding: 0; + margin: 0; + border: 0; + // Chrome and Firefox set a `min-width: min-content;` on fieldsets, + // so we reset that to ensure it behaves more like a standard block element. + // See https://github.com/twbs/bootstrap/issues/12359. + min-width: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @line-height-computed; + font-size: (@font-size-base * 1.5); + line-height: inherit; + color: @legend-color; + border: 0; + border-bottom: 1px solid @legend-border-color; +} + +label { + display: inline-block; + max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) + margin-bottom: 5px; + font-weight: bold; +} + + +// Normalize form controls +// +// While most of our form styles require extra classes, some basic normalization +// is required to ensure optimum display with or without those classes to better +// address browser inconsistencies. + +// Override content-box in Normalize (* isn't specific enough) +input[type="search"] { + .box-sizing(border-box); +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; // IE8-9 + line-height: normal; +} + +// Set the height of file controls to match text inputs +input[type="file"] { + display: block; +} + +// Make range inputs behave like textual form controls +input[type="range"] { + display: block; + width: 100%; +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for file, radio, and checkbox +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + .tab-focus(); +} + +// Adjust output element +output { + display: block; + padding-top: (@padding-base-vertical + 1); + font-size: @font-size-base; + line-height: @line-height-base; + color: @input-color; +} + + +// Common form controls +// +// Shared size and type resets for form controls. Apply `.form-control` to any +// of the following form controls: +// +// select +// textarea +// input[type="text"] +// input[type="password"] +// input[type="datetime"] +// input[type="datetime-local"] +// input[type="date"] +// input[type="month"] +// input[type="time"] +// input[type="week"] +// input[type="number"] +// input[type="email"] +// input[type="url"] +// input[type="search"] +// input[type="tel"] +// input[type="color"] + +.form-control { + display: block; + width: 100%; + height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) + padding: @padding-base-vertical @padding-base-horizontal; + font-size: @font-size-base; + line-height: @line-height-base; + color: @input-color; + background-color: @input-bg; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid @input-border; + border-radius: @input-border-radius; // Note: This has no effect on s in CSS. + .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); + + // Customize the `:focus` state to imitate native WebKit styles. + .form-control-focus(); + + // Placeholder + .placeholder(); + + // Disabled and read-only inputs + // + // HTML5 says that controls under a fieldset > legend:first-child won't be + // disabled if the fieldset is disabled. Due to implementation difficulty, we + // don't honor that edge case; we style them as disabled anyway. + &[disabled], + &[readonly], + fieldset[disabled] & { + background-color: @input-bg-disabled; + opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655 + } + + &[disabled], + fieldset[disabled] & { + cursor: @cursor-disabled; + } + + // Reset height for `textarea`s + textarea& { + height: auto; + } +} + + +// Search inputs in iOS +// +// This overrides the extra rounded corners on search inputs in iOS so that our +// `.form-control` class can properly style them. Note that this cannot simply +// be added to `.form-control` as it's not specific enough. For details, see +// https://github.com/twbs/bootstrap/issues/11586. + +input[type="search"] { + -webkit-appearance: none; +} + + +// Special styles for iOS temporal inputs +// +// In Mobile Safari, setting `display: block` on temporal inputs causes the +// text within the input to become vertically misaligned. As a workaround, we +// set a pixel line-height that matches the given height of the input, but only +// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848 + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: @input-height-base; + + &.input-sm, + .input-group-sm & { + line-height: @input-height-small; + } + + &.input-lg, + .input-group-lg & { + line-height: @input-height-large; + } + } +} + + +// Form groups +// +// Designed to help with the organization and spacing of vertical forms. For +// horizontal forms, use the predefined grid classes. + +.form-group { + margin-bottom: @form-group-margin-bottom; +} + + +// Checkboxes and radios +// +// Indent the labels to position radios/checkboxes as hanging controls. + +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + + label { + min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; + } +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing +} + +// Radios and checkboxes on same line +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; // space out consecutive inline controls +} + +// Apply same disabled cursor tweak as for inputs +// Some special care is needed because