From 400819cc1bb4dfa1ffe71c4b4f019463a52ce187 Mon Sep 17 00:00:00 2001 From: Sandler Date: Thu, 17 Feb 2022 13:02:56 +0100 Subject: [PATCH 01/21] First commit --- code/script.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/code/script.js b/code/script.js index e69de29b..d68cf66c 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,21 @@ +const API_all_repos = "https://api.github.com/users/jessand77/repos"; + +fetch(API_all_repos) + // we ask for the response from the API + .then((response) => response.json()) + // we say what we want to be done with the response + .then((repos) => { + console.log(repos); + + const forkedRepos = repos + .filter((repo) => repo.fork === true) + .map((repo) => repo.name); + + console.log(forkedRepos); + + const reposStartingWithFilter = repos + .filter((repo) => repo.name.startsWith("project")) + .map((repo) => repo.name); + + console.log(reposStartingWithFilter); + }); From 7b4b25aaf751e6973d8c612c8fb4f4134067e0da Mon Sep 17 00:00:00 2001 From: Sandler Date: Thu, 17 Feb 2022 18:15:30 +0100 Subject: [PATCH 02/21] Second commit --- code/script.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/script.js b/code/script.js index d68cf66c..d4d37eb8 100644 --- a/code/script.js +++ b/code/script.js @@ -1,3 +1,5 @@ +const projectSection = document.getElementById("projects"); + const API_all_repos = "https://api.github.com/users/jessand77/repos"; fetch(API_all_repos) @@ -7,6 +9,16 @@ fetch(API_all_repos) .then((repos) => { console.log(repos); + projectSection.innerHTML = `

All projects

`; + + //Hur kan jag lägga in listelementen i en ul? + + repos.forEach((repo) => { + projectSection.innerHTML += ` +
  • ${repo.name}
  • + `; + }); + const forkedRepos = repos .filter((repo) => repo.fork === true) .map((repo) => repo.name); From 2b9c7537c63cd64185a91d70b63f2e2ab1179ffb Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sat, 19 Feb 2022 16:42:02 +0100 Subject: [PATCH 03/21] Added getCommits function etc --- code/index.html | 6 ++- code/script.js | 111 ++++++++++++++++++++++++++++++++++++++++++------ code/style.css | 30 ++++++++++++- 3 files changed, 131 insertions(+), 16 deletions(-) diff --git a/code/index.html b/code/index.html index 2fb5e0ae..2507e946 100644 --- a/code/index.html +++ b/code/index.html @@ -9,8 +9,10 @@

    GitHub Tracker

    -

    Projects:

    -
    +
    +
    +
    +
    diff --git a/code/script.js b/code/script.js index d4d37eb8..ed704941 100644 --- a/code/script.js +++ b/code/script.js @@ -1,33 +1,118 @@ +const userSection = document.getElementById("user"); const projectSection = document.getElementById("projects"); -const API_all_repos = "https://api.github.com/users/jessand77/repos"; +const API_USER_INFO = "https://api.github.com/users/jessand77"; +const API_REPOS = "https://api.github.com/users/jessand77/repos"; -fetch(API_all_repos) + + +// Läs lite här: https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-fetch-api-to-get-data + +const fetchUserInfo = () => { + fetch(API_USER_INFO) + .then((response) => response.json()) + .then((user) => { + console.log(user) + userSection.innerHTML = '

    User infoUser name: ${user.login}

    ` + userSection.innerHTML += `profile picture` + }) + .catch(err => console.error(err)); +} + +const fetchRepos = () => { + fetch(API_REPOS) // we ask for the response from the API .then((response) => response.json()) // we say what we want to be done with the response .then((repos) => { console.log(repos); - projectSection.innerHTML = `

    All projects

    `; - - //Hur kan jag lägga in listelementen i en ul? - + /* + projectSection.innerHTML = '

    Projects

    ' + let htmlAllRepos = '

    All my projects

      ' repos.forEach((repo) => { - projectSection.innerHTML += ` -
    • ${repo.name}
    • - `; + htmlAllRepos += `
    • ${repo.name}
    • ` }); + htmlAllRepos += '
    ' + projectSection.innerHTML += htmlAllRepos + + // Returns an array of the forked repos const forkedRepos = repos .filter((repo) => repo.fork === true) .map((repo) => repo.name); console.log(forkedRepos); - const reposStartingWithFilter = repos - .filter((repo) => repo.name.startsWith("project")) - .map((repo) => repo.name); + let htmlForkedRepos = '

    All forked repos

      '; + forkedRepos.forEach((repo) => { + htmlForkedRepos += `
    • ${repo}
    • ` + }); + htmlForkedRepos += '
    '; + + console.log('Forked repos: ' + htmlForkedRepos) + + projectSection.innerHTML += htmlForkedRepos + */ + + + // Returns an array of the forked repos from Technigo + // const reposStartingWithFilter = repos + // .filter((repo) => repo.name.startsWith("project")) + // .map((repo) => repo.name); + + // console.log(reposStartingWithFilter); + + // let htmlTechnigoRepos = '

    Repos forked from Technigo

    '; + // reposStartingWithFilter.forEach((repo) => { + // htmlTechnigoRepos += ` + //
    + //

    ${repo}

    + //

    ${repo}

    + //

    + // ` + // }); + + const getCommits = (repoName) => { + fetch('https://api.github.com/repos/jessand77/' + repoName + '/commits') + .then(res => res.json()) + .then((commits) => { + console.log(commits); + const numberOfCommits = commits.map(item => item.commit).length; + console.log(repoName + ' has ' + numberOfCommits + ' commits.'); + let commitSpan = document.createElement('span'); + commitSpan.innerHTML = `${numberOfCommits}` + document.getElementById(repoName).appendChild(commitSpan); + + }) + } + + let htmlTechnigoRepos = '

    Repos forked from Technigo

    '; + + const technigoRepos = repos.filter((repo) => repo.name.startsWith("project")); + + console.log(`Number of repos forked from Technigo: ${technigoRepos.length}`); + + technigoRepos.forEach((repo) => { + console.log(repo.name) + const commits = 4; + htmlTechnigoRepos += ` +

    ${repo.name}

    +

    Most recent update: ${repo.pushed_at}

    +

    Default branch: ${repo.default_branch}

    +

    URL: ${repo.html_url}

    +

    Number of commits:

    + ` + getCommits(repo.name); + }) + + projectSection.innerHTML += htmlTechnigoRepos; - console.log(reposStartingWithFilter); }); +} + + +fetchUserInfo(); +fetchRepos(); + \ No newline at end of file diff --git a/code/style.css b/code/style.css index 7c8ad447..7c5c7f01 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,31 @@ +* { + box-sizing: border-box; +} + +html { + background-color: #FFECE9; + background-image: linear-gradient(135deg, lightgreen, violet); +} + body { - background: #FFECE9; + background-color: white; + width: 80%; + margin: 10px auto; + padding: 20px; +} + +h1 { + text-align: center; +} + +img { + height: 200px; + width: 200px; + border-radius: 50%; +} + +.flex-wrapper { + display: flex; + justify-content: space-around; + align-content: center; } \ No newline at end of file From 3199be44d1eb0cf6d97cccf1f83bc2a84b39d784 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Tue, 22 Feb 2022 08:26:39 +0100 Subject: [PATCH 04/21] Added pull request commits etc --- .DS_Store | Bin 0 -> 6148 bytes code/.DS_Store | Bin 0 -> 6148 bytes code/assets/GitHub-Mark-120px-plus.png | Bin 0 -> 4268 bytes code/assets/GitHub-Mark-32px.png | Bin 0 -> 1714 bytes code/assets/GitHub-Mark-64px.png | Bin 0 -> 2625 bytes code/assets/GitHub-Mark-Light-120px-plus.png | Bin 0 -> 4044 bytes code/assets/GitHub-Mark-Light-32px.png | Bin 0 -> 1571 bytes code/assets/GitHub-Mark-Light-64px.png | Bin 0 -> 2330 bytes code/assets/sunglasses.svg | 23 +++ code/index.html | 17 +- code/script.js | 192 ++++++++++++------- code/style.css | 85 +++++++- 12 files changed, 239 insertions(+), 78 deletions(-) create mode 100644 .DS_Store create mode 100644 code/.DS_Store create mode 100644 code/assets/GitHub-Mark-120px-plus.png create mode 100644 code/assets/GitHub-Mark-32px.png create mode 100644 code/assets/GitHub-Mark-64px.png create mode 100644 code/assets/GitHub-Mark-Light-120px-plus.png create mode 100644 code/assets/GitHub-Mark-Light-32px.png create mode 100644 code/assets/GitHub-Mark-Light-64px.png create mode 100644 code/assets/sunglasses.svg diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8875fa064d006fa4c89b6002bb38d4006ddb7cd0 GIT binary patch literal 6148 zcmeHK%SyvQ6rHirrW7Fyg)Rr&7VJX`#Z8Fy2aM=Kr6wk5FlI`V+C?d3tv}?K_&we` zGZBk*D`M}3nRA~rnFE;zV~l&VsLPnc7_*@va#Yp`y4QxbOfn+JF~WI12~!z@{bpi+ z9q`*NcE==(Sp4<-!%3RtMW^%5w`$h*PTj8CP5Z`wkaNEXidpUj(<`*jrA)(055kKi zo{ycq6PXo3lEqV1kVG-0Twf+xB1%VXxB` zNBzNa*|7Hy4v){qkLgn;Uo@c{_*SxOu!2`mKG*Z?PqS2J_u#AYt2{ztfEXYKh=I*z zz?=zob8{)6l@kNRzz+=I{veT<@_%rK6bxq7^CH9Po)N@v{FNIfw?46HIx)24&x|0(=3YajWm zC1eo;#K1pefLkMfX7FeEH&aN S=vU={bP-U5P)7{>0s|ilj!H8C literal 0 HcmV?d00001 diff --git a/code/.DS_Store b/code/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..203f993e579f2ebf12f226242ed8a8accc8d8cdf GIT binary patch literal 6148 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 XLyRvu{aX3a{{tgEGu={c*U0|?Dtn-9 literal 0 HcmV?d00001 diff --git a/code/assets/GitHub-Mark-32px.png b/code/assets/GitHub-Mark-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..8b25551a97921681334176ee143b41510a117d86 GIT binary patch literal 1714 zcmaJ?X;2eq7*4oFu!ne{XxAht2qc?8LXr|_LPCfTpaBK7K$c{I0Ld=NLIOeuC;@2) zZ$K%a)k+m-s0>xHmKxL%0V&0TRzzznhgyqrIC$F)0{WwLXLrBvd*^wc_uSc%h%m9E z{W5z3f#4_!7RvAyFh6!S_*<8qJ%KOIm?#E|L=rJQq=gB5C6WLG5;c?r%V0>EmEH#X z5eSwPRa6WXBMs#$5H%GtW2go-in9p>zW@UYDNNWc^XOXZQ? z1QjEV00I#$3^1wQUJ8&-2UsjB-G|9y(LDhMNN3PM{APL4eYi{(m*ERcUnJa{R+-3^ z34^A6;U^v`8N*O6ji%S@sd{fJqD`XFIUJ5zgTe5^5nj414F(y!G&=H(f)Lgzv?>%+ zAsWD}2qhpH7>|TU`X&W6IxDNuO_vET7|j5oG&&VDr!)hUO8+0KR?nh!m<)a!?|%yG zqOwq!CWCcIhE{<$E|F|@g>nP6FoYr6C<8>D?ID9%&5J(4oSbR1I^byW*g@__U z4QsF&uJSEcFeleM3~ChjEQGbHOjsGDMbyAl(p=Ttv9RaVo8~I#js@@Y9C^_2U})yn zzSHU%6FxuY?d;&65MyR({^lU*3$z$ZllDb(o&<7d;A_`h2U+3~BJ2Hv`{W}KEU801#cv_B|9Cm!ynR{S`AMsSn z;7E=B;mb!wx$L;S>yGXG^6=&WlQn9$s?&L%Y1D8TI^MlKB1DqsEng$>f4=xYWBoPI z_S1p!sJ#d2?YI4kPA{k}Eby?F=f-J9zIc`YDl^pzjVm~9ebE?Hn?t0Nx+la|D0MB; z9)2xv1G>a1|A9kQ>~DV<=X3-4yC&n!m8-3K#P z{X@0zRuQsy$+N ziSCoLJU{Z$nQy4A4Y5UJ07$5FA~qL2%Q+cLaqDU?Lz3?=BC5;Nk6BbTmmceEaM>-Z zi>O&-dSE=%ex;vcvCOk{*JQ5^_4M z4lW7%l9IqY(z7pV(?I@@8=KPFO82)O{VDI18-*d-k$YmI^XiuPs_LuFw<^ZcD}yP5 c*NrbeloN*74g`U%%F6r~k%+>C^#XapzmV0H-2eap literal 0 HcmV?d00001 diff --git a/code/assets/GitHub-Mark-64px.png b/code/assets/GitHub-Mark-64px.png new file mode 100644 index 0000000000000000000000000000000000000000..182a1a3f734fc1b7d712c68b04c29bad9460d6cd GIT binary patch literal 2625 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 ZsK8ky_?39l4gAjkwLQ)WTW#Z?@NW_mBhUZ< literal 0 HcmV?d00001 diff --git a/code/assets/GitHub-Mark-Light-32px.png b/code/assets/GitHub-Mark-Light-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..628da97c70890c73e59204f5b140c4e67671e92d GIT binary patch literal 1571 zcmaJ>c~BE~6izDPQq)#Nu*KOf(n^(VHY9;fiINM65``pc+9*v(mL$bwfCjbc%v9V{8r9iX|O%>Nr%pLD2qT{mty}c=LVleeamv znz3SOSm@kP8jThvOOq(56Yzh*fz(booe!uZij=BJC6+_lbvQ~B8nA2>kXdv_RDtRY z`5QXWWEySCe6vbTs^#f?J!WC*{1~RgVx!nJTJjQyO{dRANgx|FnymtGbD9%JmCh9^y)##j7{Dcqfn*1ta$rG89pJF6w-S7Z037$rr|y0;1Onp_ zGFJdT6Q!1C0AdVB0WOmpuV=AgAQ550Tn+-mivTtYPJmz*#75#_n9oV%!#rSOfmAfy zki%C~=fTp1{O#BLpJ|0jj#m6#|LRWit-vq3PE1z9ZqyvET4sX$-Icqy7t z<=aq5ff86AuBZBu6EjJsYWM0uejufWFTwPA7Su}0Bm$7KFb!q{Um_8~A{LUG#1l(l zSehUda@kU8LIRg9fkk2tZ;~ss5~R+mM<==F7hLHpxqLB>>PQS%Vc7b~?q!%T5+h8Q z4G=4Nzyi5WZ?^gkasJ{?Xhm`JC#WG6$1K2jb@=9&D3EgD#3UhGh#*21rJjulVXjCF zvp76q62jt0zzMG5C7DlfMgPl%C^3+~wf|}Lq=}jz|MmIcQjh1Ok6NjD$Em^Iv26D> z8tt_TnM9~^Tt8mflRGPOrrX|HtT3gG4LEuuk{g2Rn}QgJIa?gZo))!!=o_l9bvD%A zZ`aHajl8#~u?!4f7F#*b*->A=R2L)6!>saz?h>#wTXT-I(XmQ zx{84skS>k=i~i`(6k4C7;Zpfx%dCPVjPayMf8pugtGM=~s=Id1l#8MZJ1-73wV#Q3 zR3>v3%}jbQs1f_Z0xo;%=LILlA+nTpKI4ha%xWW}uqHrNao~&T4AY6m`P$_n-6h*g zhoX+e4n%~gl_lhe#s+AMb7d{5WzvYTa%6Q~si@@4{;s(0zU|H&P3fE+t{7X`S#Cj@ zC#vd}^4pcBD*77Ny5=j$h8EL2_t$O38$SQiJ6fPjJMimypr~MB2(&P0aI|h}$64<0 z>_~duqNjaT=DM^6+N{&B_lED;F2wrl?!4Lk*2((x!fmrcsw+=cI^qttuZ9C}-m~5E z-ryYVpL%^xR#&(0YI5hz<(}F7-p)?FPcyJO-zVO>%9ZDXJH8pnY;GJYFDQ>vd#j_* zRrd}L(r=!g+1#nQwsO?kpS`Qq8`NxE+Zy{gf7*_7J*U2V_|NpLo{iasj7VCg_V9&| ShohtYzipXxh2)4xTkbNS=9n;FC~MOYyq z5Qu5ON?Ne?^wWKYaP5AUm;6k7ER@nCq#?pMX&OrmLdYE9CJ-6GXT^iTAd9m(`4;E} zfy}Yzg+@pt0@sk(LOz-_L`>RbTB#+~b3MT|& z14UGj%UhW)21C+=LfPqwY$6Bc>x1-?k+cr@pp=D_@sk7+lFS?R)h|hV*O@UW6`Ai_H`049j)JozV)4d8r`BUo7M!zgCCD`;G!S0dV&q zp8LL%~Ba#6Eg$iKtZe$N47EeRXa5>+}e1_})f4LZ~7>us9|I_MOlXiY|*KdQX zeS8~zP@tW6v39VXfr*USwp~rS`=B$j`)nk?@}kq(ClF4d>YOz8hkr;=W~kkm zCW7a<(pcz5X#A0R<9Z{E*BfJ?`u2(tHC?l!+(h-PRUM^q=-1CbjbNI^81U7VyU;3( zT2f^?#ma%q8;EN&iz|Pk@=)pdaMq3d25mbDNrIP#bi|hqP`3*fT}kuvR+%ng#;F!o z!3#SBB2F;iNzfJ(L`*fNFT`NdGQiAH|Ej|Hc2f5bF>p2ufwkUZTFe}(dJ$`MX;C(0 z-V{r-E2m(c5BI}drL(~k6SEswne#fEUdvi&3FiZh%N)80&$C_2kh}Zs$!WSMT5)2L z->t!4_PuW(@0iMUf!tM3EXsxR=8aqQJS!tI77vxXD$Q$NZ1vCFp)TCJPPKgJ6$dq6 z6AvwIT>T_kTfhs9Ro&hblgcP`#)4Y!f6RfcKKz5}fFeLswhx__Ru z`f>qsFw=AMC$D2)!n`KC&FVyxLH=oq<|UuIL`hLk2jvOa!Qq_R3CqNXSp|NlZhBlh z@V0BxvHNAmtK__)^rv^SNw9j3M7}#zg*ToWtbKT~2{x#g2)k9TC|R>Dzhq!T-pA~R z>ZL3u2sdInHHePlU?n!;#-16SNWGJd=j+gQ4vI}N_YbJpa3kc$Q-$nCw8DusXXMl4 z*nJS|qzj=rNJpZI; z$vRbg>YS|lmxjj--{P0zyGBQ?yoS4%MX$EkOMqE$O+Pm%_1o-3WM-q=b4f2dQfTt> zOFR@zTq!4JBAQzKEZEFs#YOE+WUR@=e`!;~PCh-+ddeAuP%>I*Cd8Cb%!1YNZFKDIJTra-- zG#+}%TS;ZSZaqDK8^0CL=AU{B|LU>Hu0mU~}a9D5U= zlszxG=SokFC;8liaQHBlh z2BUO}iYG`REj!%$Xj-syeaVfwq3hF5*L>e!Jm^2?Jo?@}>G*`TrXZHmap&CnfJ4u^ zk68!bvsByruv+!zzl{#!R8}8y9^Ra-sENMbl68A9w_o}?z5eO*E&If08t#Rq+K#s{ zb}mq^_${jVjmeHhTXNWUoFMIe)lJ26`vXz zWvk~HR@whs?OF8cKV8YyEs1et|A`i*;GS`_+RH=ns17TKJg|lJv;Y(H<+2}hIXsat z5ANw;3-!HT?J@e?t>VkCV$sSaXTfoVh-!;h=kN@TPi^X~Dlo@yIP4fl2 z#pt2|1Jj>Ov$71^ei~h1H$uM|R6wY=ZG3Q99U>X|mV`BoS9`4vYw~J@(FazM_8hI9o-&aIo@yE| z6xi92RAt7!kM;6HVQV)mjXu!6Snn}L!YlYRm7CF)XL~-WsBd9Uk6GUDFm8S4@oR}s z!f_@&&0G2FHTy?nQd8F&@&}*SrC)xRgU!h6eepUXk}}=;?q@wX1aZ#AJc}avS@*XR MKo6o-Qerdz3wwRZj{pDw literal 0 HcmV?d00001 diff --git a/code/assets/sunglasses.svg b/code/assets/sunglasses.svg new file mode 100644 index 00000000..a1fcd7e8 --- /dev/null +++ b/code/assets/sunglasses.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/index.html b/code/index.html index 2507e946..9add35d2 100644 --- a/code/index.html +++ b/code/index.html @@ -5,18 +5,25 @@ Project GitHub Tracker + -

    GitHub Tracker

    -
    -
    -
    -
    +
    +

    GitHub Tracker

    + +
    + +
    +
    +
    +
    +
    Footer
    + diff --git a/code/script.js b/code/script.js index ed704941..ed8ba56d 100644 --- a/code/script.js +++ b/code/script.js @@ -1,61 +1,127 @@ const userSection = document.getElementById("user"); const projectSection = document.getElementById("projects"); -const API_USER_INFO = "https://api.github.com/users/jessand77"; -const API_REPOS = "https://api.github.com/users/jessand77/repos"; +const username = 'jessand77'; +const API_USER_INFO = `https://api.github.com/users/${username}`; +const API_REPOS = `${API_USER_INFO}/repos`; + +// const hardCodeApi = "https://api.github.com/users/jessand77/repos"; + // Läs lite här: https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-fetch-api-to-get-data +const getPullRequests = (repos) => { + repos.forEach(repo => { + // const repoName = repo.name; + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`) + .then(res => res.json()) + .then(pullRequests => { + + const myPullRequests = pullRequests + .filter(pullRequest => pullRequest.user.login === username); + + myPullRequests.forEach(myPullRequest => { + // console.log(myPullRequest.commits_url); + getPRCommits(myPullRequest.commits_url, repo.name); + getPRComments(myPullRequest.review_comments_url, repo.name); + }) + }) + }) +} + +const getPRCommits = (pullRequestCommitsUrl, repoName) => { + fetch(pullRequestCommitsUrl) + .then(res => res.json()) + .then(commits => { + + // console.log(commits) + // Print number of commits + // console.log(`Number of commits: ${commits.length}`) + + let commitSpan = document.createElement('span'); + + commitSpan.innerHTML = `${commits.length}`; + + document.getElementById(repoName).appendChild(commitSpan); + + // // Print commit messages + // commits.forEach(commit => console.log(commit.commit.message)) + // // + + }) +} + +const getPRComments = (pullRequestCommentsUrl, repoName) => { + fetch(pullRequestCommentsUrl) + .then(res => res.json()) + .then(comments => { + console.log(`The comments for ${repoName} are: `) + comments.forEach(comment => console.log(comment.body)); + //Printa kommentarerna på något sätt på sidan + }) +} + +const formatDate = (dateToFormat) => { + const year = dateToFormat.getFullYear(); + const month = dateToFormat.getMonth() + 1; + const day = dateToFormat.getDate(); + const formattedDate = `${year}-${month}-${day}`; + return formattedDate; +} + const fetchUserInfo = () => { - fetch(API_USER_INFO) - .then((response) => response.json()) - .then((user) => { + fetch(API_USER_INFO, options) + .then(res => res.json()) + .then(user => { console.log(user) - userSection.innerHTML = '

    User infoUser name: ${user.login}

    ` - userSection.innerHTML += `profile picture` + userSection.innerHTML = ` +

    User info

    User name: ${user.login}

    +

    Full name: ${user.name}

    + profile picture + ` }) + //Fungerar det här överhuvudtaget? .catch(err => console.error(err)); } const fetchRepos = () => { - fetch(API_REPOS) - // we ask for the response from the API - .then((response) => response.json()) - // we say what we want to be done with the response - .then((repos) => { - console.log(repos); - - /* - projectSection.innerHTML = '

    Projects

    ' - let htmlAllRepos = '

    All my projects

      ' - repos.forEach((repo) => { - htmlAllRepos += `
    • ${repo.name}
    • ` - }); - htmlAllRepos += '
    ' - projectSection.innerHTML += htmlAllRepos + fetch(API_REPOS, options) + // we ask for the res from the API + .then(res => res.json()) + // we say what we want to be done with the res + .then(repos => { + //console.log(repos); + + // projectSection.innerHTML = '

    Projects

    ' + // let htmlAllRepos = '

    All my projects

      ' + // repos.forEach((repo) => { + // htmlAllRepos += `
    • ${repo.name}
    • ` + // }); + // htmlAllRepos += '
    ' + // projectSection.innerHTML += htmlAllRepos - // Returns an array of the forked repos - const forkedRepos = repos - .filter((repo) => repo.fork === true) - .map((repo) => repo.name); - console.log(forkedRepos); + // // Returns an array of the forked repos + // const forkedRepos = repos + // .filter((repo) => repo.fork === true) + // .map((repo) => repo.name); - let htmlForkedRepos = '

    All forked repos

      '; - forkedRepos.forEach((repo) => { - htmlForkedRepos += `
    • ${repo}
    • ` - }); - htmlForkedRepos += '
    '; + // console.log(forkedRepos); - console.log('Forked repos: ' + htmlForkedRepos) + // let htmlForkedRepos = '

    All forked repos

      '; + // forkedRepos.forEach((repo) => { + // htmlForkedRepos += `
    • ${repo}
    • ` + // }); + // htmlForkedRepos += '
    '; - projectSection.innerHTML += htmlForkedRepos - */ + // console.log('Forked repos: ' + htmlForkedRepos) + // projectSection.innerHTML += htmlForkedRepos + // Returns an array of the forked repos from Technigo // const reposStartingWithFilter = repos @@ -74,41 +140,37 @@ const fetchRepos = () => { // ` // }); - const getCommits = (repoName) => { - fetch('https://api.github.com/repos/jessand77/' + repoName + '/commits') - .then(res => res.json()) - .then((commits) => { - console.log(commits); - const numberOfCommits = commits.map(item => item.commit).length; - console.log(repoName + ' has ' + numberOfCommits + ' commits.'); - let commitSpan = document.createElement('span'); - commitSpan.innerHTML = `${numberOfCommits}` - document.getElementById(repoName).appendChild(commitSpan); - - }) - } - - let htmlTechnigoRepos = '

    Repos forked from Technigo

    '; + projectSection.innerHTML = ` +

    Repos forked from Technigo

    +
    + `; - const technigoRepos = repos.filter((repo) => repo.name.startsWith("project")); - - console.log(`Number of repos forked from Technigo: ${technigoRepos.length}`); + //The Technigo repos are forked and their names start with project + const technigoRepos = repos + .filter(repo => repo.fork === true) + .filter(repo => repo.name.startsWith("project")); + + getPullRequests(technigoRepos); technigoRepos.forEach((repo) => { - console.log(repo.name) - const commits = 4; - htmlTechnigoRepos += ` -

    ${repo.name}

    -

    Most recent update: ${repo.pushed_at}

    -

    Default branch: ${repo.default_branch}

    -

    URL: ${repo.html_url}

    -

    Number of commits:

    + + const mostRecentPush = new Date(repo.pushed_at); + + // Not necessary because repoGrid is created in projectSection.innerHTML injection above? + // const repoGrid = document.getElementById('repoGrid'); + + repoGrid.innerHTML += ` +
    +

    ${repo.name}

    +

    Most recent update: ${formatDate(mostRecentPush)}

    +

    Default branch: ${repo.default_branch}

    +

    URL: ${repo.html_url}

    +

    Number of commits:

    +
    ` - getCommits(repo.name); + }) - projectSection.innerHTML += htmlTechnigoRepos; - }); } diff --git a/code/style.css b/code/style.css index 7c5c7f01..7477637f 100644 --- a/code/style.css +++ b/code/style.css @@ -1,31 +1,100 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap'); + * { box-sizing: border-box; + margin: 0; + padding: 0; } html { - background-color: #FFECE9; - background-image: linear-gradient(135deg, lightgreen, violet); + background-color: grey; + font-size: 16px; + font-family: 'Nunito', sans-serif; } body { background-color: white; - width: 80%; + background-image: linear-gradient(135deg, lightgreen, violet); + width: 90%; margin: 10px auto; - padding: 20px; } h1 { text-align: center; } -img { +.header { + display: flex; + justify-content: center; + align-items: center; + background-color: violet; +} + +.logo { + height: 50px; + width: auto; + margin: 2rem; +} + +.main { + display: flex; + flex-direction: column; + justify-content: space-around; + align-content: center; + gap: 4rem; + padding: 20px; +} + +.user-section { + border: 1px solid black; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.4rem; +} + +.avatar { height: 200px; width: 200px; border-radius: 50%; + filter: grayscale(100%); } -.flex-wrapper { +.project-wrapper { display: flex; - justify-content: space-around; - align-content: center; + flex-direction: column; + align-items: center; +} + +.repo-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; +} + +.repo-div { + border: 1px solid black; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); + padding: 10px; + margin: 10px; + transition: 0.2s; /*The delay of the scale change below*/ +} + +.repo-div:hover { + transform: scale(1.1); +} + +.footer { + background-color: lightgreen; + height: 4rem; + display: flex; + justify-content: center; + align-items: center; +} + +@media only screen and (max-width: 992px) { + .repo-grid { + grid-template-columns: 1fr; + } } \ No newline at end of file From 32a3a0c3d2b52f459deef18b2af942f566735450 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Thu, 24 Feb 2022 16:23:26 +0100 Subject: [PATCH 05/21] Added some styling and comment/commit message lists --- code/index.html | 2 +- code/script.js | 212 ++++++++++++++++++++++-------------------------- code/style.css | 51 +++++++++--- 3 files changed, 137 insertions(+), 128 deletions(-) diff --git a/code/index.html b/code/index.html index 9add35d2..bcf28fc1 100644 --- a/code/index.html +++ b/code/index.html @@ -16,7 +16,7 @@

    GitHub Tracker

    -
    +
    diff --git a/code/script.js b/code/script.js index ed8ba56d..bdea41fb 100644 --- a/code/script.js +++ b/code/script.js @@ -5,176 +5,154 @@ const username = 'jessand77'; const API_USER_INFO = `https://api.github.com/users/${username}`; const API_REPOS = `${API_USER_INFO}/repos`; -// const hardCodeApi = "https://api.github.com/users/jessand77/repos"; - - +//Global variable to be used by the chart +let technigoRepos; +// const hardCodeApi = "https://api.github.com/users/jessand77/repos"; // Läs lite här: https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-fetch-api-to-get-data -const getPullRequests = (repos) => { - repos.forEach(repo => { - // const repoName = repo.name; - fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`) - .then(res => res.json()) - .then(pullRequests => { - - const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username); +//Should not be included in git push?? +// const options = { +// method: 'GET', +// headers: { +// Authorization: 'token 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' +// } +// } - myPullRequests.forEach(myPullRequest => { - // console.log(myPullRequest.commits_url); - getPRCommits(myPullRequest.commits_url, repo.name); - getPRComments(myPullRequest.review_comments_url, repo.name); - }) - }) +const fetchUserInfo = () => { + fetch(API_USER_INFO) + .then(res => res.json()) + .then(user => { + // console.log(user) + userSection.innerHTML = ` +

    ${user.name}

    +

    Username: ${user.login}

    + profile picture + ` }) } -const getPRCommits = (pullRequestCommitsUrl, repoName) => { +const getPRCommits = (pullRequestCommitsUrl, reponame) => { fetch(pullRequestCommitsUrl) .then(res => res.json()) .then(commits => { - // console.log(commits) - // Print number of commits - // console.log(`Number of commits: ${commits.length}`) + let commitParagraph = document.getElementById(reponame); + let commitMessageList = document.createElement('ol'); - let commitSpan = document.createElement('span'); - - commitSpan.innerHTML = `${commits.length}`; + commitParagraph.innerHTML = `Number of commits: ${commits.length}`; + commitParagraph.appendChild(commitMessageList); - document.getElementById(repoName).appendChild(commitSpan); - - // // Print commit messages - // commits.forEach(commit => console.log(commit.commit.message)) - // // + commits.forEach(commit => { + // console.log(commit.commit.message); + let listElement = document.createElement('li'); + listElement.innerHTML = commit.commit.message; + commitMessageList.appendChild(listElement) + }) }) } -const getPRComments = (pullRequestCommentsUrl, repoName) => { +// Hur kan jag ta fram bara huvudkommentaren i stället? + +const getPRComments = (pullRequestCommentsUrl, reponame) => { fetch(pullRequestCommentsUrl) .then(res => res.json()) .then(comments => { - console.log(`The comments for ${repoName} are: `) - comments.forEach(comment => console.log(comment.body)); - //Printa kommentarerna på något sätt på sidan + // console.log(comments) + // console.log(`The comments for ${reponame} are: `) + + let commentList = document.createElement('ul'); + let commitParagraph = document.getElementById(reponame); + commitParagraph.appendChild(commentList) + + comments.forEach(comment => { + // console.log(comment.body) + let listElement = document.createElement('li'); + listElement.innerHTML = comment.body; + commentList.appendChild(listElement); + }); + }) } -const formatDate = (dateToFormat) => { - const year = dateToFormat.getFullYear(); - const month = dateToFormat.getMonth() + 1; - const day = dateToFormat.getDate(); - const formattedDate = `${year}-${month}-${day}`; - return formattedDate; -} +const getPullRequests = (repos) => { + repos.forEach(repo => { + // const repoName = repo.name; + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`) + .then(res => res.json()) + .then(pullRequests => { -const fetchUserInfo = () => { - fetch(API_USER_INFO, options) - .then(res => res.json()) - .then(user => { - console.log(user) - userSection.innerHTML = ` -

    User info

    User name: ${user.login}

    -

    Full name: ${user.name}

    - profile picture - ` + const myPullRequests = pullRequests + .filter(pullRequest => pullRequest.user.login === username); + + // console.log(myPullRequests.length) + //If the length is 1 I have done a pull request + //If the length is 0 it is an ongoing project or a group project where I haven't done the pull request + + if (myPullRequests.length === 0) { + document.getElementById(repo.name).innerHTML = `No pull request done by my username`; + document.getElementById(repo.name).className = 'no-pullrequest'; + } + // console.log(myPullRequests) + + myPullRequests.forEach(myPullRequest => { + + // console.log(myPullRequest.review_comments_url); + + getPRCommits(myPullRequest.commits_url, repo.name); + getPRComments(myPullRequest.review_comments_url, repo.name); + }) + }) }) - //Fungerar det här överhuvudtaget? - .catch(err => console.error(err)); } +const getTechnigoRepos = (repos) => { + return repos + .filter(repo => repo.fork === true) + .filter(repo => repo.name.startsWith("project")); +} + + const fetchRepos = () => { - fetch(API_REPOS, options) - // we ask for the res from the API + fetch(API_REPOS) .then(res => res.json()) - // we say what we want to be done with the res .then(repos => { //console.log(repos); - // projectSection.innerHTML = '

    Projects

    ' - // let htmlAllRepos = '

    All my projects

      ' - // repos.forEach((repo) => { - // htmlAllRepos += `
    • ${repo.name}
    • ` - // }); - // htmlAllRepos += '
    ' - // projectSection.innerHTML += htmlAllRepos - - - // // Returns an array of the forked repos - // const forkedRepos = repos - // .filter((repo) => repo.fork === true) - // .map((repo) => repo.name); - - // console.log(forkedRepos); - - // let htmlForkedRepos = '

    All forked repos

      '; - // forkedRepos.forEach((repo) => { - // htmlForkedRepos += `
    • ${repo}
    • ` - // }); - // htmlForkedRepos += '
    '; - - // console.log('Forked repos: ' + htmlForkedRepos) - - // projectSection.innerHTML += htmlForkedRepos - + technigoRepos = getTechnigoRepos(repos) - // Returns an array of the forked repos from Technigo - // const reposStartingWithFilter = repos - // .filter((repo) => repo.name.startsWith("project")) - // .map((repo) => repo.name); - - // console.log(reposStartingWithFilter); - - // let htmlTechnigoRepos = '

    Repos forked from Technigo

    '; - // reposStartingWithFilter.forEach((repo) => { - // htmlTechnigoRepos += ` - //
    - //

    ${repo}

    - //

    ${repo}

    - //

    - // ` - // }); + getPullRequests(technigoRepos); projectSection.innerHTML = ` -

    Repos forked from Technigo

    -
    +

    Technigo projects

    +
    `; - - //The Technigo repos are forked and their names start with project - const technigoRepos = repos - .filter(repo => repo.fork === true) - .filter(repo => repo.name.startsWith("project")); - - getPullRequests(technigoRepos); technigoRepos.forEach((repo) => { - const mostRecentPush = new Date(repo.pushed_at); - - // Not necessary because repoGrid is created in projectSection.innerHTML injection above? - // const repoGrid = document.getElementById('repoGrid'); + const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); - repoGrid.innerHTML += ` + repoContainer.innerHTML += `
    -

    ${repo.name}

    -

    Most recent update: ${formatDate(mostRecentPush)}

    +

    ${repo.name}

    +

    Most recent push: ${mostRecentPush}

    Default branch: ${repo.default_branch}

    -

    URL: ${repo.html_url}

    -

    Number of commits:

    +

    ` + }) }); } + + fetchUserInfo(); fetchRepos(); \ No newline at end of file diff --git a/code/style.css b/code/style.css index 7477637f..7aa0adcc 100644 --- a/code/style.css +++ b/code/style.css @@ -17,12 +17,31 @@ body { background-image: linear-gradient(135deg, lightgreen, violet); width: 90%; margin: 10px auto; + min-width: 290px; } h1 { text-align: center; } +h2 { + font-size: 2rem; + margin-bottom: 2rem; +} + +h4 { + font-size: 1.5rem; +} + +ul { + list-style-type: none; +} + +ol { + font-size: xx-small; + margin-top: 2rem; +} + .header { display: flex; justify-content: center; @@ -46,7 +65,6 @@ h1 { } .user-section { - border: 1px solid black; padding: 1rem; display: flex; flex-direction: column; @@ -61,23 +79,26 @@ h1 { filter: grayscale(100%); } -.project-wrapper { +.project-section { display: flex; flex-direction: column; - align-items: center; + align-items: stretch; + text-align: center; } -.repo-grid { - display: grid; - grid-template-columns: 1fr 1fr; +.repo-container { + display: flex; + flex-wrap: wrap; + justify-content: center; gap: 2rem; } .repo-div { + flex: 25%; border: 1px solid black; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); - padding: 10px; - margin: 10px; + padding: 2.5rem; + margin: 0.5rem; transition: 0.2s; /*The delay of the scale change below*/ } @@ -85,6 +106,11 @@ h1 { transform: scale(1.1); } +.no-pullrequest { + color: blue; + font-style: italic; +} + .footer { background-color: lightgreen; height: 4rem; @@ -94,7 +120,12 @@ h1 { } @media only screen and (max-width: 992px) { - .repo-grid { - grid-template-columns: 1fr; + .repo-container { + flex-direction: column; + flex-wrap: nowrap; + } + + .repo-div { + flex: 100%; } } \ No newline at end of file From 7db2bec66f3320ec3f09c82bbc270f283cdffa79 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 25 Feb 2022 09:16:50 +0100 Subject: [PATCH 06/21] Added gitignore --- .gitignore | 1 + code/index.html | 1 + code/script.js | 61 ++++++++++++++++++++++++++++--------------------- 3 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..143f9792 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +code/secret.js diff --git a/code/index.html b/code/index.html index bcf28fc1..d3fc1173 100644 --- a/code/index.html +++ b/code/index.html @@ -24,6 +24,7 @@

    GitHub Tracker

    Footer
    + diff --git a/code/script.js b/code/script.js index bdea41fb..92e79d25 100644 --- a/code/script.js +++ b/code/script.js @@ -8,20 +8,15 @@ const API_REPOS = `${API_USER_INFO}/repos`; //Global variable to be used by the chart let technigoRepos; -// const hardCodeApi = "https://api.github.com/users/jessand77/repos"; - -// Läs lite här: https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-fetch-api-to-get-data - -//Should not be included in git push?? -// const options = { -// method: 'GET', -// headers: { -// Authorization: 'token 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' -// } -// } +const options = { + method: 'GET', + headers: { + Authorization: 'token' + API_TOKEN + } +} const fetchUserInfo = () => { - fetch(API_USER_INFO) + fetch(API_USER_INFO, options) .then(res => res.json()) .then(user => { // console.log(user) @@ -34,14 +29,16 @@ const fetchUserInfo = () => { } const getPRCommits = (pullRequestCommitsUrl, reponame) => { - fetch(pullRequestCommitsUrl) + fetch(pullRequestCommitsUrl, options) .then(res => res.json()) .then(commits => { - let commitParagraph = document.getElementById(reponame); + let repoDiv = document.getElementById(reponame); + let commitParagraph = document.createElement('p') let commitMessageList = document.createElement('ol'); commitParagraph.innerHTML = `Number of commits: ${commits.length}`; + repoDiv.appendChild(commitParagraph) commitParagraph.appendChild(commitMessageList); commits.forEach(commit => { @@ -57,10 +54,10 @@ const getPRCommits = (pullRequestCommitsUrl, reponame) => { // Hur kan jag ta fram bara huvudkommentaren i stället? const getPRComments = (pullRequestCommentsUrl, reponame) => { - fetch(pullRequestCommentsUrl) + fetch(pullRequestCommentsUrl, options) .then(res => res.json()) .then(comments => { - // console.log(comments) + console.log(comments) // console.log(`The comments for ${reponame} are: `) let commentList = document.createElement('ul'); @@ -70,6 +67,7 @@ const getPRComments = (pullRequestCommentsUrl, reponame) => { comments.forEach(comment => { // console.log(comment.body) let listElement = document.createElement('li'); + // listElement.style.display = 'none'; listElement.innerHTML = comment.body; commentList.appendChild(listElement); }); @@ -80,7 +78,7 @@ const getPRComments = (pullRequestCommentsUrl, reponame) => { const getPullRequests = (repos) => { repos.forEach(repo => { // const repoName = repo.name; - fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`) + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`, options) .then(res => res.json()) .then(pullRequests => { @@ -92,15 +90,30 @@ const getPullRequests = (repos) => { //If the length is 0 it is an ongoing project or a group project where I haven't done the pull request if (myPullRequests.length === 0) { - document.getElementById(repo.name).innerHTML = `No pull request done by my username`; - document.getElementById(repo.name).className = 'no-pullrequest'; + + let repoDiv = document.getElementById(repo.name); + let commitParagraph = document.createElement('p') + + commitParagraph.innerHTML = `No pull request done by my username`; + commitParagraph.className = 'no-pullrequest'; + + repoDiv.appendChild(commitParagraph); } + // console.log(myPullRequests) + // Hur får jag bara själva huvudkommentaren? + myPullRequests.forEach(myPullRequest => { - // console.log(myPullRequest.review_comments_url); + const pullNumber = myPullRequest.number; + console.log(pullNumber) + + console.log(myPullRequest.review_comments_url); + // https://api.github.com/repos/Technigo/project-business-site/pulls + //https://api.github.com/repos/Technigo/project-business-site/pulls/comments/289 + getPRCommits(myPullRequest.commits_url, repo.name); getPRComments(myPullRequest.review_comments_url, repo.name); }) @@ -116,7 +129,7 @@ const getTechnigoRepos = (repos) => { const fetchRepos = () => { - fetch(API_REPOS) + fetch(API_REPOS, options) .then(res => res.json()) .then(repos => { @@ -136,11 +149,10 @@ const fetchRepos = () => { const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); repoContainer.innerHTML += ` -
    +

    ${repo.name}

    Most recent push: ${mostRecentPush}

    Default branch: ${repo.default_branch}

    -

    ` @@ -150,9 +162,6 @@ const fetchRepos = () => { }); } - - - fetchUserInfo(); fetchRepos(); \ No newline at end of file From 65bf85229588f31e169c3678eab2a21d39c0c724 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 25 Feb 2022 13:57:45 +0100 Subject: [PATCH 07/21] Added some more styling --- code/assets/magnifying-glass.png | Bin 0 -> 38256 bytes code/index.html | 2 +- code/script.js | 85 +++++++++++++++++-------------- code/style.css | 24 ++++++++- 4 files changed, 71 insertions(+), 40 deletions(-) create mode 100644 code/assets/magnifying-glass.png diff --git a/code/assets/magnifying-glass.png b/code/assets/magnifying-glass.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa859c0653fcd56fa219e4d36abb1bb022eb2b7 GIT binary patch literal 38256 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 Project GitHub Tracker - + diff --git a/code/script.js b/code/script.js index 92e79d25..8d13df65 100644 --- a/code/script.js +++ b/code/script.js @@ -36,10 +36,11 @@ const getPRCommits = (pullRequestCommitsUrl, reponame) => { let repoDiv = document.getElementById(reponame); let commitParagraph = document.createElement('p') let commitMessageList = document.createElement('ol'); + commitMessageList.className = 'message-list'; commitParagraph.innerHTML = `Number of commits: ${commits.length}`; repoDiv.appendChild(commitParagraph) - commitParagraph.appendChild(commitMessageList); + repoDiv.appendChild(commitMessageList); commits.forEach(commit => { // console.log(commit.commit.message); @@ -51,33 +52,51 @@ const getPRCommits = (pullRequestCommitsUrl, reponame) => { }) } -// Hur kan jag ta fram bara huvudkommentaren i stället? - -const getPRComments = (pullRequestCommentsUrl, reponame) => { - fetch(pullRequestCommentsUrl, options) +const getReviewComment = (myPullRequestUrl, reponame) => { + fetch(`${myPullRequestUrl}/reviews`) .then(res => res.json()) - .then(comments => { - console.log(comments) - // console.log(`The comments for ${reponame} are: `) + .then(json => { + + let repoDiv = document.getElementById(reponame); + let reviewCommentParagraph = document.createElement('p'); - let commentList = document.createElement('ul'); - let commitParagraph = document.getElementById(reponame); - commitParagraph.appendChild(commentList) + reviewCommentParagraph.className = 'review-comment'; - comments.forEach(comment => { - // console.log(comment.body) - let listElement = document.createElement('li'); - // listElement.style.display = 'none'; - listElement.innerHTML = comment.body; - commentList.appendChild(listElement); - }); + repoDiv.appendChild(reviewCommentParagraph); + json.forEach(item => { + reviewCommentParagraph.innerHTML = item.body; + }) }) } +// ------ This function shows the detailed comments --------- + +// const getPRComments = (pullRequestCommentsUrl, reponame) => { +// fetch(pullRequestCommentsUrl, options) +// .then(res => res.json()) +// .then(comments => { +// console.log(comments) +// // console.log(`The comments for ${reponame} are: `) + +// let commentList = document.createElement('ul'); +// let commitParagraph = document.getElementById(reponame); +// commitParagraph.appendChild(commentList) + +// comments.forEach(comment => { +// // console.log(comment.body) +// let listElement = document.createElement('li'); +// // listElement.style.display = 'none'; +// listElement.innerHTML = comment.body; +// commentList.appendChild(listElement); +// }); + +// }) +// } + const getPullRequests = (repos) => { repos.forEach(repo => { - // const repoName = repo.name; + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`, options) .then(res => res.json()) .then(pullRequests => { @@ -85,46 +104,38 @@ const getPullRequests = (repos) => { const myPullRequests = pullRequests .filter(pullRequest => pullRequest.user.login === username); - // console.log(myPullRequests.length) //If the length is 1 I have done a pull request //If the length is 0 it is an ongoing project or a group project where I haven't done the pull request - if (myPullRequests.length === 0) { let repoDiv = document.getElementById(repo.name); let commitParagraph = document.createElement('p') - commitParagraph.innerHTML = `No pull request done by my username`; + commitParagraph.innerHTML = `Either ongoing or group/pair project where I didn't make the pull request`; commitParagraph.className = 'no-pullrequest'; repoDiv.appendChild(commitParagraph); } - - // console.log(myPullRequests) - - // Hur får jag bara själva huvudkommentaren? myPullRequests.forEach(myPullRequest => { - const pullNumber = myPullRequest.number; - console.log(pullNumber) - - console.log(myPullRequest.review_comments_url); - // https://api.github.com/repos/Technigo/project-business-site/pulls - - //https://api.github.com/repos/Technigo/project-business-site/pulls/comments/289 + // const pullNumber = myPullRequest.number; + // console.log(pullNumber) + // console.log(myPullRequest.url) + // console.log(myPullRequest.review_comments_url); getPRCommits(myPullRequest.commits_url, repo.name); - getPRComments(myPullRequest.review_comments_url, repo.name); + getReviewComment(myPullRequest.url, repo.name); + // getPRComments(myPullRequest.review_comments_url, repo.name); }) }) }) } +// This function filters out repos that are forked and start with "project" const getTechnigoRepos = (repos) => { return repos - .filter(repo => repo.fork === true) - .filter(repo => repo.name.startsWith("project")); + .filter(repo => repo.fork === true && repo.name.startsWith("project")) } @@ -140,7 +151,7 @@ const fetchRepos = () => { getPullRequests(technigoRepos); projectSection.innerHTML = ` -

    Technigo projects

    +

    My Technigo projects:

    `; diff --git a/code/style.css b/code/style.css index 7aa0adcc..53336e5b 100644 --- a/code/style.css +++ b/code/style.css @@ -42,6 +42,10 @@ ol { margin-top: 2rem; } +a { + color: rgb(63, 60, 60) +} + .header { display: flex; justify-content: center; @@ -95,6 +99,10 @@ ol { .repo-div { flex: 25%; + min-height: 13rem; + display: flex; + flex-direction: column; + justify-content: space-between; border: 1px solid black; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); padding: 2.5rem; @@ -103,14 +111,26 @@ ol { } .repo-div:hover { - transform: scale(1.1); + transform: scale(1.05); +} + +/* Where does this div inside .repo-div come from? */ +.repo-div div { + display: none; } .no-pullrequest { - color: blue; font-style: italic; } +.message-list { + display: none; +} + +.review-comment { + display: none; +} + .footer { background-color: lightgreen; height: 4rem; From 31a4dd8735f70eb86628b0e6d2cc520042a30b74 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 25 Feb 2022 14:20:44 +0100 Subject: [PATCH 08/21] Tried to fix token --- code/script.js | 2 +- code/style.css | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/script.js b/code/script.js index 8d13df65..e199a5da 100644 --- a/code/script.js +++ b/code/script.js @@ -11,7 +11,7 @@ let technigoRepos; const options = { method: 'GET', headers: { - Authorization: 'token' + API_TOKEN + Authorization: 'token ' + API_TOKEN } } diff --git a/code/style.css b/code/style.css index 53336e5b..26055409 100644 --- a/code/style.css +++ b/code/style.css @@ -121,6 +121,7 @@ a { .no-pullrequest { font-style: italic; + font-size: small; } .message-list { From 39db693c1c66465cde0015e901e641115f4ec99b Mon Sep 17 00:00:00 2001 From: Jessica Sandler <46941395+jessand77@users.noreply.github.com> Date: Fri, 25 Feb 2022 14:56:58 +0100 Subject: [PATCH 09/21] Update index.html --- code/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/index.html b/code/index.html index 1b498260..e3d6bf55 100644 --- a/code/index.html +++ b/code/index.html @@ -24,8 +24,8 @@

    GitHub Tracker

    Footer
    - + - \ No newline at end of file + From 46d7642216c11c983fc70c28859401cac2d120bf Mon Sep 17 00:00:00 2001 From: Jessica Sandler <46941395+jessand77@users.noreply.github.com> Date: Fri, 25 Feb 2022 14:59:41 +0100 Subject: [PATCH 10/21] Update index.html --- code/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/index.html b/code/index.html index e3d6bf55..c0c5404f 100644 --- a/code/index.html +++ b/code/index.html @@ -24,7 +24,7 @@

    GitHub Tracker

    Footer
    - + From be9ad4b0d30475ba03a9a39dfa77e2b816193e3e Mon Sep 17 00:00:00 2001 From: Jessica Sandler <46941395+jessand77@users.noreply.github.com> Date: Fri, 25 Feb 2022 15:13:08 +0100 Subject: [PATCH 11/21] Update index.html --- code/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/index.html b/code/index.html index c0c5404f..f0004bf1 100644 --- a/code/index.html +++ b/code/index.html @@ -24,8 +24,9 @@

    GitHub Tracker

    Footer
    + - + From 51da6efbb605cfb882cfe1c2881b7d8afadbbc20 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 25 Feb 2022 15:14:17 +0100 Subject: [PATCH 12/21] Added chart trial --- code/chart.js | 25 +++++++++++++++++++++++++ code/index.html | 12 +++++++++--- code/style.css | 4 ++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/code/chart.js b/code/chart.js index 92e85a30..5618263e 100644 --- a/code/chart.js +++ b/code/chart.js @@ -2,3 +2,28 @@ const ctx = document.getElementById('chart').getContext('2d') //"Draw" the chart here 👇 +const labels = [ + 'Done', + 'Left', + ]; + + const data = { + labels: labels, + datasets: [{ + label: 'My First dataset', + backgroundColor: ['rgb(255, 99, 132)', 'rgb(130, 99, 132)'], + borderColor: 'rgb(255, 99, 132)', + data: [6, 19], + }] + }; + + const config = { + type: 'doughnut', + data: data, + options: {} + }; + + const myChart = new Chart( + document.getElementById('chart'), + config + ); \ No newline at end of file diff --git a/code/index.html b/code/index.html index 1b498260..2b052b2a 100644 --- a/code/index.html +++ b/code/index.html @@ -4,7 +4,12 @@ + Project GitHub Tracker + + + + @@ -23,9 +28,10 @@

    GitHub Tracker

    Footer
    - - - + + + + \ No newline at end of file diff --git a/code/style.css b/code/style.css index 26055409..37225f4d 100644 --- a/code/style.css +++ b/code/style.css @@ -132,6 +132,10 @@ a { display: none; } +canvas { + width: 50%; +} + .footer { background-color: lightgreen; height: 4rem; From cf1d134c7e589c7032577bf7b40252235cbc058e Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 25 Feb 2022 18:03:48 +0100 Subject: [PATCH 13/21] Added buttons --- .gitignore | 24 +++++++++++++++++++++++- code/chart.js | 49 +++++++++++++++++++++++++++---------------------- code/index.html | 7 +++++-- code/script.js | 24 +++++++++++++++++------- code/style.css | 3 ++- 5 files changed, 74 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 143f9792..2fd51f55 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,23 @@ -code/secret.js +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files + +# Ignore Mac system files +.DS_store + +# Ignore node_modules folder +node_modules + +# Ignore all text files +*.txt + +# Ignore files related to API keys +.env + +# misc +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# other +code/secret.js \ No newline at end of file diff --git a/code/chart.js b/code/chart.js index 5618263e..0980b7be 100644 --- a/code/chart.js +++ b/code/chart.js @@ -2,28 +2,33 @@ const ctx = document.getElementById('chart').getContext('2d') //"Draw" the chart here 👇 -const labels = [ - 'Done', - 'Left', - ]; +const drawChart = (amount) => { - const data = { - labels: labels, - datasets: [{ - label: 'My First dataset', - backgroundColor: ['rgb(255, 99, 132)', 'rgb(130, 99, 132)'], - borderColor: 'rgb(255, 99, 132)', - data: [6, 19], - }] - }; + const labels = [ + 'Done or ongoing projects', + 'Projects left to do', + ]; + + const data = { + labels: labels, + datasets: [{ + label: 'My First dataset', + backgroundColor: ['rgb(144, 238, 144)', 'rgb(238, 130, 238)'], + borderColor: ['rgb(144, 238, 144)', 'rgb(238, 130, 238)'], + data: [amount, 19-amount], + }] + }; + + const config = { + type: 'doughnut', + data: data, + options: {} + }; + + new Chart( + ctx, + config + ); +} - const config = { - type: 'doughnut', - data: data, - options: {} - }; - const myChart = new Chart( - document.getElementById('chart'), - config - ); \ No newline at end of file diff --git a/code/index.html b/code/index.html index 8718e1b8..e495168c 100644 --- a/code/index.html +++ b/code/index.html @@ -22,10 +22,13 @@

    GitHub Tracker

    + +
    + +
    - - +
    Footer
    diff --git a/code/script.js b/code/script.js index e199a5da..1d97f198 100644 --- a/code/script.js +++ b/code/script.js @@ -5,9 +5,6 @@ const username = 'jessand77'; const API_USER_INFO = `https://api.github.com/users/${username}`; const API_REPOS = `${API_USER_INFO}/repos`; -//Global variable to be used by the chart -let technigoRepos; - const options = { method: 'GET', headers: { @@ -34,14 +31,18 @@ const getPRCommits = (pullRequestCommitsUrl, reponame) => { .then(commits => { let repoDiv = document.getElementById(reponame); - let commitParagraph = document.createElement('p') + let commitParagraph = document.createElement('p'); + let showCommitsButton = document.createElement('button'); let commitMessageList = document.createElement('ol'); commitMessageList.className = 'message-list'; commitParagraph.innerHTML = `Number of commits: ${commits.length}`; - repoDiv.appendChild(commitParagraph) - repoDiv.appendChild(commitMessageList); + showCommitsButton.innerHTML = 'Show commit messages'; + repoDiv.appendChild(commitParagraph); + repoDiv.appendChild(showCommitsButton); + repoDiv.appendChild(commitMessageList); + commits.forEach(commit => { // console.log(commit.commit.message); let listElement = document.createElement('li'); @@ -49,6 +50,10 @@ const getPRCommits = (pullRequestCommitsUrl, reponame) => { commitMessageList.appendChild(listElement) }) + // const showCommits = () => commitMessageList.style.display = 'block'; + const showCommits = () => repoDiv.innerHTML = 'Show messages here' + + showCommitsButton.addEventListener('click', showCommits) }) } @@ -146,7 +151,7 @@ const fetchRepos = () => { //console.log(repos); - technigoRepos = getTechnigoRepos(repos) + const technigoRepos = getTechnigoRepos(repos) getPullRequests(technigoRepos); @@ -155,6 +160,10 @@ const fetchRepos = () => {
    `; + // Get the number of forked Technigo projects and draw the chart + const numberOfTechnigoRepos = technigoRepos.length; + drawChart(numberOfTechnigoRepos); + technigoRepos.forEach((repo) => { const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); @@ -173,6 +182,7 @@ const fetchRepos = () => { }); } + fetchUserInfo(); fetchRepos(); \ No newline at end of file diff --git a/code/style.css b/code/style.css index 37225f4d..1f1240da 100644 --- a/code/style.css +++ b/code/style.css @@ -132,8 +132,9 @@ a { display: none; } -canvas { +.canvas-section { width: 50%; + margin: 0 auto; } .footer { From d43b3e6c4e6ef4f807f6cb211e9963513b37a3c1 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sat, 26 Feb 2022 14:23:22 +0100 Subject: [PATCH 14/21] Updated getCommits function and changed colors --- code/chart.js | 4 +- code/index.html | 3 +- code/script.js | 105 ++++++++++++++++-------------------------------- code/style.css | 47 +++++++++++++++------- 4 files changed, 70 insertions(+), 89 deletions(-) diff --git a/code/chart.js b/code/chart.js index 0980b7be..ffa9a6d0 100644 --- a/code/chart.js +++ b/code/chart.js @@ -13,8 +13,8 @@ const drawChart = (amount) => { labels: labels, datasets: [{ label: 'My First dataset', - backgroundColor: ['rgb(144, 238, 144)', 'rgb(238, 130, 238)'], - borderColor: ['rgb(144, 238, 144)', 'rgb(238, 130, 238)'], + backgroundColor: ['#4D724D', '#8DB48E'], + borderColor: ['#4D724D', '#8DB48E'], data: [amount, 19-amount], }] }; diff --git a/code/index.html b/code/index.html index e495168c..304b067b 100644 --- a/code/index.html +++ b/code/index.html @@ -10,13 +10,12 @@ -

    GitHub Tracker

    - +
    diff --git a/code/script.js b/code/script.js index 1d97f198..694fc498 100644 --- a/code/script.js +++ b/code/script.js @@ -16,86 +16,59 @@ const fetchUserInfo = () => { fetch(API_USER_INFO, options) .then(res => res.json()) .then(user => { - // console.log(user) userSection.innerHTML = ` -

    ${user.name}

    +

    ${user.name}

    Username: ${user.login}

    profile picture - ` + `; }) } -const getPRCommits = (pullRequestCommitsUrl, reponame) => { +const getCommits = (pullRequestCommitsUrl, reponame) => { fetch(pullRequestCommitsUrl, options) .then(res => res.json()) .then(commits => { let repoDiv = document.getElementById(reponame); - let commitParagraph = document.createElement('p'); - let showCommitsButton = document.createElement('button'); - let commitMessageList = document.createElement('ol'); - commitMessageList.className = 'message-list'; + let commitParagraph = document.createElement('p'); commitParagraph.innerHTML = `Number of commits: ${commits.length}`; - showCommitsButton.innerHTML = 'Show commit messages'; - repoDiv.appendChild(commitParagraph); - repoDiv.appendChild(showCommitsButton); - repoDiv.appendChild(commitMessageList); + let commitMessageList = document.createElement('ol'); + // commitMessageList.className = 'message-list'; + commits.forEach(commit => { - // console.log(commit.commit.message); - let listElement = document.createElement('li'); - listElement.innerHTML = commit.commit.message; - commitMessageList.appendChild(listElement) + let commitMessage = document.createElement('li'); + commitMessage.innerHTML = commit.commit.message; + commitMessageList.appendChild(commitMessage); }) - // const showCommits = () => commitMessageList.style.display = 'block'; - const showCommits = () => repoDiv.innerHTML = 'Show messages here' - - showCommitsButton.addEventListener('click', showCommits) + let showCommitsButton = document.createElement('button'); + showCommitsButton.className = 'commits-button'; + showCommitsButton.innerHTML = 'Show commits'; + repoDiv.appendChild(showCommitsButton); + + const showCommitMessageList = () => repoDiv.innerHTML = commitMessageList.outerHTML; + showCommitsButton.addEventListener('click', showCommitMessageList); }) } -const getReviewComment = (myPullRequestUrl, reponame) => { - fetch(`${myPullRequestUrl}/reviews`) - .then(res => res.json()) - .then(json => { - - let repoDiv = document.getElementById(reponame); - let reviewCommentParagraph = document.createElement('p'); +// const getReviewComment = (myPullRequestUrl, reponame) => { +// fetch(`${myPullRequestUrl}/reviews`) +// .then(res => res.json()) +// .then(json => { - reviewCommentParagraph.className = 'review-comment'; +// let repoDiv = document.getElementById(reponame); +// let reviewCommentParagraph = document.createElement('p'); - repoDiv.appendChild(reviewCommentParagraph); +// reviewCommentParagraph.className = 'review-comment'; - json.forEach(item => { - reviewCommentParagraph.innerHTML = item.body; - }) - }) -} - -// ------ This function shows the detailed comments --------- - -// const getPRComments = (pullRequestCommentsUrl, reponame) => { -// fetch(pullRequestCommentsUrl, options) -// .then(res => res.json()) -// .then(comments => { -// console.log(comments) -// // console.log(`The comments for ${reponame} are: `) - -// let commentList = document.createElement('ul'); -// let commitParagraph = document.getElementById(reponame); -// commitParagraph.appendChild(commentList) - -// comments.forEach(comment => { -// // console.log(comment.body) -// let listElement = document.createElement('li'); -// // listElement.style.display = 'none'; -// listElement.innerHTML = comment.body; -// commentList.appendChild(listElement); -// }); +// repoDiv.appendChild(reviewCommentParagraph); +// json.forEach(item => { +// reviewCommentParagraph.innerHTML = item.body; +// }) // }) // } @@ -117,21 +90,14 @@ const getPullRequests = (repos) => { let commitParagraph = document.createElement('p') commitParagraph.innerHTML = `Either ongoing or group/pair project where I didn't make the pull request`; - commitParagraph.className = 'no-pullrequest'; + commitParagraph.className = "no-pullrequest"; repoDiv.appendChild(commitParagraph); } myPullRequests.forEach(myPullRequest => { - - // const pullNumber = myPullRequest.number; - // console.log(pullNumber) - // console.log(myPullRequest.url) - // console.log(myPullRequest.review_comments_url); - - getPRCommits(myPullRequest.commits_url, repo.name); - getReviewComment(myPullRequest.url, repo.name); - // getPRComments(myPullRequest.review_comments_url, repo.name); + getCommits(myPullRequest.commits_url, repo.name); + // getReviewComment(myPullRequest.url, repo.name); }) }) }) @@ -143,15 +109,12 @@ const getTechnigoRepos = (repos) => { .filter(repo => repo.fork === true && repo.name.startsWith("project")) } - const fetchRepos = () => { fetch(API_REPOS, options) .then(res => res.json()) .then(repos => { - - //console.log(repos); - const technigoRepos = getTechnigoRepos(repos) + const technigoRepos = getTechnigoRepos(repos); getPullRequests(technigoRepos); @@ -173,7 +136,7 @@ const fetchRepos = () => {

    ${repo.name}

    Most recent push: ${mostRecentPush}

    Default branch: ${repo.default_branch}

    -
    +
    ` @@ -185,4 +148,6 @@ const fetchRepos = () => { fetchUserInfo(); fetchRepos(); + + \ No newline at end of file diff --git a/code/style.css b/code/style.css index 1f1240da..31e3d923 100644 --- a/code/style.css +++ b/code/style.css @@ -1,5 +1,11 @@ @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap'); +:root { + --primary: #F5F5F5; + --secondary: #8DB48E; + --third: #4D724D; +} + * { box-sizing: border-box; margin: 0; @@ -7,17 +13,16 @@ } html { - background-color: grey; + background-color: var(--primary); font-size: 16px; font-family: 'Nunito', sans-serif; } body { - background-color: white; - background-image: linear-gradient(135deg, lightgreen, violet); - width: 90%; - margin: 10px auto; + width: 100%; + margin: 0 auto; min-width: 290px; + color: var(--third); } h1 { @@ -50,11 +55,12 @@ a { display: flex; justify-content: center; align-items: center; - background-color: violet; + color: var(--primary); + background-color: var(--third); } .logo { - height: 50px; + height: 3rem; width: auto; margin: 2rem; } @@ -103,7 +109,7 @@ a { display: flex; flex-direction: column; justify-content: space-between; - border: 1px solid black; + border: 1px solid var(--third); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); padding: 2.5rem; margin: 0.5rem; @@ -114,17 +120,26 @@ a { transform: scale(1.05); } -/* Where does this div inside .repo-div come from? */ -.repo-div div { - display: none; -} - .no-pullrequest { font-style: italic; font-size: small; } -.message-list { +.commits-button { + width: fit-content; + margin: 0 auto; + padding: 0.6rem; + font-weight: 600; + color: var(--primary); + background-color: var(--third); + border: var(--third); +} + +.commits-button:hover { + text-decoration: underline; +} + +.commit-message-div { display: none; } @@ -138,11 +153,13 @@ a { } .footer { - background-color: lightgreen; + background-color: var(--third); + color: var(--primary); height: 4rem; display: flex; justify-content: center; align-items: center; + margin-top: 2rem; } @media only screen and (max-width: 992px) { From 878caa9a601532281ee0eaac79727ff8adf9e177 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sun, 27 Feb 2022 19:47:34 +0100 Subject: [PATCH 15/21] Added pull requests for pair and group projects --- code/script.js | 76 ++++++++++++++++++++++++++------------------------ code/style.css | 33 ++++++++-------------- 2 files changed, 51 insertions(+), 58 deletions(-) diff --git a/code/script.js b/code/script.js index 694fc498..2e29b50c 100644 --- a/code/script.js +++ b/code/script.js @@ -29,14 +29,17 @@ const getCommits = (pullRequestCommitsUrl, reponame) => { .then(res => res.json()) .then(commits => { - let repoDiv = document.getElementById(reponame); + let repoDiv = document.getElementById(`${reponame}-div`); + console.log(repoDiv); + let repoDivContent = document.getElementById(`${reponame}-div-content`); + console.log(repoDivContent); let commitParagraph = document.createElement('p'); commitParagraph.innerHTML = `Number of commits: ${commits.length}`; - repoDiv.appendChild(commitParagraph); + repoDivContent.appendChild(commitParagraph); let commitMessageList = document.createElement('ol'); - // commitMessageList.className = 'message-list'; + commitMessageList.className = 'message-list'; commits.forEach(commit => { let commitMessage = document.createElement('li'); @@ -47,57 +50,54 @@ const getCommits = (pullRequestCommitsUrl, reponame) => { let showCommitsButton = document.createElement('button'); showCommitsButton.className = 'commits-button'; showCommitsButton.innerHTML = 'Show commits'; - repoDiv.appendChild(showCommitsButton); + repoDivContent.appendChild(showCommitsButton); - const showCommitMessageList = () => repoDiv.innerHTML = commitMessageList.outerHTML; + const hideCommits = () => { + userSection.style.backgroundColor = 'brown'; + } + + const showCommitMessageList = () => { + repoDivContent.innerHTML = commitMessageList.outerHTML; + let knapp = document.createElement('button'); + knapp.innerHTML = 'en knapp'; + repoDivContent.appendChild(knapp); + knapp.addEventListener('click', hideCommits); + } + showCommitsButton.addEventListener('click', showCommitMessageList); + }) } -// const getReviewComment = (myPullRequestUrl, reponame) => { -// fetch(`${myPullRequestUrl}/reviews`) -// .then(res => res.json()) -// .then(json => { - -// let repoDiv = document.getElementById(reponame); -// let reviewCommentParagraph = document.createElement('p'); - -// reviewCommentParagraph.className = 'review-comment'; - -// repoDiv.appendChild(reviewCommentParagraph); - -// json.forEach(item => { -// reviewCommentParagraph.innerHTML = item.body; -// }) -// }) -// } - const getPullRequests = (repos) => { repos.forEach(repo => { - fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls`, options) + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`, options) .then(res => res.json()) .then(pullRequests => { + // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? + const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; + const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; + const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username); + .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor) //If the length is 1 I have done a pull request //If the length is 0 it is an ongoing project or a group project where I haven't done the pull request if (myPullRequests.length === 0) { - let repoDiv = document.getElementById(repo.name); + let repoDivContent = document.getElementById(`${repo.name}-div-content`); let commitParagraph = document.createElement('p') - commitParagraph.innerHTML = `Either ongoing or group/pair project where I didn't make the pull request`; + commitParagraph.innerHTML = "No pull request found"; commitParagraph.className = "no-pullrequest"; - repoDiv.appendChild(commitParagraph); + repoDivContent.appendChild(commitParagraph); } myPullRequests.forEach(myPullRequest => { getCommits(myPullRequest.commits_url, repo.name); - // getReviewComment(myPullRequest.url, repo.name); }) }) }) @@ -115,6 +115,8 @@ const fetchRepos = () => { .then(repos => { const technigoRepos = getTechnigoRepos(repos); + + console.log(technigoRepos) getPullRequests(technigoRepos); @@ -132,16 +134,16 @@ const fetchRepos = () => { const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); repoContainer.innerHTML += ` -
    -

    ${repo.name}

    -

    Most recent push: ${mostRecentPush}

    -

    Default branch: ${repo.default_branch}

    -
    +
    +
    +

    ${repo.name}

    +

    Most recent push: ${mostRecentPush}

    +

    Default branch: ${repo.default_branch}

    +
    +
    ` - - + }) - }); } diff --git a/code/style.css b/code/style.css index 31e3d923..a12c863d 100644 --- a/code/style.css +++ b/code/style.css @@ -38,13 +38,8 @@ h4 { font-size: 1.5rem; } -ul { - list-style-type: none; -} - ol { - font-size: xx-small; - margin-top: 2rem; + font-size: small; } a { @@ -70,7 +65,7 @@ a { flex-direction: column; justify-content: space-around; align-content: center; - gap: 4rem; + gap: 3rem; padding: 20px; } @@ -92,8 +87,7 @@ a { .project-section { display: flex; flex-direction: column; - align-items: stretch; - text-align: center; + align-items: center; } .repo-container { @@ -106,12 +100,9 @@ a { .repo-div { flex: 25%; min-height: 13rem; - display: flex; - flex-direction: column; - justify-content: space-between; border: 1px solid var(--third); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); - padding: 2.5rem; + padding: 1.5rem; margin: 0.5rem; transition: 0.2s; /*The delay of the scale change below*/ } @@ -120,6 +111,14 @@ a { transform: scale(1.05); } +.repo-div-content { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + gap: 0.3rem; +} + .no-pullrequest { font-style: italic; font-size: small; @@ -139,14 +138,6 @@ a { text-decoration: underline; } -.commit-message-div { - display: none; -} - -.review-comment { - display: none; -} - .canvas-section { width: 50%; margin: 0 auto; From b242b32ff8320bd4882657d7dee0feb93526e531 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sun, 27 Feb 2022 21:53:09 +0100 Subject: [PATCH 16/21] Updated README.md etc --- README.md | 10 +-- code/assets/GitHub-Mark-120px-plus.png | Bin 4268 -> 0 bytes code/assets/GitHub-Mark-32px.png | Bin 1714 -> 0 bytes code/assets/GitHub-Mark-64px.png | Bin 2625 -> 0 bytes code/assets/GitHub-Mark-Light-120px-plus.png | Bin 4044 -> 0 bytes code/assets/GitHub-Mark-Light-32px.png | Bin 1571 -> 0 bytes code/assets/magnifying-glass.png | Bin 38256 -> 0 bytes code/assets/sunglasses.svg | 23 ------- code/index.html | 4 -- code/script.js | 69 ++++++++++--------- code/style.css | 23 +++---- 11 files changed, 49 insertions(+), 80 deletions(-) delete mode 100644 code/assets/GitHub-Mark-120px-plus.png delete mode 100644 code/assets/GitHub-Mark-32px.png delete mode 100644 code/assets/GitHub-Mark-64px.png delete mode 100644 code/assets/GitHub-Mark-Light-120px-plus.png delete mode 100644 code/assets/GitHub-Mark-Light-32px.png delete mode 100644 code/assets/magnifying-glass.png delete mode 100644 code/assets/sunglasses.svg diff --git a/README.md b/README.md index 1613a3b0..c9df4dbb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,7 @@ # GitHub Tracker -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. - -## The problem - -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +The GitHub Tracker displays my repos that are forked from Technigo with info about them fetched using the GitHub API. It also includes a chart that was created using chart.js. ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://jessicas-github-tracker-project.netlify.app diff --git a/code/assets/GitHub-Mark-120px-plus.png b/code/assets/GitHub-Mark-120px-plus.png deleted file mode 100644 index ea6ff545a246caa64074ba809bbc86fcb8589071..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4268 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 XLyRvu{aX3a{{tgEGu={c*U0|?Dtn-9 diff --git a/code/assets/GitHub-Mark-32px.png b/code/assets/GitHub-Mark-32px.png deleted file mode 100644 index 8b25551a97921681334176ee143b41510a117d86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1714 zcmaJ?X;2eq7*4oFu!ne{XxAht2qc?8LXr|_LPCfTpaBK7K$c{I0Ld=NLIOeuC;@2) zZ$K%a)k+m-s0>xHmKxL%0V&0TRzzznhgyqrIC$F)0{WwLXLrBvd*^wc_uSc%h%m9E z{W5z3f#4_!7RvAyFh6!S_*<8qJ%KOIm?#E|L=rJQq=gB5C6WLG5;c?r%V0>EmEH#X z5eSwPRa6WXBMs#$5H%GtW2go-in9p>zW@UYDNNWc^XOXZQ? z1QjEV00I#$3^1wQUJ8&-2UsjB-G|9y(LDhMNN3PM{APL4eYi{(m*ERcUnJa{R+-3^ z34^A6;U^v`8N*O6ji%S@sd{fJqD`XFIUJ5zgTe5^5nj414F(y!G&=H(f)Lgzv?>%+ zAsWD}2qhpH7>|TU`X&W6IxDNuO_vET7|j5oG&&VDr!)hUO8+0KR?nh!m<)a!?|%yG zqOwq!CWCcIhE{<$E|F|@g>nP6FoYr6C<8>D?ID9%&5J(4oSbR1I^byW*g@__U z4QsF&uJSEcFeleM3~ChjEQGbHOjsGDMbyAl(p=Ttv9RaVo8~I#js@@Y9C^_2U})yn zzSHU%6FxuY?d;&65MyR({^lU*3$z$ZllDb(o&<7d;A_`h2U+3~BJ2Hv`{W}KEU801#cv_B|9Cm!ynR{S`AMsSn z;7E=B;mb!wx$L;S>yGXG^6=&WlQn9$s?&L%Y1D8TI^MlKB1DqsEng$>f4=xYWBoPI z_S1p!sJ#d2?YI4kPA{k}Eby?F=f-J9zIc`YDl^pzjVm~9ebE?Hn?t0Nx+la|D0MB; z9)2xv1G>a1|A9kQ>~DV<=X3-4yC&n!m8-3K#P z{X@0zRuQsy$+N ziSCoLJU{Z$nQy4A4Y5UJ07$5FA~qL2%Q+cLaqDU?Lz3?=BC5;Nk6BbTmmceEaM>-Z zi>O&-dSE=%ex;vcvCOk{*JQ5^_4M z4lW7%l9IqY(z7pV(?I@@8=KPFO82)O{VDI18-*d-k$YmI^XiuPs_LuFw<^ZcD}yP5 c*NrbeloN*74g`U%%F6r~k%+>C^#XapzmV0H-2eap diff --git a/code/assets/GitHub-Mark-64px.png b/code/assets/GitHub-Mark-64px.png deleted file mode 100644 index 182a1a3f734fc1b7d712c68b04c29bad9460d6cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2625 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 ZsK8ky_?39l4gAjkwLQ)WTW#Z?@NW_mBhUZ< diff --git a/code/assets/GitHub-Mark-Light-32px.png b/code/assets/GitHub-Mark-Light-32px.png deleted file mode 100644 index 628da97c70890c73e59204f5b140c4e67671e92d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1571 zcmaJ>c~BE~6izDPQq)#Nu*KOf(n^(VHY9;fiINM65``pc+9*v(mL$bwfCjbc%v9V{8r9iX|O%>Nr%pLD2qT{mty}c=LVleeamv znz3SOSm@kP8jThvOOq(56Yzh*fz(booe!uZij=BJC6+_lbvQ~B8nA2>kXdv_RDtRY z`5QXWWEySCe6vbTs^#f?J!WC*{1~RgVx!nJTJjQyO{dRANgx|FnymtGbD9%JmCh9^y)##j7{Dcqfn*1ta$rG89pJF6w-S7Z037$rr|y0;1Onp_ zGFJdT6Q!1C0AdVB0WOmpuV=AgAQ550Tn+-mivTtYPJmz*#75#_n9oV%!#rSOfmAfy zki%C~=fTp1{O#BLpJ|0jj#m6#|LRWit-vq3PE1z9ZqyvET4sX$-Icqy7t z<=aq5ff86AuBZBu6EjJsYWM0uejufWFTwPA7Su}0Bm$7KFb!q{Um_8~A{LUG#1l(l zSehUda@kU8LIRg9fkk2tZ;~ss5~R+mM<==F7hLHpxqLB>>PQS%Vc7b~?q!%T5+h8Q z4G=4Nzyi5WZ?^gkasJ{?Xhm`JC#WG6$1K2jb@=9&D3EgD#3UhGh#*21rJjulVXjCF zvp76q62jt0zzMG5C7DlfMgPl%C^3+~wf|}Lq=}jz|MmIcQjh1Ok6NjD$Em^Iv26D> z8tt_TnM9~^Tt8mflRGPOrrX|HtT3gG4LEuuk{g2Rn}QgJIa?gZo))!!=o_l9bvD%A zZ`aHajl8#~u?!4f7F#*b*->A=R2L)6!>saz?h>#wTXT-I(XmQ zx{84skS>k=i~i`(6k4C7;Zpfx%dCPVjPayMf8pugtGM=~s=Id1l#8MZJ1-73wV#Q3 zR3>v3%}jbQs1f_Z0xo;%=LILlA+nTpKI4ha%xWW}uqHrNao~&T4AY6m`P$_n-6h*g zhoX+e4n%~gl_lhe#s+AMb7d{5WzvYTa%6Q~si@@4{;s(0zU|H&P3fE+t{7X`S#Cj@ zC#vd}^4pcBD*77Ny5=j$h8EL2_t$O38$SQiJ6fPjJMimypr~MB2(&P0aI|h}$64<0 z>_~duqNjaT=DM^6+N{&B_lED;F2wrl?!4Lk*2((x!fmrcsw+=cI^qttuZ9C}-m~5E z-ryYVpL%^xR#&(0YI5hz<(}F7-p)?FPcyJO-zVO>%9ZDXJH8pnY;GJYFDQ>vd#j_* zRrd}L(r=!g+1#nQwsO?kpS`Qq8`NxE+Zy{gf7*_7J*U2V_|NpLo{iasj7VCg_V9&| ShohtYzipXxh2)4xTk~yGx|IyE_hf&fR?X{%c*< zVo`7GnLYE&%rmnIRgja!#vsFhKp@zkK7RNDfgpl!5g}+O;LC;U#4Y&p#6j$n5*qmM zL^BKlKcm}zRCjW?iUG(jZATBO0Z_KPM91Qerjo#SU zo1`8Il0hKPA)h{oD!HZ|EV?+xO-{9~F3a%mqSJ|>WkHub@V`g>L_|cyz_t>>!!EX1J+R)Q(dWUzV z@2l30;RJzfom+=b0`NMpbNm8)?qBL$Otb3@9-LMBzK37)*^cT`qu4jar`0)sLUsH1u2WC9Wz>IpvJ=DBQYJSrBa%{|f|-rl}uyy0e*YZ9^QbXWOT|GgGgJ(Pb_j`s}V!}9>VwG={J!6=KPnR(n-Hx)2?f}}8uuwGo6 z06f)dJ+00=OxwfP(5v?!y*<~r*-jW0NFV7-I^2uDS`9{N9GuI z_75N6mjp!bKR9x&#(WM42tvSnMj@kMiw0@$7DL0jhm&aKjrZShP0Q8a-wSg5%S3(7 z$`gEUR*)v(5#(Sp+yLX5yqq>Ok#jgYAeGCZ*q%5wJUc(DliGwR`r6e+(GiPBfbG$G z*h7G>&s9+$Y-;`Kj$;rPi!Y3Oqnc4?j~*8$|NKo0Ma~)lL%IS?7}r7fduC#9!FoT1 zuziw2FwS@T4YuBBinXp$T8gFG)NItN^}bd{xx)uaRT?&=>BFF3Xx|YLj{v{uQ!X7I<0Fx1m0#kZy64VBe$E^*l5Xb1v=W~Innj{@%YO7VzF+& zfQe#2Xu?{i+N4E1ShwxeyQSlEtP!r%!FBAqqWN5{#7?={)&&KJ;Eu?ZZp#`9FDPcXC`-%c1u1 z8x*AS((=+q4`+16+6~{G28rzqmvwCN9AD?z5*1Oe^Lwkg#(=#fe5Y(XRCaag{DOpu zN;Sy&-Q7rwi7we6OaIK)1&jmPVCa$lZW<|b`a6Hh)Twnx{^sO=WuHTwixqNVuUlaw)iR%>q@)S7olboo>DuusrR ztpYl}0s&Uma zhD%TaFa1<~;uES9o0X1UK&50+~@gi0jF^!XG;p%d1jOQLXdek zI`aPF(&V1QtFpG1dqQqC%PXQjCw0zXkwTD8yRh%tr=glT^ zksc%$rHl4G^s4$*zg_F*eTias=rECiAJC5dOS_W5@PTCeRxj<`o6}`F(=-)PpCIV% zj=FYtbUZG2!Lj#Uob1Kkt=Q)PLnC80pMjUTo@Z33&UEUFUP32ArHgF#t-c743#P=c zlRIr3ACP-5)>&t^p^a7V6T!SkFhGHW%H)&YyIt126X}HbsjZ~Vy-1*C?oqLq8jxj3 zeDPknni?-p)U%-yTtO*Ur9aAxVMS@5C_dtvK?l-|Pzt-9W1jW^1|&t;g*s=>?Yxamt7vrBZj+ z(v@S?Z@+o)hQTgK`MV6z3z4?p*ye=Zg+@@{u>t_BDxBwQLt6<@rX+TH zyp<2X?Fn;3b=jxJeOJAMRHZ`o`LLsax?jbAv2r8f-_dQF#UvW&^6p+CJ;V$KVu%A@ z7tBUrqs-sgjbcwm}EBsKVNQE)LHPfCtbek*)h=j&9h?rIjB~VP^a`LRSzId3VnSZxUPD^2u>Z zBJl(&0md$6W`rcviz`F=c=M^PNt@hppNVFBomPfQMy0Y($C@_u0!*?0IlsH*Zz1Am z7zdJJzHk~^h}h0Ph9|14Www{?M|NwE3p13(b37OVLdKp1+Mv~~7hl;sPaag4;|oXC zV?=}R(t)t|Kp__k2%b-_JqrCLtme*VG^u|m)EDM8FpQSo+sGl_)-y0b|q!Dc0! z9=iMo&Swz({9dY*$ZgJD=7SLClv?xi%h25PfvKps4%M>PHO{&&jKr;;N?;5Atn@|O z7$%lyByg&_JT5j&(}U0zuy`zwYjkVsb1vsr3ya7jSh~Q>#oZbFK269@OThRc!OGRA zhn32sQ|I*Dl8Ss`*mdFi2%9;V>4!yQmV(9KeAt@RbT7I7x(c^g&IeUDvAI73vEfvS zgv3|0PH1@gC6JY&X|67coaH!lg{W|H{zr7VeY@uri+W$KGLv8p z-NBV)=2jGaCJz-4k3g#TWs#cwM2U|G1cc`QVi*XAZ^^k@USV_{6w3&?uf7KEHKHhh zeC8KyXSLkC1pwf~sv|<~D*w_nL*wGVwni$w2~O6h&o)M@{F?@1GKUkKiqz{@OjKB| zlNU94G{yzeob+S;0g@7?{lI-C_I3H~krT9xhZD@X%cgcm)6B;N=axuXP0)dV za0~WfE_qz1f4zISHOHY9LBgQL6Q2GTcEyy+TJy8=2H|jf6J7Cjsv3A*82~8w^n2mU zi`O=JAC?=bjdxmg=!VhVF5)`7mqgZZ%=H}%-FC5)O_X-52q_vdZ)_V_kXiKt23ObpYr`A!o5r7UaOen=p4U9y zNKjqkA#+#&?)9)$QTy2nK~(h5!9t|<1L}CC0}tXiL2vSEqlDqqZfTe0qp4Cn9_DtZ zUnULo-|n8)i+%`^ZX~&W(wQ04_ERsz6-og7p{QtWH8aLLgAcr`P*VVftDwKjMHgBh zEG+UN^h=LHLZQ}>t4yqYRh2ro$t!uR=474ffpb_@w41$nbIzRe@eoP4ire1aK2BZK zC3nkG?{puUFCKi~Zbf-qRJxn~WMEn`f3%HO0FA}T^w`?_`kr>nnw-i z-z@~F?OvF?RG_Oj31^|s3RNeAE$8EKKR*S|6f-Q|Y+cxJXie9SH>~H|?#`Ie4YW{u z2AjHg-I4d%d=9!~Y}ghhXZQMm?RZ}!2#EPF9z4+5cKvH_c5dk3oeI<=Pvbm)c>mh- z`{Qd`?b;r4{jZ*J#q}=3l6>1l#n~5}ANZ>`)x~;qojB&bf{m?P)VCjtBz`EX#puZ>jX8D_im9NWH zh5MuK+N#>ZUm>A9K|a0kSg(g|iN5O8cyTVquPFTB+n?DaxmOUoBq#Yvp+ezS=#t|w zD7xl%t70(D$+*RErQK09@7Wpi?zo~QH#w#Ir9l_L@aGD5*+(VB_C}rcwF!Y2=k1Q9 z`bLQq?zSzxK=!ShT8y^XSxy2$QzxA_@|I;j32WaDlp24p?F9*z+^RncU3Y$!R%nq! zDy-fU2}gL39{$?e4TsdsWVY3grC*@dVQ)o9j%s1BAIXC+*7J8C5sGtTy4(W_+ggQ5 z*n;vzGRc^mbC;es+$m#sgvqW1y-tt6oCkP&sZqA=;W^J0-^YBd_}aX`xt4)pxnk~G z0Nov0Gy4+D;Ef-#E>VL66-!mT)+{D-94E=TlndmN3*VwgMqN6aC&p(cg4f>hHW&=T z;V-Q=FIN4R~uU7P7=s;&-h|A=q8XZHaI-E9?1?p8}DM33C@V#e>Fle?pN{( zh_8Z;(9*La1P`0E;IQuT3`=CRV*K6v!0m%`EPVGY`0D7&nK982dQRJ-@{W<)T;ir7 zl0mnO-7daJze<-6~7A2v%&eS~p6b(Mp-VIiV))*n z5-faiI68nIyI`#8t#V3jj(wF%K!BvX0LvgRCC(2QE0gH~qXV^;@7hHPv0m-9IKLmu znbF~<54C>p%SmFyEITyIPIlGS!|htTom@mlXK+2xzd%APWTo}+QCP3cW*R7MJbC=T z>aPN|%eZSW5-fYA_ftpH^7QgZu)WVVD3~gI_jb8k$y zq8x+mD!^>CfT>I-O-jKwq~JT%`QV@9XVAad8BJfRN5bfpe(DdC7c5uvgkGjAJ*Qpq&J3O}1)roX zxo>VqV`7{Wgtv#kUgE~iG`l0qv1a^LYf>_!a=nq|zdSsyrogaRjVJ(l0IyqpkM+Y) z@7ogIK_!u*K6(W$%x`{yB20=1jo8mRIH^6O7KewGKCS~QAqjTV>&bt`$I;9cO@T)t zmM*tw#_9TUQp4qYa7%EStWZZoa;*A0ucy7vR!|M9p|Zvd`lXw`ZF$0bD;PyagVpo; z+1XsNTqG-BVHxB<-#p2>C;y>%B4Ke8l^YzByX}U55_&jUZgoIqU3!}asw(#!IOEXV zi2Vv1*~N~e0=@>j_gmiUZTAFOis2yj@jiAR<|CrOAjy-JL7Q=h6Sl!S=iabPlk@@2jFk zN!21KCo;wUos6;b3G7tStW{fL?zgx5Gl4v>9(Jl6V6P={&yPJME4^pGO5a6>%Kv;Q zZ!~oqv=z(#%6zD)l{~&{*n1Ype0|OG!&~#K+4AR#ZnujP+?|;_3F$kh-UFM~wRlvC zeHl1MS__*~-wOy3laSqNGvLv~eGKrtSH;4W4dQ>A@mvN0_+8 z=UQp`lx41fw7)V@2Qvq!Vk-v)v43xz5kGfJD>Qq*kG{(JNi_$YC(MJX5Np)2w_E^g!TAQyvsl-eQmh(g>m|D-c!i^)a+F=JfZgv zBb-IFjD2`?FJb=Vyn@wyl@yi7M(-9gy2510hU&QJQA4mp+^%@0 z=Up*Hnmh=SEHdXO42WHIzW;ub?xE~9C@-4c8WGFRyNnGF{EWCb2e?qz8+?BVgZ-gk zOB0H26;X>g9-77&o^R57GY-2%%fmT@nhHOfs#^yk*&p-$QSSw()q6e(7n|V>D@~a| zPrT`71R?QUNY~`gXQi>Q2uoh7^PW4$J&&qTg&vC8+Qd8Sov-%ZXFm#SkJ@%vbH~kB zY!Tmwx&2{XZIn_jluD(cJ;lZP3J-eAd-l#@-wIf0D~vaA%`T@vWxB7Dk`~ebo9S#l z6Q)m^`5xiWzHd$&4MDq13_ir}?K9j3{TCxAk{N~*X(qssua%|Y+cc#_;bfw8WF-UGVIm3~pWed-N+ zB||xf?UR##bd>Pt$i57P2W`K@wMq`UX8g1l1=$b z+HadEG9;_@(|UyzDT>&lVK*#`d~NPI(5R2I#9iP>w!dHl(D*T2ZZRa{G%`D9pW90G z%f=4&ew*$(1v6*EQj_icV$wA#S^N9c z(f9old@G93ltF>O5JtAzu%>zkg=UcG(-hk56tl@V~9FZy%-#UCy7DUAP;P zk1NQ1XZqraXjT^2(Re0E>+%2qe&O%%p0wa@m{sdkYFmez}MY4l)!UR!;G ziZTk_P2A;O(^;`R`0=gMIhI z?HWo`T+hJ7D2xO|5kk64J1@0A-Zt;U0?$^91LGL9r({&f{-wX`Z02#)@6EmJG2l6H zqlJ2LhOccl!*gDjdV9kVCJq<;lQ=eKS{(gG7n$7L>X|ccklvDUy=eJrWMHTK)_UF# z&@yzJefo~(Ui>1CPmcTK`quRp9_uahy3w@4iH+hva3P0e3&jyVEAIci*WU&r-H z9g=_sXXN(2AHMFo2&%iHn5ztxmt6XroIQuz2Y*UP(V?kmeADIF2AUOER?`7h^wqFjY>g+VMbqQ^v;A+$e6CRggV^_~3NAda)!nW!%Rc3g z`}P`_{1odnmRL77G2$@RqmHHy)qV!*xRZ^>%p|l;R8PNsy528m*fe3^%-g7arvkh{ zLg0BfF99g!A;TO79{ON<>*oGzbNJIuCi`hsVTFdm;TerIfU%#Le)d?)QK zhm*WL4w+7Kkn2IdzehsDz(&%#TSof!4LvmEITwGz$j&pd4%+6MOof*ln}+9$1kg(J zy${)To!P%`Y^THuCrT~2O2bsCo^==7v~c0?>90@{_+dz6Kvwq;+Bmd|j3)hO4j(-v z<8)nF5-QB}dcUMG>7I|fDx6Z^doEMY!Cz9aK+2MAFMvhvjFPRpV z&*6e?TQ2vz!HT6zW2>W;G_RR3(;U(mX~XPl$;8ZJy&~%FILQQ1x_CuIJG2-eVf!;e}Zqy1}mV(*?S? z*O{hZK`a)k>IxuiB=_|Yq7`d%Qt5qoTXX^N1 z2!5b1#qo)W_|?Z1y`r*bD7rj|Ed1-MDz~3`!>A3a?#6XJ*~D z-A>fz^dIb^S^7#Avr#FB4GKl;mxS{9D~EA{Mlf_2EPlX7TDG^*O8x%{IvlQv|AyeT6cU#P`e>BZ)JD36fwHq*Mj}jw^)`^b zc0r^iEBlKTH#yJ4J~n?8m!`t?kF>v7AZhLB;S)aT9p>!68gc4t$py777eIzc4=8=9 z{aaA6v-d&|3;~_=n@XOWxC#(!O((NFI*SkXphWDPdrLzvAk8yDUgs?27Dou_P<=pj z97X@GP|vtrJhL*H1^4$g^)iFCe|XRcR8z$n{4s}v z#6R+UmfT}hY9uIAF3CSsr3T@B{`I?doc(Ab3n_wpCSEc4iagw{H+IfFTAO7u97urvP(Du37NMH_&>Qi%R z^XWP6iL+Es8tAIoAvM~6ZN0*9Z&Q9Q3_Vo^MgGi3L85v-J}j&G5TwQ*j_+j=P{=;+ zRzB{@t0yx!FZZ6*+ihq^xIMh1MK9?4H(=-py?V8UgfRVH@4Bwc)V>o!d)hR#Yg_Kt zu0`wvqiR%fyA=ELg08_)eQw#Arvx?nr<&m(ppO@qt{gU(`=*vJpFd{^i8f~W?Hs!$ zu~u+xu!(VWO2k{;X*!{>y6dR-%HgIMB5*2LHpP%qKG zzb7hBTsD1w`5(Pe-^llM$9^`COSFiJHZj%=RpS%nD?*;)%&w{3y!}w--oR8oO??z zybqAqEZpHrf|T@E$EzjYlzc86-5;ACdlyU5=grPXVu0|)veXHlP@HR|yv^pLbLX4h z3MK4NZANn(K_AK0WR(!SipX+YsP!1k6ny9Tvw{fjMdcH-e@trdGJ(g?L`(0c>(o=| zmY91e-EOFOt2Sc1Kh&%7#%he@|Ql``00_it8&&T`-J6kGImvNY-)S~A}u2%RdDS^Qo zCLWN+4uT;33b4qur=^YS-tNL%i!2d^6mD+JnY|YM(6Ui)Kg$` zAzin!Xs~@M|6ebExqd4AV>%c#JKjIoKN?l*c6khXBE1&9$f~8pz*7R{O$)B_+><9s@34ls}N zAyASp<Q}X zgR0@#R7>a)d%KA(O9Zz&@An8`eF_NEPDul;(W7)y9L^nvWrsKLt;OkNcG0^5L`Y$c zWp7_JJyAX9y5iO0R*^?A`*sNlpO4hmP4jDEp2X&Tl}hIx=!e8Nnj6+3%rR=ACo@ki zwSW5<7|S^mr%spt-u}6&b0gCo$1FY&^ZsD&K3FaZPYV~m{MT^v1udk5#1nPl7r{ya zv}fF+&njrlZn$*FhpkeY$sQX^y+^sUCtH|>>5FF5*}47AWp?eg+XB;~h;QMT8to>4?AU#n!Tdwc-Ov~DhK~|wiIVTTcI%#Qrd93y%}O3J zm+9n`i1E?g*`?3d6N}JsnweSp^T~|z|%eh_H-=tfTk!kC2Y&^ zoFNG{?{D7Mbz+ptv!?1bcuUqr8cy5Sp-<3Ab7+pSIx&<=digf>~Ht`T@nu0hunW@3za$oDzg|wH^w(8 zVol|5UU04>BBe~MZB%6Q>&vZ?A+uE$s(_Fz8*i%(ExP9)16_}$lwZw568*PE;chEE z*1TAP5F4*^MGYK^(#$yIsKdGTL@4%pUyX2ciX_nTgynQ{$|1iZ!2WN|t|#O1yl3Zp zO-=;!iEnJRjhghUW00*2AGHTxoBy*TJYm6CXD}E;`0B!3s;7T_uEKrUT|hqSZbC%m zC>1m%dY1CMeokk%rJ{_*Ad0w7x~||%_JC@PmALdbC<{>(8Ph=f5zB0Gq>m2{fZp)L zf|{&vpb9i)rRhEYMpVd?&gLDy0ap3-;T6};X!Pykt-`M+7Zs<}?@llZ&BXhT+u`_AT|b`+~)#6WQTc*1VT0<4A145BaZJM!~+?@lr(W zOo%~4P6&U#`1v4B3&Ll@Se@L1qE5|nma4E0%ss3=VnJ^&e>tE5o0QW49YLq5qMWVr zU#7uYr%U-G zYUaaf?RieUP5QE`)kBkN12DeSz42BPExOXX;&1?2_`J_|sX?C#VQC5*P*o=hs(!u7 zKwJ86DR1MZvB*6!I$T^vdU9$bUyb%k4@; z-C7RE0Oe{_=y2G$mUFM_^~HB>up+pzZ?7f3=rKTn;GmA z`(s6YmY=HzDzxX-dA%tta^+tLvrex+D4UP{7}b?I?-xLh+7hwHNt!eXX0eTD90a3sg03ODc5+;MyjwB{0P7o6oLzCVu4Ps$5b$QjJ)AYVY+}8}*gBHRvI2w%UF79bmvLBl)rJp^Xa{WjqYpIVjw$X`3ti9R|`0 zWzwww9~U@Ul4uf(TV-~HWnQy?;2O##1kVcg~uL_+{TAStzCmU*e&by&QuXNuZ@w(};R_VY= z$c^QpJ3BG}wzGvZr2u{VZYnq|J=ylnveUIT;MEkA2-VdCVUzbPpOM zyYMjq!75v%%hF>yTpwh*r%dc?**1^93bxa=I1|%Ep7SW-=>BHVGWs&>*R^i;C3j=` zlz}ka&!nX+p;`6h2#=myrdm)K)V{m@W1ZwJ^3B{J84*vVFt}$yxNZE{N20&-G-&K~ z+Cmyd28A={wxVM7nv(TYN_(02PAqOSCm_iG4W+-U8Cy249rwOAmGBXYFC3cxT05v3 zUAn`uY3ej+75A~YZ|Rb$zn{$~!56SnvggJMFDjk_zL%RySG=53Zo`)VEi8hDmp`FX zddsX^@Q(?}WlHTY%U{*m5HQ_muv<*c=dt(O98I7!9fGM$HkhZNwkys>Try!ZnlexA z)uYEBc>WN4TyDDMSn>>%Q-aqI!vHEc;^O)8aH%&IVcNWIwwaP^i6B@4E6yHTiFxuQ z*!6d`Mf{L4ZHuwC25v(-W<4eH*LWpsELh$&{^}`t`8j#wGc4E0GIfp)b`oKHrnb+-;8OqbZHfB-j6Z&9AfTGF|+Y&8N`0 zC;_&M>5s%};B!L}#$WK$rayN#<7YR}YRS14QfScC zr_3Y9&kf9!7p(MTN7hJS4~VQM%@!UKG|?+vPiK}6HP!h|f>a_vl-PYpf))5>*xsIq zW{1Pp3YE4)>zT}E#&5}|x;DiV-weJVCm8|!Mnuoz&E1#mQ>B1;niXo!Z*==_vo(C0 z_nkS%hB+eJt@!liU29f1J@G^+eOy3c?FY|XOFa|;=Q&}yjEA2aD;a9T) zd*fezM0OWWSMx*icrCFnKT^`FU?w6wnjeBm(5zy z!o~0+rNKq0kOvh|zcwcK?GIzf7H>WFMT(euZ@W&;Iowihx z@C<7Od;Zjj2fF--z=X*j{jr0P@^O!-i_?Jvtv-GXKg}&9u%%5@sJC^YZNX%X8brzgsSr44?6?khqjeEm!103?Po27#$l!pI%-#i^#w>-f@f# zTXfs1MvHbjz9)1ad@N~WgLb&MPeg480aMF-Zx^N#0T^nMyuZVDsH(UA!(>aZ*Mhzo$*u8}=nID-0 zqE2n6l$z&YJ~th2$WKh!6u6}Pr?$)R{NL^mK?&4%cbz1e-&13=7nX*FefN(?H9ZZh zy@#8mdhww;r^DR|Ov6c}()n|h>B#EnMfdN1jn~P;nP9V^m01sObdw;)Pa*so+%_oK zzn1bR%W=F$<229f%I_-Wxyy_tcf&G=5`6$A!^A=X5L3~*%}Fou$3Gs8#&1GkNKT#L z5~s&()Q6#);OWpyL;S`}YM#~;Vq8x+r*cYl`w?`xOc9?>YU~h3?|M7!)HPkapTitT zkNhOq_70Vx-r?SGVA|?JxYw#Tfk__l9-9^FgViLs?ozG@d9u^3lE;V@pb=VmrrJD@ zvN#E_0KQ$dlPkvZ@}$}0Q}^Uo8ryWK_h8g6V#wpQdQXFe&$i5MN(Hol`uW;6b=&!1 zt%6|IxAx-VMDH!a*B&l0sp+zY{k)*D6sruIPI91E}I2oB9{_R^hU(tR~O|;rRLa zhx;9S=rey(beaWxOBZc?Pd+0J=if@%DjHtECHz!8T&nj+Q+-7?Wt9{{{_}r&2Hm@T zYCMr(9WU7}dvVSdva-n*QD{qCVScr_Dq2>1PrM|;-U95q3U#Yorp#?USIM&@wD5>u zqS7VE5$Sf3Jvs?s^Z)2A2u9z21^v_)96bj_xyYY{6MN3ws{VX+q;Sj3vJAj06e~O7 zVw%nhp4#Apd04C+D=NgM-p*k~{#H+;D9AG4ft)$5OJ*fHy z-|S&JDgAwrJN}OAf-{CM<|!?`z?4b)yGbqaEgB$xr1^@V7^G^3;*@Dja7pN5B#`q*aS9l z95+9I;0($}>o+ts0X1I(c?DTHDll?V^A`iqZC~7=?I*CRSRa>ywms-WloG5}W>*3< zh>gSaU9&UF*Qjmj*TVR73f+91pRM--FdOn(^PirC7@9Uspyw~;Bab2#;c%8E?2$kI zXMY(*P*;AukNGP2xRC|JCIwwP@JG00~6-a_oGWQhkH#isYgD3!)7~y8^V^i#XGeOxxrPTx3 zmnbR~>*YFmAJ9W5{reG3|J$OaO75L(CLXqh;}AuX6rO%mvRe2V4|W=y0CI4I3vFIqHkuvx6N$MhgpgAY zpJ`i<>`6nZ@LiP3roW%$o2KKz&wo7Hwdl>^vT@bu&%oOZEteAQN|7Qjf2ye^C58ao z;dnWuCbj+sS#*{X@7tY*9L)InhQXulyha=m!0F%*w8j$^PQPsU@F}*Q(Dd->C9Wl~ zXC?Dur#HZ!I}sP$3TG|jj`LfxO|~;rKfd#l0#ZMc@E>n#D@CREmtYPK_SXiJHUo$I z+RLbox-?N_1Y)j{0<;jw=G!R*UJ4v;Sd9|6$^7joBZLtFUOlIQ0m&M~;reW)mF;J* zSo=5|{}*!?Jiz79ijABmfc{C{&GtH3^$XsHI(r}f?69N4$^3$&%QpC14A7Y$Q6^Am z(XEp3mq1Z`J);qM!w+wJ&d8&}1SH5gnvM!bHj#nIBH%pHW)Z`3 zEehD9&N$o?T%6ar9{quuj*OQBvYJnom?!kO!8tuU7s8*G(w828qo{@QtE>97t1qSy zCK|78fV>Un1>D6ttyxA6dEGxct<_IG4fB?5(NXj#3(LrxGQja{!69$1S^QL_LS zrZ4=q1+MeSMrvF0ZhQ|nut4l5tq43R1RwXj@sX%RQy zAniae;`aRDxD}9EJB1~4<;MO!ug)1pR3dRrLFv0`KG}FiO(=H##6=PU8Tj*s^{m!P zt!QCNJ5;%d0Pk8j@0K_LJO32A3=qOGAj=L>&j}L~l1?j7RBawDYqME`*C8f_EP{E7 zsHZ#T3~~{sT9;rjroPFjGKGGc`C0Qug@E6DZOVNfPC`f_<{2mzG+y6iwLi&pAtk$U zLQNC)G#*v60EH#)?(s;M*Sb3};X(y%w=E)|pdbcZI4FC5HD*?i0R8oWd}iQ~NzGNo z4^J#}08PZ!61`(kS>b4WzzITBG(BPV1{khbJr;{@cf+9%|G5L`5_S#Vx8jM1?Kx@F z?Qtvr-%HJbG)?kuvzFjo-lH~-N>bzJ6NEcI!o_Sv3bim(IvfGzG#9jGaZxZVJ+}}f5m1q zC8JAZ=eyXN0+)kaa5RyBXz)?O^fPbLAziK7gYj#Tgkl9!pYBx=ngA%Taxlbqhj9)jg-j~LYNGIc~c78 zf2_CKEqq&g9~^)u)LX!gh)1Q1AlzLgOmTCQ_ED&Csh*rG?~61-JGfDqE{;4wxs-Cj z`M%s8K|xUTK}`XyJD=swsp94aUq#|!HRado*lJY%%o+e{Wh-l>H4r!p!-}~7m}86R zSii}Wr%<(~R;)>D2kC>#XfinT%v1uK752XVX?z^0%BZt1zz9g|EGf4q&*hF2Yeqms z_`HPp42)@-M%YKv2Aup7jC>989jV+q-|yv;pj;$Utc;U$0CC`{@N8rAsXSNu{Z4B)lGFF|f9Dk3AGww!dKk_B#wbxaYo)ps{? z&ERCV*jpj^_P;`(<2oh|2|zqv#%;qpU$8JkxP(IR-5o5%&{#*k?oiP}l{0f?1Prth z@TllObH;r@{z_)8+oelvSf zOq!;RXjZ4Smhb+2zYwh2tUthE~fAF(1EQ_p!sS)UZnc4*-44ur?H&Jf&4s< zP|<3~#0cT%>Hn^KKE2D2*7w9i@4Gt{-xMJPT+}3b6RW>TD3Z|=JR%P^g~6V~=?DRa zntlu^%7q}l4I?ysBBI73Qufs;dv_gPAhD$)Wbd><6NW}>odwWj_s-@#x+90NC3lWPE zioeQ(SbBR8Se>6^tGqxy8SleCiM8R+61%At5MEB9 zAZHE}%WFvf#mQn5Y36;8)~evmuTjlUd=b=pc0Q4d8-TYIvpdp?a{U#jMEe6V5yV{) zdlvX85gD@YTL*)mwIUKGsD5}I?j%?^aHI_jLP!eg1!2k-W_-9)F#7*y0YG<>ZosJ~ zo)*H7?E5cR7frv}v9rnzVukw6| zgTtSeyho8al*l!zg^4eS*EWoeNdJC7Tm5t+S7ic$Y*;iEt2r%w%2YF?tFzekbmjbN9|Bpg zyc=X+zTItGh74p7U<_voMdnCLjtj;gRV)4r5;Bp5*!TT4I6ocW7~IqTGBGAS7j_dJ zp#opBQ+>R0ob&O@J!Id&_xt>vw!8m%o$WuQbNH;;-m)V8=g%mduamZ*1&^vHqlHX0 ztMAJoJPws4h2nK6MhwG|NTMh|TNhPb&uFJuK)wI~Wt1!AmXVk4)*lrYV5gIQUHi^q z<9oYI0A9xTLtiXh&-CB)MLsYC=^oO*zx7fS9|`@qG~~Feb3O{3v9~JI4cU(MX9HHl z6!C~6Xu2*_NH%Z?NmPLkY<+F;@s>(71y|`X^G;5B`J}(=m1_fZ47Klkz^I11hh-oh zRl;7@eE0ZU9mpD&j^IL$IwTD|C!fD`j%{;CKh{l4#Z`$bYZYJ0DqW7=BzAHeArLPk zemmftDn(XCI2T5#JkWvfOCVX@k`26#K_D007xESvvg7s4h|(9Yh3PHsdM_Nt^6uuR z{d}G4WsIZ?m|=F<`h6zC+{O+zmNAnW0n&_XFtDVJ!ig`Iv{7&aKX5SV=Pzmcr*5$~ zN(oN$_v|W_`f~UxK1QiW<=ag0Q}=A7&p(1G8{P13@&g=F&{)e<%R)>nSJ!i8;6fq% zOGpZV;>n{ej4?op$q^V-3&QN@A6Zpk#QFotg6DbghrkN8;%*h#BikV4U%4atQG%EZt1Oy4` zW}T{1;1b8Yd>F>_4v@I5Ri(?7F%eUhWDRHGDID1E?0D5Vanw98bBcsLj709qV zv&TSoMvG16G(jCd;QkY5_7N1AOZUBlTBy?GPdYi=?7w()=La)T>7#uRzfIVU%vNFfS%P{* zPvz}vMG!~#!;1*(?5ipuA7UXolttnLU+RlFU zre!TcON=rD0dm4ad2b=QqUahzmFShM%ZW2=rMmAy2qtH$cX$S`av=B6qXu!Az$@7A zPm>d;`XA$K9fqHW1Klv}#cB;(Vg9NtYQdL+E@(aTynZ)&b*nu<23OGPGE?##W#7X! z4n_Ds|2<|k(PkoqHB)Q!QD+1;_X!}Np&DupWT?I<{!oc5+iI<4G{a-_{ikt#8BxCRPYl|Jo7g(Vr16V${aG(K)?~0F%Q0ctFIt-{K7A-n!`T)^UHe zWG4l5LGEh12l3!7#`|2BkGm-QqQiHKWw%N*^`DSm)k4Q9QJ{;s4Rf{N;*3y#yu?5` z@#)KV<6FJE!nYEm0H=rcIiSCI;&~0NFnRppt@`|rCKs&MT0;GH)aKhC7!cs1EN;sF zed=o%Us?A!@GOT76;7Pn>kdqty&$w;4*Z!|?eXdN=Q@~QK+9hZJ6dvsugW!BR6v{z zCQF--7#n`o+?X{0P-^?))cSshsf*HN0JE}7=t))MM zO8c=NIA=F!=A1rHZl(ottOIcjA~kTAztHN7czj zSS)wzF#6j#7*YmIlkN2Pkj*js>D(SO-Z4j?4q`f4_ogb|71pbiJ!BDxw4fK~szcOx zVp0Ch6#5cJvSd%hMpt8kKp}`e5TLGcFozmGs)PI3%#Fy42u^Sw#Lz>)5%9k7pfNd4 zOIooo__2iZ0db7IS_^Q;#9*2Qke?1jyc1K`w>nhGC|gY}O3-@LAMh0c)Z{k1nx*aC zXXqTLn-CyHT7ZB8;|Au&OYN*iODREHc<-)`>g}JqpvjM$Emv3IoVdbr!cF98EQI#o z`PN6?bS{Ge9mre9Y!LpmC64vXVv}LnfY7pOyH`ZTSokClHuF3KU7f zDV*5FUOPEc{i>wd+@07kU|==(WT~v?<&Wq`Zs;jDpMl%@auQ+P{$yJ_!SgB+kY{80 zUOb>Xv3Ga!h8Hg+Xq^(*p~ew{!%cUEGbJf&PgCxrUL1m|!S}P3KFULa7UVXTRrFTS z+TCkhDsC-Y`<_nqUm+u*_udNLU6}_jGgF!Bi)yBswo2FwJEH3~l~;EA>-*{jzQVNq z-%UVaq|J>_Js9yogu2^^l2gAUhI;bjbt;wBUe8&_V(sfZW0(!li857cBE`y2GmNdx z^;$h*#Zv#KZW^|q&?Ak(FbdGX=^_K9f;*0wJ?2fR-U%0I4+VKT-NsDe54Oun`pu!s zjR^!6EFFR!csNx&4PWOU&9H5f?@3}43MMKoa%YtKYNM3}O>_N^*v#ip$9Qk?)}$$@ z0390}YqYTZN+T0AboJ;k0unCt;|s^9Z#BUD57pi)gh-A2E%pc)Q=;#-Y08`PS@h`G z<%NRIQUm5jJkYfK+en31ElZXk2mkFq`|w5kdVI8b5fos_PUAY*c00E|i=afJ*`#0i zYhQ2MHwOX3EIa*n`VS%{!E-BDEwt}{`|@kq@96O*Vr{T2$jC7Y^T%DJ^wtsOwmM%?e-+S*ymi)za0k%sk#O-F+(h~e{H-s z1fO$L(m4?9E~(Tb<7K&LOl7P<&LU7Hwae+mHBXU+ngtAiALjk?>Nl`ieQP(lr0<9| z7EJ%U&&BhCL!QwV;iMPYCo~c_sHw*N1NNdl|7FCSz=H=e)`Q9<*#Y} zb@?_)r+vxu2dU71>w|Df&oASnD<%)YDu*!~D8_nI*Z)>H^_~a6bN0>$#Q=^LGY#Vk z>Zo+rQhR`2zL+v!t&&RV2`p2-)k7LQjEsH)`c@1HI==|N&!Qt>>3H)~P$YH{Wr%_p z{P7Or5}aNiq~z9*%-d>{&zOiCPgru(GhY^$396_!p<+pr)+%p9(I`14UQC`N-J!4gh9B~-qvn)yfTW< z-%y)$Z_VLq43C*9KQ5r>E;Fw;fga+0doWU8t*E5@`pe%Mmz~Sc*@In-vt13TP_ABu z(1qBQiF**P_pEF*QWphE=|p5td;`8kI$E5mFGmG;4_^Vu*2YaEdZX$t3bGUmZmnzo zO3&xjQ({g(X3P_(e8S|4d@3k5wN21hTDac?x<*5(`B?Fd0V+mbT zLUy6qRCV*CiA6439KGz8YwEXnIu`kHB%{MI<}Lr-Oxq-j)@1pJbq7&zXeu^2@lA_T zS?Bu)_CGs3Qi-Ez@|pQ)IQ%7>=YzF-5p@ohxnN-(#rB-NkJrh5U95=QaX>0GCL2q; z)XNGS%B+@OnV5nt(MBGSet|m2ev1smmFTKkhzzL~cYqG6X>6s^}XZei8ogk-h~&ZiuE24zbLEOy1@iPNO;MZkwd;~zQ={&g)10Sup38D zAGIpuHP+GCT|0?ooOs%20dcjP{)G^AJ@AVo!E5cG^#$;7k;g33`(n`evD4Pn{WtY1 zq5Ld?M*Gx^zfg3CSZuD>bs4X4VV~fPH>0Ir&v69GQ&w-`T^|qh_blieHS$~y<@Hu) zSK<&Ro4ih(B#NozsRdx|%;LH0BW)Skhr( zB0KuZcvHG_I#~O$mwid7l#h)0kui&U%QNX$3ZivDScIM$zZ2-MYxcfdrFyXI@cnaD zg|y`F6UCu0OPgtQT}+#^)c_!Vuq(XVuh#I~JeK3W4=Cbql;nAk6a3{h}B?(xU+p0JXSGO`Qs%QSdGQ7OM;Lq1sauo@H=|zYx{H*r2mYtHm$eJjK>FYiGqVVcY0#C=3`|irCYbJw@i5&y(hA71 zx>ACA8!PEgpm=`MGzCq+vUuw~*_%~#8 z#;esq$g5OfX)Hj;hFp;Hbw5kOfuRaVT6dM~;7d89nyT8P+E4dcwT|lF9M_8L9&D4v4`%R_t&cU& z$;qu2$OO!gn?DW|Tc7nThIc6hz?ObX-W;B^yH`gdL{9eVmN|^`8a|geuB*%{&F^2b zFw|w&po|YI&r$FAFdmlh(N29}0b7IzR1C3R;pobXkZ-Nj6++f;S$0n0v1%6d;6P__4-_=<;8e>tnyagmM=`VWB z#nocu4}nLIa=tsgkPYHkRVh3oR}!JOyoi4^ux&nLd~7w;KzjMjjLe)Z&|Y9c@iCq7 zSgJ*|x&8UdMX!AD@>`v6WN_81q)_iT@PrIA9O47ha@67})mF||H1E!Xi=DvEQ5>*^J+l z?MJ04e$f50sCzw8W-{A{N>KH0dthZWl}V)ZM}JGz!MVqKg2>xYspJLRE6kISmMbjD z09B&@cL@RGr?H^G-g{l2$c=_uY>UBw6@EcuvYvlBJDHDB8RSE>Sp97h;WxSc${`h} z%gwfZ(b;iy*Nv-NCG@N4?&l`zD+0ecmYuo3aCK;;!S78tD2QAR7>3f=EuRMETb=9= z2mLgA5f!`@?wcI`02q>DD`}d8*mAUA48&|;-XqdAW6V71UX5L2!gvId1=;bez4EL? zUuKwZmHka={^$O{pL~QOU-7!CPFm{He_SN=`~1SAwp=3Y!jA}DD7JE9ca>GbN?o1* zY+S(Gd6CrO*NpKMx5#%RRgOfu;6<2CYfnAjvOokiD=AS)XiLw6XBq+a>>5= z@jkNmk2_ZLyiC1lI;KB0F}5Zpx4{P`RJQQi?fW4T&;?RX?G`Y{MqFKpZ+WiZ5NHAIM!77k%p2nKkuJ3?8D4q9 z(xTMP8ox~LF6~PhidOq1#Jiu@_y$Hx8f!f0qtsF$T3m^fRcP-=OXgBshrY*?p6VpZ z;#fEinguY2gx(-F-M(_oB%@0B4HL6u)IhNgRrG4F;yT=e|NC5t;Hye3^7m{|Gx6l>O>*vlDaPZ`_nMkNJT>0>!F&e zHY%PPV#*dgxJoB^fT0F&aTvrOY(8eH6R`WnGEtw^>@0S(L4 z3Js!fL_oWFGTo;|UHidPK9~Sp<%>m+V9PXUrjHMA?^Q6ZFuYO*;fHG#!51qQX?kMT7RodB@pSk`s_mOch~K!oO;>K z4~?$9ae-86QSj6uGX*p9oGhsc69|5Nlt}NpI|k67pKZ5NpTJgOz345!xni{VuJh7; z=Y3mSds0WlOiPG8!^h`aq92JQ9{6vT(AMT|enbi}UQhF`_|!%sW%Pc5L&);zdfL0R zstwj?+&uh3{=53nzUs4}9W)YGCmME)F~JA#M|;gB#%jb(7bi+?4Rxx>g2KryFK?!m zmssJ^W`jlMW46=56`|hB@4^>=)rUR)+FdoNhtxS5bPJfe81U*{8n<`mxeY=2@pm*V z+A5+Z^{&rla!jMq4I!hRf_K~WgJJ{iLc+7)F)J{5ZM&*zg?*eUpc(h2f7bEJsUjAMrbc*M11mR1@#s9im7oDlZZHoQF%&?7qoQgh!76=?|Hf-`tdCx z4T|HH%na{CMXd+X#iA_om}Laz&A;t+JQseQ=2(?neJ3`6X*g!ngW8JA3!4#V<)rc~ z?tGp4b3OEHs{MMAAD>U~gSl<#`~PnBG!`Y==A40s>nIpO~r+M=k;GNQEbi zYx{_T1n;NMmHNj(9F;Db#7VfHCtbM&POEis;)L0o_`QsR^sl3B3B6SAy=zP_U+Mzx zd@z=>X`k&5ig873Mi`=OR&Fift=obUb}`t&9EzK1k&Fh91MC0f82c?&#|~*I{6$6p z2%wc1Z+`|F^ad%SlE~2@uPTE!L@hXz>}Avj7ysl~ zdKgjtbYi+A z35qJcQf>x5l*U*!T{W?-=K4nmX0yi+)@_TM67VR-nEd@M#8(=T#%rEr3b)VoF^F>S zgZ+sD_$q)Nv2IsIR5xfwf7An@-4FaKT3$b-|6s?WcvSDy0T)rr!7(WA>3so?wr7CQ z&TR3d(0$hWsqwj|giV?-hP|9Gr*Op@)q7K-I&8MLo(2d}bw8Vf#*S%v6mNlnRy@(} z8=CXD0{D8+ISxnEX2dw`wnxXFlS76A!?)A|NV~s@gS=(6HH}yDQ`_5#gp6|3;z&sx5{7z#y{ zYUY~-7g$R(NUXF!Yx_9WAng0?4!wa1cvc89MqP#h0myUkIaH`4x{-X@(M-ti~y|b@_Xq8h;H)r)Yi3sZ-N+Maj)>K#l ziKWQ#_CX!?eI^plAipOb{`^mG`;p6fXk&lfu=IMuxIGVFxgt+WkEYz_5uamxzo-D; ze>7Duc-m-sBXGk-p6!|gzgRynPP^Oa_pD&(!jd{2j=+}Sk1|1CgFKoVcEjdxMwnFg zj18?xX>IeHq@My`#I{WAcGT15dO~o3fR4fG-@Bg@`dss$3j69vw;XN%-J9*dDbRmV zXH|1FMVMZ+jkDRY}F1O8ueu<97KfdA;1J{95wFhgfNAs{mDfoxUVyr4{O=XHfb~yHxd1D}V$? zPLVOz*hApC+?hmowH>ebNbe~VB7qKh$`~)uKQ2YFas%SlLzO(4w z<>1_vTDSZu_-L7-Fw5^B3O+ZJ*n<<@H$(GLrr#EL?+H+DCeTl}W0qtGtM$UWf2@ zqLn?zf6wPTJtOiU!4?@iUF%C&F7+?XsbE<(%(!IY$*kljf=Y8P!$Yq}Up06!-^nsP zmQy3>3nM6(+JHOB#-}WJjkkodaV12_LQVQMc!plrR2hA{{%C*L;)`K(>{RcKw7GJ% zE4EJE!!r3EF0Ihb0J;BtX%JS!N3+pdM!ymf{%x()jcQQYe_J_mWpAxi_ppmDo|KUO zv%8*EL3HJMih~>(x7_fS%OW4F)l;B}bvM$${^iTFE&CcZoWSYjL9@Pk0iOz}i?1q5 zF4+k39{aGBIJUxz3wCDH{@bI4)BX_SQ*hwHzjfI=qghLRa~C-E(d);hW|lpg^d%B<|29os?f#kk;}4%~i4aH7D*VP5 zMc~~3EX5TIT|u;9UlaHTBZJ{(c_y-%L9SO=?9JjphtNC{K_Zx3s ziw8gt+Y&FD6{S+7V{m93!AM2&#lH|i|7Fh4)T~&3xXzUu=~lh8gk)M3B!~fncj>DB z5FiD=hD&pbR9~c!KZuLbAN-{@z)-$K(02>z3+VsM^u8n&gX-UQ|Rc0y8D5#Yg_J+H8IoKi8Mlb8?$$npAoUDqE zT6XyOPoGxdw}{q@fzLz_XR|3W@2iE1z>v~`7;UzWME(Y&1>4oXu8c<|uKeJOgtIwr zZ~8=N2h*P4PKhtS(8|BAepBMhkHLntjvy7|5vmw;x)E|sEc%2nNhn0wxL$~o$pq>6 z55C4M(rkR%Zux|T5B4McQ*S?9EKJ>KN68{M-ldz1bM7ZrUDGY=v%KE42MD}C(NlD$ zo%nK%5Gf~;&&`O39oaBcjRmR1#`0(<%;n=%%1ewo%D3w%!(bhh+wTT`W32L-&cEvv-$)*!bN{3J|Kdt(?4441BmA2s_F8SbYS zqiY0LhdKr)48}Iw|K6NzU*TFVftrP{vEFg7_pc;sJkOZ9TN<__f^O-JD?`WOzm(e; zoW#cfTMal5J-a$2+5inrJfKnh>@}?;u_- zP4my1<_su8CX=}36Kd(Fepz>3GDi($*Ux?ZSMj-t|M7!lXmHyb>!pfm#u1s)YH{J} zpZlaXbXQE&mIGGL2Pnwt+h0I$@5ZL-A9_&6uFPt3h^(AC>Tz? zo`C66CI|Pg4qJOm4XQ#P2q))hM(JAwo`aEexd3N=2RZ3t%G>A3cwIQg++3n@%&>vQ zgKv6r6it~^RY^AIYmXh-R;QRIe32A=*U&xyE50=J@ECx&o=U(K76JC2aSY+w;7^2mc z70a%qbpW+3n^!yc)T^YTqC9ZUV4833<=J3bE!sKLB+4)!~MlNM7}AKlKEP+y2yy4fj= z-i+?()~NY3Bh8=I?DNhWSqB5V?SagGOgG)4^QQZK76*mlVLC0KNYIlu?U5!cr8=pirjZEv?k6!0mvfBQK0A8K^W(3D2=rMt52Rex>D%|L%z6|> zcF)&S$~B|hf>F|764@U{E$&Y-@V zC;jT_Dgj=$Q@Pa1hOl2nC~gZBTEI6l>b^TXQDShE(pzB+DgRFJK?vx>!^)ijlqNVQ zY6o;M!>hWBK1NZF;U-!toeY!To0yQ!(@ z{=3*H8`H%_?}OVIfKY433*RPm?OGgl+g~hJ$Gm26UgEb@WS>Ng#A><;=Zwt_ygy!e z^K(Q~q}CfPgtC978{wo1g+mKyB&X7(;J!UBtjc;By@DB0(9V~;`W2Sj7D=WtXmy#W zkFB5%ZYtwQ5cN3--{C3KbG=_f6};GybRTCJ)?a3XiT899&zt^LUq1BQb=o&{?&0%% z_DM$z_}qlhsW$C`_tfQG1DgXMMVsH<@6vwy$amEGmtD%Zm7zwN;~P)d1$Eurx!-u< zN_U~zi;cM}G@|{P9KIdu6JeMWk1Fq7IQuuTdoP=h#*m%`wQuH{bXw1T>YICu$YSc;o>O{1yrf-VPUGgud1x>} zT4##okgo0EIOq75V`6aRZIQ|FyE|bDVTAS8minZKIb1yC`QhPbhLgzP^c7P8ZK8-^ z%N|f$jhe_c7_3j5fZ^;3Q+9SP3)^UunRu<;d@gr$`{Kf-8#Md)o`3ay-BAGw6;$dg z_^<8rY79p%)F~^6eh!2D$FUs6(+09qqY&?)2)zvLvicEC#i{D3KtltOYBT;rR0)&m zBt=U`?|K9fY_SvfOg1BrfQ_lo+F%-sSFK(CATzP!RpN-x11o7Kld#?_ZIC^jisP_H z!iiDILlM!Xs%pwBVMMmml`avzFNTZy5`G~&5Bxl2(S2a8`w4%ZSqz1A(AUkC=IJDs ze|m_BEs5tsM}ED_i=RY2^PsIg62sNVQLFPDg! z$#X^o;$Z-1h(j7_r?$rPu*RAQIOZ@U*O=!co%Y#H=?EW<(aQQ zLa?vWO_<;8LL`tJ?LptMUCGw5^`HDBy0?cPchbbfOy+mW@9?D$ab1BIqK?B$Yr)0* zL)xE>=Zw6b3pl;97?OU&MHmLa!kJPg6CkIf>BJN#Yl-i>ZRPfo-4U4B>ZwY3G=fQg zPALIob1G1Iza$Kw_Kj&x8uK|cw1!>>b5u%#?U=3>?9$TFAIH6SWO9 zb7co9+4XO*i$@Qq>qieyc1Qk3MpF>FQ(x%2n26t1?IkyDWQ=AA*HYb7(~COCf=4>+ zbl*?nSacTKJp9w>ygf=B!dwB{akZcCIALrypC3%q+T&Qe0%8q{E=W*M;6HJ9dA{$EoTei3g zO@}Nj4aV;{uhE}M)w7a@;+$dh4Z@yaYd*bVFd#%ut1&?TXvIjip^@hQ+PAypy$y-M z`#IpB;u@7^tTQsYNR%(Ui9GOC^ipNaHWJ zqwYfG`gX-R!Hjwp5nnXTlRDE!Yw*}6pT40`&s$=B=>)r0lbE{1vnz2=7~fZ8r($jXVh;Yk8x+^W@`EpDw(X%PSxXBfK& zS0CNZr#29hsqGOhk;xw^w zc7K0AeX~8b-n9Q%qd`VqYiZ{9rWV_U*MvQHx_CqsS8{w(>f+@3y6MJ2SK zepyc;3}fWK~IGRMn{&{tppSX1$RLYlcQTUCaIKln*EXEw!j^Ns09 z$%cw;c$9_YJGP+*KJAYGjag2_p!$UDtL@i4Zg~wJE-B{5YfjvnG&@@Kzy7|4+DA2ixl^|bD-X_*%0@(V%JnjqUz1EYZ}aZR|dh;(Q0Cjg>6 zjL-8ppK%y#&dEl=ZE?DY7)(aP^KA60KZEbeRKvQ2;DgRQI`y3G7EiM@D!0ij3tuXW zyadduXvIs_I>q7bmm0^(Gxe7fGljzoLY$K&vbyd++c=GoPUmO1Oc4 z;U?Lu0Fc;pI6A+dc!}DI^=GSpC~Hua;k-4S&S2mC5`f#jqY4Zii^pDd_NHBbPIqR1 zWP&;j5Y3kr&mU1dpy>^WamhIkf!`;mH?#J&TvmUU^+IRjNzbK2>)%)s<&<*8&Mm>h z*Ex^xlH;8;f*eLwKf+S6gUMlkR}(0`9IsX!_!*C%T@5e$`*;LA2d3HYsFg0OYCP<% zYDLSXu^M0^H_yivX#}clNrTPR=*8QzB^yO5oNz$n{?cqJznuJf!Mjs^0qe_HVm&WJ=>S!dGS z@Mxc0JpgoUV(@^0UPd^H@>db>Sbv{P%hPYre%~>%Ec&dQHa}^L844cLhWQOQgBjnD zSKhN6c4dYke5<|b51=I2up#y7>*Gldy4jipK&=yoUt`M6uQ)WOUhQhkdw*jF9}yC` zcE}ly;T3lAWFk>Qi#-?dbMse6JN0?>_`qGFALT>wrbwsY>r%VpPVE|;6vx$Wy^c{~ z(Y5jW@WO<|IK^Xh#8n<_bpPDRFf~24w>3rUn~I(%?0`Co!N&G1 z2eeX8`QLhvw(z{P7(D1&j{eqiS`2L$4^>2qb^9{0rn7a$JMWn-Vw>KnnVTh5=zNkJ zaoEDb>;76ItY<46?Tx%&SOAKDqmEw84}4H(W1Z_u(es>Z_ss+zcH_LX>6izPbU-Xd zecoAcBe3+5zihYZYml_%LL!ubqB|GTP0I;!LR(!A7OLk;Q!-A;{`9-A{PC`2VyCP+ zy~#P63-m%E0sja6vSn(%%_TF<)+?5P5Ju?EK;;mGlBA)E_TBoj39t+(>KYt9?VJqd(Cuc7AzMOM z9o3bB2_bxro_f{ZESGmNNW->`H_LIb!BCRV1|Na2t-k0v^~tAVY;wgAZSwB_@n~UY zzkVHQA$sK-fsKlgBqEUI!BwForshi+1l_*S|e%G@b}xX_i0)-L9PXzP!A z7@w2KAiuY<7G9FMc?JfFQC&K4G}QFnrmr4qJxz0+9xS`HPQhrt^yPL#%&Zh4*4M32 z#r1d>Xi$dwx8J8+oV_+({yD?a4nn<=o+aI~6HhK9?4etO6E(hbPAL$HDBt{+1Hg#? z?!xoNK6yp|Q`#99O3Wpj(C7{Gula^sF}whOg6WQT0f92Ky#_kt>{%;Z3g2MjN0$k! ziJ;`$i%{2VIkAU9J<*2fMV9t)a7e)>L|D~bCb2X8>EG|uY)m^m?1lHC34J+hNjqw# z%8FZzbY$Wb3kH59=jFZ*2f&yxDSb?|^2xq%=-NU1I%Bm@yFLsmb${btc(8ug809`G*J@*nWMc8`rkqTD>8OltBaQl*Kxkxv|rv|Jh?Wd?Qgpfc0&h zk;ZDxQF;!$?w{>Hls;$9Aoj(rm_@;;QciNI)%9!jEkT<|<^pkXc`#mP3@<+iaY^+((1-_W$W8JbJI}6)zKYOKDTBWs3$KyeMCOh92 zG`cz(93rpc{g-?W&@%s|E(xA6>~cN{^!PHlZN9q{1Q)Ic!{~{?$*C z=1o9kTP;KDQskj{JEgq zN<^;G%!?1lEBvp^-6F_2aPNHuvGR`6a_TcXGT_%L_>xLnBf7_%^5fATewr>D7^F;F z`y44t2VKqI)OspTfrezb;c>lpRgZT1#Qh9Qc)Ub4LM>+WharxrDKD;vB*Vm0qwbP0 zGd(^_?6MMWu2CfjcGiAn+&yoV$5_$}4p}Ha0u6c*vEH7QZ1WEj>A0mu$8KHMfiT0E|&hnqG#p%(EsIL-Cp^T1GgLT{PMtUl;<{dT%c5VzI9 zoU%P=(ZyO|&cYD7yo`!|(hYLv4sH?Jv#tmXP)SxJ#_Es>j`=#chCBUS931mIRJ5&j zfpg{UM#}k3;K_+W8wJcS^dn~oxV^l~g4cei#nu5|$Di-^$Bo}gLS?sjlE=7?Mfd_K_UR0fs(YJN?4DJNcH zxVfUYVscICMW4iHo|itp?C9to2Q6PPnm%~ni!i`(dIZ?Sbh|Ru@rKhv?ESX}1t={7z{;PVb`pHOlrR1P`qJC4EG8^h&MiATbxa(Poi02AbfZ`F zQ;UA7h?E=;GgPg;`T13jhj+B;yZa>E0jRvRY)W)Dy$nS=Ir*-;l1f0lNso)2vK!Z6 z=k>nn<~PJ%SL>>_oUs7Z+F+R~?Np@|JsS~Ym00Pl7?w97!Hf9|TTpK2^{jM&#~>Z& zUFyj|6w=^)QX!m>vhTxBrQT#=%Vb7gIDowF^4KtQ2R&5zCT#hunCF)Z(ymZ( z-~O%9v)40$QXfUhMVolC6wyqGSBGbAZd}=lH|1LeJ#V8l-eM9whX%5gvq$=NwK_>t zM>rj(11_n9VkE*J9qV2~i!}GE;Y&P1LX41rFH@f(f%0;(JV%Htc7EoJ5`rc_06!Bu zoFMOW?=TWRb@@B#EJ5~93+(@An0h#0w zm=ryA7}V0m{EDRo>7cjUL7QR~|E3w$-im!%2qmwA zvFS!IW-l?hB$icAhnTg3Ctt&d?iNj6RxvjEAC%6 zoWh=-Gx)l9fl=-~b}Q=ZMuBOQwaX()Ek06{tVu+uWQYKbM7+Fp!yuDIHnI1Tai?F` zkR`T_M{gFdJRL9f7u=E>5lT}&CJ84dH9MRpke#t>Qm=xb$+xo96q8=9Hj318KbCww%(aFQh2jjycs60q(ej>h{wQE z78^%5_>K98CeMA~P*OB7#2>|5I#53A!bBIU)ySPv3|6x>iZuE-1D|CGElUsUs>8z- zCW(HllxDCx9O0kbN-sSxQpWRXSC;X>64DoUdLyBZ4>=Z;F8`6Fp5bcyB_>Yt-Ngq_ zPDXVduX^q1a0sc_tyAA}(08#^cONbYpPyn4^{VKz)}~gB^_E_P^k`}LKVxie%r$g_ z64e(|pp9(J6ZaP2x%H&xIiYam?ve4&0sGe1_rf6w;7(@OMp63BJZK$EA7_f*EFs=y zF+Dtoqz_`0U{GWcUvYJNts8`b-r-h>K{Q0xl~4-_74kKKy1?Ia6jB&QftI$-{qtsY zFNO3r^8BrC9W(Ql&OHZwbdM$A*X z4O`#xLL$0^!QY7~_(MM|F34NDc;x-W@t$l4j#yGvqCypJUsNfoor-o4oM;^eq7oMn zpR*V=NZC!S6wdO|8i&OBCm_Xs1KrctZD0i4ST9Z_hS+zax8GtD^nA<;^&X$3AwF8) zU+AvLokS@=(8@Yo*0Y&2V~4x>5tHY!crQbGv*Dtj4s}Gi5~>u@uNGBi{7TnR4fiX$ zJkxP$G$G%$sDOtIF2c~^q3qJ@m z8!0x19s??p#GWxeXF3vBk4JMh0({O=d?tqEGC_LWA;0c2 zh?dGGpa$37{!2RX3(nLqDlCc8N3j*9pEqp7hu2%)4WHA#M>+MIOD(S;{$dgOT+Lyy zWS2Lx;-X&?n(v^VN5IqZ+UidD%l{-I{pEafW5(aZ|GHinI-=L;H# zh~@9ggi6Top&!hl{O~qtQHgjCZ9{B19(ivP<9{-mGakTt~v98WOW#R_7@oypq1==aVSOuO`P6&3zLtRp1IM01Wezd2;KQ>q2jYE5}Q34CTE6q+! zatv%(tu=zuExI`+Tdjt)Yi64Jx<@ZATBw;xEYJlAGZ_}v>Vm9YK~>qps}rZuAd*Mw z3Fr%34ASs3o)WQ7Pe5`9>dd zWhf-kU#a+Y{_lt~UE`9oxuXO(bZ#v;BG>~-o=fBV!OZI}Ye4*>U#LOx%P^Lcb@#Nd zw4RTN`LqpcV2DWZ_fCb|mj2%#vP`%kDvbj?u)qMgaV_G1+hrxX4=!nYv>^ZAk_hl>(I3*0+8?K1 z=M#eXA(6NVsi3QY>5c8ZQda@#TFnYdt5r5PTu6QwhQ*)N4kKX66S%h)!B@(XGbT5{te?9=pK>0pb zH=`4aN66umVdO}x!$tt?*T{G9KV8#audcTmFqqNu8jobY9-NX6ON`1{oo9(kF#Pzz zqUCw(vv|~+gRtr-6!&7M|3J8-L-7ii36tatmfszv{Ic-oK9TQ^p1@&* z&2vZLS%++;_-!gP<1+>Rdh{s+IEuzp4Cm`j}7l`-PJ z#br@tSzl~|S2SQr9k40ykQpr2;qs%>Jh6ja;h<-?cX8*ude*X*Va5%%{~^9#+D1UjQ3i6?F3M!b>Dd`#6aIvs@CpCG7WdOBPlCP6 zx6H2$C9BAMx>```{11RH`E!?P9LB*~4S)d)=RdsWmbupZV|)R2L-&KG$oT+q?}scl zj4ANop7=gmtWb-M(Dtc%ub;N8Kr}1+Jr9~&YvavRN*P>er5V~o5Xc?>E1zsxuA?!C z=D3$i^g{-YMgj)Vu({rC*|0R_xIaeG08jcF7U+3N!yZ%_(*0gGiNKJ+F44R@4Y}wk zD*^7%`SUqlmj%C%#~21@S1saNX5ap0Uzslm=iLt?ky!~f#J|%4U!OdPyxC4O;_!jc z&ME4B*+^_atPxmhMI?P~>&tWm>wlshI9Q7&hvKNHmJ5e>Ff$cAQ66Yb&o0V zNvf!~6rOj)kIP#aI0b||)gEn0TznyS?tgzCNUg*KE7LLUGD6idClVpW{U^E?z&qCF zH$Zr62KMW8%nEg+ATu{rt5HTM?N&YWyY2iUv-*K1!1vEJ2EG}(Mz%X{^>wFawmYQu z(mdgAH%WxP6+ytk7svhYx14W~?@?0!SHiW&Gr7j`ZJ32&B{Gh?BPT7nYchmXgd&%N zxs@@O35UckNOMZMxD?7%CW$GMa+{;%a60DJB+XDK5>}bZu$_17{r7#I=Y4+P=llD9 zf6x1Q-)F7FOL-o1fTPtlduPA1bWEA{)x+sqScw$r(RS?xeF2j|7j}O9u1yi^KxupW z)@zfKoOzM4sZ+EwFe=^Ltc{aLWEKo*iIj~p*3&EoIND4x{Bt$j>yk&U%;3QUYoI3R z!2rif+uU4p0&6|eXaPtTSyg#@top;i{SXnI{DSHP)7|VTF(kKA&XI@wmT9;jXwRh6 zS@}>=cT^?cv?^Pq$PJ6+sX0-}MehfjO$37-M`cAov;H&PA)>e47RL>KlUFa`ELJZr zgMhgaOUfWR(3>(UCvP$1ivGGOj3GZ;KiwF{AYHtM{C$)!sMeLRL*;BB$cA#n0bZn( zaQ+gp3>%q7OW?mQZWnqMu>G4(2DpidK-IZE4B=*S9gCERPkmLiQ~L_^VLe3jieR;( z^4m;ImF{`4d7*gq!)}!;bfyeW3JNE_sJX`xK{#5K5e41<#T~V)Q6c@f&w(A^jCr|z zfNSbLN~weBK>U?_{Ju5NVu0UEm6ipbjunCuF?29Jb|558+a;T1`gA?`YSEe6F49a` zT5RD^7ik*{uD%HrH?u);P#UTMYC2KoN5{cPZ99*xhyFy)DgDW4bP!=yVd9`$bnB$z z@~~Fb2Tz!87Hc%*HOA!?7i$98+n-evDP87kGtGVsQuu);b(9zr-Ls3p$$}Bf5g~A6 ztX+=FlFI$aDV^DG1H~Wa3l5HNnSEfz=M062RA{!6{BvA5s{iA#tJLd{Nj!W7#L;pM zAF}VhVR%Uwc9`~AI^VFh=)y86m}N}_q!bojqH+6oaO$pY$mtxw61>`zmE+b9Wj7hL z!y58ZM^*)x0&yxh-yuAQaChEwlx-UDY#i?z{vu1OGR$Vjr6AQV2g+stXAECA=G6^} zi4!|Ngd+dOTwsV{osiNn+eKuut| zb>suLrW^K3uIdB5sMxpj6<48kxwvxo6RO{(S=%LKv74J_^G~@#_?f$}L#{a{KCM_t z-)fxT&88yJp1;Z8$_?TD;v2+sMEld*Ig$W}1{?m0sSNDOFB+Nq)p2(B`bInTbG;-qz zY9c~F-QJu9sGH3SE zfE!l?oYMsStZtM(DSFcZ#RXWyj&Jt6XPay+3leM;f;-u~2MheAE5TM)FhHh*c6)($ zbMfRePa&#DAQagLnKD(3dIIs=f{_vQ3JA4*rftRgoy!?yi`k=p zr?dDMxsSb(@hN){B&iP#{XI}XY?@X7BqF@(Z8eo|>@z(B`ucXB#ItD9qF;MhZ%#rB z7KkgiIDmzQ;g2u>GV`1s&4uTrdOVXKx={xV_%a!19yC)p9wJg@+DhbH`k;}3-(a7( z;d5YZ5GWnb_ntijsMh-{djReb`zj<>(Yw=#3qW`)e&aY8SE_bmVRT;f(LcZQ4`cZ` z=(rSKg3YxkoBa*(8D?Gf?aQLdbGnw^`yjE?b#us*Y#@I$P5mS~elB-MCj6bz;eW>n zaEIaLXc8mytVX+nz331?92!!;Cxnt~fL^hCy)-ZumEWzQ^y2U2fK9W~qI%Db_c$J=Os+0Brrd{3Nz=qB8tfLA zaC)9e;k0~{;i|{!49iAPDf?1!aZd5In7@B847z0&4&%Nas4Wb8@vO=z6NOrf&4$=$=Fj-f+e@m z0{Oj`-kqbKjg$5**423Tz&eY_giyLfdZgv#$TvQ>nS7Y~5td~;lQ=iLRg=fvzaC(Z ze7*}>yTsS7w*UfzC5Ehckky&y9nd50!?T3*Ii;7ML?cU$fL#o~Y%_L*lUnnxY^o-) zwC_k>-fV&hV1JG=s$(E^pI29j&T-jT;Um+cV{6HcyiN<|yi?NYx%o}2^8Y$Va=U@g z*{l3EP*5$0@hu?Go3qo1Rs%xyK1U1Y!UdoZP7;L`XxIg$qp|6K+VkGe8g$m$5|CPJ zC-ika0($F!VzWIEDEytIZ(oW6#e*|Af2n@SdAj6s;$AYWv^%eRszo_?*n(xDS(;0a zwrSI{V945OLHJ&+jWw)U^Qr}+5&8YK+Dt$-)+jUAJ29ZbZ7+ou`4lN8R{)SC3F-HH0VZ~kUX^ZP~dO>Msno072 ziYJ78AJE_5BAiIN+mq+4kNCRq25U*L^FuzdHuaQncN&S>3;Gu_lP`VQGxzmjyb!I~ zThM`(!*14Ce3WIvB;_Vmvn6Pf6T-C>wqkVr6mL^l%Chi1>*Xa2n;q(RG;5pKBna>B z6C8lLGb*SaWFs{Kd5GNBmS$bJcbax8THpI?*eDT)4$?msoI0&X(-#CtR%kMKZf~bu z1H3oNAdR|%Znwa#9Cy9zj~_;SY8Sqzv|g3K;y-)z@TwsQ*lZLHSa?(%U$J7cRO14FShA!xcN+7GZ=SKG{LR#-8%&db^{r&LE0+3PFs(|0A7Idz z7DdFGo+T0aeXUUabDT>;rNZ>@2r-|ZOf0@GaOiBIKNk21eQhvy{yWA;5($2W)coax zrvgEFFNAIYx-D(<6u3WzH$FA5;`L^1Up27y2%GT1gyzO{Q1f@Z5#h!l z)(x149xF!*6Sn0L`--jYpgYrD6W$HfCE`PIm z)Vb48yoAbXc{0BOedBuA8C=(tP9Je!-g@WC;wi%{Q#mQ#4TW3}vNtEi34@J>SA6;ymXWq{+yn z9eR3t=~3Q%Xd4dm(x}F|{K0cs1OoBxaIK9mW&Do^B06W3ldZ6lN2T7(vec~I!*4z$ ztWJNWZWYA`1APUtWU0$d+JcCQY2{;$8FN%Bb - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/index.html b/code/index.html index 304b067b..aa7128ec 100644 --- a/code/index.html +++ b/code/index.html @@ -27,10 +27,6 @@

    GitHub Tracker

    - - -
    Footer
    - diff --git a/code/script.js b/code/script.js index 2e29b50c..87800d17 100644 --- a/code/script.js +++ b/code/script.js @@ -10,7 +10,7 @@ const options = { headers: { Authorization: 'token ' + API_TOKEN } -} +}; const fetchUserInfo = () => { fetch(API_USER_INFO, options) @@ -21,8 +21,8 @@ const fetchUserInfo = () => {

    Username: ${user.login}

    profile picture `; - }) -} + }); +}; const getCommits = (pullRequestCommitsUrl, reponame) => { fetch(pullRequestCommitsUrl, options) @@ -30,42 +30,51 @@ const getCommits = (pullRequestCommitsUrl, reponame) => { .then(commits => { let repoDiv = document.getElementById(`${reponame}-div`); - console.log(repoDiv); let repoDivContent = document.getElementById(`${reponame}-div-content`); - console.log(repoDivContent); let commitParagraph = document.createElement('p'); - commitParagraph.innerHTML = `Number of commits: ${commits.length}`; + commitParagraph.innerHTML = `Number of commits: ${commits.length}`; repoDivContent.appendChild(commitParagraph); + // Create a new div to put the commit messages and the hide commits button in + let commitDiv = document.createElement('div'); + commitDiv.className = 'commit-div'; + commitDiv.style.display = 'none'; + repoDiv.appendChild(commitDiv); + let commitMessageList = document.createElement('ol'); commitMessageList.className = 'message-list'; + commitDiv.appendChild(commitMessageList); commits.forEach(commit => { let commitMessage = document.createElement('li'); commitMessage.innerHTML = commit.commit.message; commitMessageList.appendChild(commitMessage); - }) + }); + // Buttons to show or hide commit comments let showCommitsButton = document.createElement('button'); showCommitsButton.className = 'commits-button'; showCommitsButton.innerHTML = 'Show commits'; repoDivContent.appendChild(showCommitsButton); - - const hideCommits = () => { - userSection.style.backgroundColor = 'brown'; - } + + let hideCommitsButton = document.createElement('button'); + hideCommitsButton.className = 'commits-button'; + hideCommitsButton.innerHTML = 'Hide commits'; + commitDiv.appendChild(hideCommitsButton); const showCommitMessageList = () => { - repoDivContent.innerHTML = commitMessageList.outerHTML; - let knapp = document.createElement('button'); - knapp.innerHTML = 'en knapp'; - repoDivContent.appendChild(knapp); - knapp.addEventListener('click', hideCommits); - } + repoDivContent.style.display = 'none'; + commitDiv.style.display = 'block'; + } + + const hideCommitMessageList = () => { + commitDiv.style.display = 'none'; + repoDivContent.style.display = 'flex'; + } showCommitsButton.addEventListener('click', showCommitMessageList); - + hideCommitsButton.addEventListener('click', hideCommitMessageList); }) } @@ -83,22 +92,22 @@ const getPullRequests = (repos) => { const myPullRequests = pullRequests .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor) - //If the length is 1 I have done a pull request - //If the length is 0 it is an ongoing project or a group project where I haven't done the pull request + //If the length is 0 no pull request has been made if (myPullRequests.length === 0) { let repoDivContent = document.getElementById(`${repo.name}-div-content`); - let commitParagraph = document.createElement('p') + let commitParagraph = document.createElement('p'); - commitParagraph.innerHTML = "No pull request found"; + commitParagraph.innerHTML = `No pull request found`; commitParagraph.className = "no-pullrequest"; repoDivContent.appendChild(commitParagraph); } + //Fetches the commits for all the projects where a pull request has been made myPullRequests.forEach(myPullRequest => { getCommits(myPullRequest.commits_url, repo.name); - }) + }); }) }) } @@ -107,7 +116,7 @@ const getPullRequests = (repos) => { const getTechnigoRepos = (repos) => { return repos .filter(repo => repo.fork === true && repo.name.startsWith("project")) -} +}; const fetchRepos = () => { fetch(API_REPOS, options) @@ -115,8 +124,6 @@ const fetchRepos = () => { .then(repos => { const technigoRepos = getTechnigoRepos(repos); - - console.log(technigoRepos) getPullRequests(technigoRepos); @@ -137,15 +144,15 @@ const fetchRepos = () => {

    ${repo.name}

    -

    Most recent push: ${mostRecentPush}

    -

    Default branch: ${repo.default_branch}

    +

    Most recent push: ${mostRecentPush}

    +

    Default branch: ${repo.default_branch}

    - ` + `; - }) + }); }); -} +}; fetchUserInfo(); diff --git a/code/style.css b/code/style.css index a12c863d..9e531409 100644 --- a/code/style.css +++ b/code/style.css @@ -2,7 +2,7 @@ :root { --primary: #F5F5F5; - --secondary: #8DB48E; + --secondary: #a6c2a7; /* Only used in the chart */ --third: #4D724D; } @@ -43,7 +43,11 @@ ol { } a { - color: rgb(63, 60, 60) + color: rgb(34, 31, 31); +} + +span { + color:rgb(34, 31, 31); } .header { @@ -109,6 +113,7 @@ a { .repo-div:hover { transform: scale(1.05); + background-color: var(--secondary); } .repo-div-content { @@ -116,7 +121,7 @@ a { flex-direction: column; justify-content: flex-start; align-items: center; - gap: 0.3rem; + gap: 0.4rem; } .no-pullrequest { @@ -126,7 +131,7 @@ a { .commits-button { width: fit-content; - margin: 0 auto; + margin: 1rem auto; padding: 0.6rem; font-weight: 600; color: var(--primary); @@ -143,16 +148,6 @@ a { margin: 0 auto; } -.footer { - background-color: var(--third); - color: var(--primary); - height: 4rem; - display: flex; - justify-content: center; - align-items: center; - margin-top: 2rem; -} - @media only screen and (max-width: 992px) { .repo-container { flex-direction: column; From 06c9b6c276383cf154fc8e5dbab8528fc283dd24 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sun, 13 Mar 2022 16:36:34 +0100 Subject: [PATCH 17/21] updated getPullRequests function --- .DS_Store | Bin 6148 -> 6148 bytes code/script.js | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.DS_Store b/.DS_Store index 8875fa064d006fa4c89b6002bb38d4006ddb7cd0..1580b9d3b8db9845613aeff6646dd67532f29399 100644 GIT binary patch delta 272 zcmZoMXfc=|#>B)qu~2NHo}wr#0|Nsi1A_pAXHI@{QcivnkT0;Ak!d-jBS?ycA((JNI|n{J(^7%3?*O}B`mu~2NHo}wrd0|Nsi1A_oVQh9MfQcivnkiTPM;qu7_A}pdT49N`n z3@Hq$$dZ$Nm)+c7G?l}E+;eq diff --git a/code/script.js b/code/script.js index 87800d17..b8ace47a 100644 --- a/code/script.js +++ b/code/script.js @@ -88,9 +88,10 @@ const getPullRequests = (repos) => { // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; + const thirdTitleToSearchFor = 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor) + .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor) //If the length is 0 no pull request has been made if (myPullRequests.length === 0) { From 75248f43e4ca3ad4ca8bdb04f9a64ec1c0a0e5f9 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sun, 13 Mar 2022 16:55:27 +0100 Subject: [PATCH 18/21] Removed options --- code/script.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/script.js b/code/script.js index b8ace47a..7c058572 100644 --- a/code/script.js +++ b/code/script.js @@ -5,15 +5,15 @@ const username = 'jessand77'; const API_USER_INFO = `https://api.github.com/users/${username}`; const API_REPOS = `${API_USER_INFO}/repos`; -const options = { - method: 'GET', - headers: { - Authorization: 'token ' + API_TOKEN - } -}; +// const options = { +// method: 'GET', +// headers: { +// Authorization: 'token ' + API_TOKEN +// } +// }; const fetchUserInfo = () => { - fetch(API_USER_INFO, options) + fetch(API_USER_INFO) .then(res => res.json()) .then(user => { userSection.innerHTML = ` @@ -25,7 +25,7 @@ const fetchUserInfo = () => { }; const getCommits = (pullRequestCommitsUrl, reponame) => { - fetch(pullRequestCommitsUrl, options) + fetch(pullRequestCommitsUrl) .then(res => res.json()) .then(commits => { @@ -81,7 +81,7 @@ const getCommits = (pullRequestCommitsUrl, reponame) => { const getPullRequests = (repos) => { repos.forEach(repo => { - fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`, options) + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`) .then(res => res.json()) .then(pullRequests => { @@ -120,7 +120,7 @@ const getTechnigoRepos = (repos) => { }; const fetchRepos = () => { - fetch(API_REPOS, options) + fetch(API_REPOS) .then(res => res.json()) .then(repos => { From b25f1b155059a72e918008099b917f92093abda2 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Fri, 8 Apr 2022 14:43:03 +0200 Subject: [PATCH 19/21] Added pull request info --- code/script.js | 3 ++- code/style.css | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/code/script.js b/code/script.js index 7c058572..42c07eba 100644 --- a/code/script.js +++ b/code/script.js @@ -89,9 +89,10 @@ const getPullRequests = (repos) => { const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; const thirdTitleToSearchFor = 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; + const fourthTitleToSearchFor = 'Project Elephant Quiz made by Sofie Pellegrini, Lisa Bergström, Jessica Sandler, Terese Claesson and Emma Berg' const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor) + .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor || pullRequest.title === fourthTitleToSearchFor) //If the length is 0 no pull request has been made if (myPullRequests.length === 0) { diff --git a/code/style.css b/code/style.css index 9e531409..8af54bb8 100644 --- a/code/style.css +++ b/code/style.css @@ -129,6 +129,10 @@ span { font-size: small; } +.commit-div { + margin-left: 2.5rem; +} + .commits-button { width: fit-content; margin: 1rem auto; @@ -137,6 +141,8 @@ span { color: var(--primary); background-color: var(--third); border: var(--third); + position: relative; + left: -1.3rem; } .commits-button:hover { From eb8bd28a089c492e25f94b092594fe8ac1dfb202 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Wed, 1 Jun 2022 15:43:24 +0200 Subject: [PATCH 20/21] Add PR title for project-auth --- code/script.js | 188 ++++++++++++++++++++++++------------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/code/script.js b/code/script.js index 42c07eba..46fc69f0 100644 --- a/code/script.js +++ b/code/script.js @@ -14,135 +14,136 @@ const API_REPOS = `${API_USER_INFO}/repos`; const fetchUserInfo = () => { fetch(API_USER_INFO) - .then(res => res.json()) - .then(user => { - userSection.innerHTML = ` + .then(res => res.json()) + .then(user => { + userSection.innerHTML = `

    ${user.name}

    Username: ${user.login}

    profile picture - `; - }); + `; + }); }; const getCommits = (pullRequestCommitsUrl, reponame) => { fetch(pullRequestCommitsUrl) - .then(res => res.json()) - .then(commits => { - - let repoDiv = document.getElementById(`${reponame}-div`); - let repoDivContent = document.getElementById(`${reponame}-div-content`); - - let commitParagraph = document.createElement('p'); - commitParagraph.innerHTML = `Number of commits: ${commits.length}`; - repoDivContent.appendChild(commitParagraph); - - // Create a new div to put the commit messages and the hide commits button in - let commitDiv = document.createElement('div'); - commitDiv.className = 'commit-div'; - commitDiv.style.display = 'none'; - repoDiv.appendChild(commitDiv); - - let commitMessageList = document.createElement('ol'); - commitMessageList.className = 'message-list'; - commitDiv.appendChild(commitMessageList); - - commits.forEach(commit => { - let commitMessage = document.createElement('li'); - commitMessage.innerHTML = commit.commit.message; - commitMessageList.appendChild(commitMessage); - }); - - // Buttons to show or hide commit comments - let showCommitsButton = document.createElement('button'); - showCommitsButton.className = 'commits-button'; - showCommitsButton.innerHTML = 'Show commits'; - repoDivContent.appendChild(showCommitsButton); + .then(res => res.json()) + .then(commits => { - let hideCommitsButton = document.createElement('button'); - hideCommitsButton.className = 'commits-button'; - hideCommitsButton.innerHTML = 'Hide commits'; - commitDiv.appendChild(hideCommitsButton); + let repoDiv = document.getElementById(`${reponame}-div`); + let repoDivContent = document.getElementById(`${reponame}-div-content`); - const showCommitMessageList = () => { - repoDivContent.style.display = 'none'; - commitDiv.style.display = 'block'; - } + let commitParagraph = document.createElement('p'); + commitParagraph.innerHTML = `Number of commits: ${commits.length}`; + repoDivContent.appendChild(commitParagraph); - const hideCommitMessageList = () => { + // Create a new div to put the commit messages and the hide commits button in + let commitDiv = document.createElement('div'); + commitDiv.className = 'commit-div'; commitDiv.style.display = 'none'; - repoDivContent.style.display = 'flex'; - } + repoDiv.appendChild(commitDiv); - showCommitsButton.addEventListener('click', showCommitMessageList); - hideCommitsButton.addEventListener('click', hideCommitMessageList); - }) + let commitMessageList = document.createElement('ol'); + commitMessageList.className = 'message-list'; + commitDiv.appendChild(commitMessageList); + + commits.forEach(commit => { + let commitMessage = document.createElement('li'); + commitMessage.innerHTML = commit.commit.message; + commitMessageList.appendChild(commitMessage); + }); + + // Buttons to show or hide commit comments + let showCommitsButton = document.createElement('button'); + showCommitsButton.className = 'commits-button'; + showCommitsButton.innerHTML = 'Show commits'; + repoDivContent.appendChild(showCommitsButton); + + let hideCommitsButton = document.createElement('button'); + hideCommitsButton.className = 'commits-button'; + hideCommitsButton.innerHTML = 'Hide commits'; + commitDiv.appendChild(hideCommitsButton); + + const showCommitMessageList = () => { + repoDivContent.style.display = 'none'; + commitDiv.style.display = 'block'; + } + + const hideCommitMessageList = () => { + commitDiv.style.display = 'none'; + repoDivContent.style.display = 'flex'; + } + + showCommitsButton.addEventListener('click', showCommitMessageList); + hideCommitsButton.addEventListener('click', hideCommitMessageList); + }) } const getPullRequests = (repos) => { repos.forEach(repo => { - + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`) - .then(res => res.json()) - .then(pullRequests => { + .then(res => res.json()) + .then(pullRequests => { - // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? - const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; - const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; - const thirdTitleToSearchFor = 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; - const fourthTitleToSearchFor = 'Project Elephant Quiz made by Sofie Pellegrini, Lisa Bergström, Jessica Sandler, Terese Claesson and Emma Berg' + // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? + const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; + const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; + const thirdTitleToSearchFor = 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; + const fourthTitleToSearchFor = 'Project Elephant Quiz made by Sofie Pellegrini, Lisa Bergström, Jessica Sandler, Terese Claesson and Emma Berg' + const fifthTitleToSearchFor = 'project-auth Lisa & Jessica'; - const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor || pullRequest.title === fourthTitleToSearchFor) + const myPullRequests = pullRequests + .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor || pullRequest.title === fourthTitleToSearchFor || pullRequest.title === fifthTitleToSearchFor) - //If the length is 0 no pull request has been made - if (myPullRequests.length === 0) { + //If the length is 0 no pull request has been made + if (myPullRequests.length === 0) { - let repoDivContent = document.getElementById(`${repo.name}-div-content`); - let commitParagraph = document.createElement('p'); + let repoDivContent = document.getElementById(`${repo.name}-div-content`); + let commitParagraph = document.createElement('p'); - commitParagraph.innerHTML = `No pull request found`; - commitParagraph.className = "no-pullrequest"; - - repoDivContent.appendChild(commitParagraph); - } + commitParagraph.innerHTML = `No pull request found`; + commitParagraph.className = "no-pullrequest"; - //Fetches the commits for all the projects where a pull request has been made - myPullRequests.forEach(myPullRequest => { - getCommits(myPullRequest.commits_url, repo.name); - }); - }) + repoDivContent.appendChild(commitParagraph); + } + + //Fetches the commits for all the projects where a pull request has been made + myPullRequests.forEach(myPullRequest => { + getCommits(myPullRequest.commits_url, repo.name); + }); + }) }) } // This function filters out repos that are forked and start with "project" const getTechnigoRepos = (repos) => { return repos - .filter(repo => repo.fork === true && repo.name.startsWith("project")) + .filter(repo => repo.fork === true && repo.name.startsWith("project")) }; const fetchRepos = () => { fetch(API_REPOS) - .then(res => res.json()) - .then(repos => { - - const technigoRepos = getTechnigoRepos(repos); - - getPullRequests(technigoRepos); - - projectSection.innerHTML = ` + .then(res => res.json()) + .then(repos => { + + const technigoRepos = getTechnigoRepos(repos); + + getPullRequests(technigoRepos); + + projectSection.innerHTML = `

    My Technigo projects:

    `; - // Get the number of forked Technigo projects and draw the chart - const numberOfTechnigoRepos = technigoRepos.length; - drawChart(numberOfTechnigoRepos); - - technigoRepos.forEach((repo) => { - - const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); + // Get the number of forked Technigo projects and draw the chart + const numberOfTechnigoRepos = technigoRepos.length; + drawChart(numberOfTechnigoRepos); + + technigoRepos.forEach((repo) => { - repoContainer.innerHTML += ` + const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); + + repoContainer.innerHTML += `

    ${repo.name}

    @@ -151,9 +152,9 @@ const fetchRepos = () => {
    `; - + + }); }); - }); }; @@ -161,4 +162,3 @@ fetchUserInfo(); fetchRepos(); - \ No newline at end of file From d5acff07e44118224fd782c3ae648ac0a4fc87e1 Mon Sep 17 00:00:00 2001 From: Jessica Sandler Date: Sun, 5 Feb 2023 11:27:50 +0100 Subject: [PATCH 21/21] Uncomment options in script.js --- code/script.js | 252 +++++++++++++++++++++++++------------------------ 1 file changed, 130 insertions(+), 122 deletions(-) diff --git a/code/script.js b/code/script.js index 46fc69f0..75794be6 100644 --- a/code/script.js +++ b/code/script.js @@ -1,149 +1,161 @@ -const userSection = document.getElementById("user"); -const projectSection = document.getElementById("projects"); +const userSection = document.getElementById('user'); +const projectSection = document.getElementById('projects'); const username = 'jessand77'; const API_USER_INFO = `https://api.github.com/users/${username}`; const API_REPOS = `${API_USER_INFO}/repos`; -// const options = { -// method: 'GET', -// headers: { -// Authorization: 'token ' + API_TOKEN -// } -// }; +const options = { + method: 'GET', + headers: { + Authorization: 'token ' + API_TOKEN, + }, +}; const fetchUserInfo = () => { - fetch(API_USER_INFO) - .then(res => res.json()) - .then(user => { - userSection.innerHTML = ` + fetch(API_USER_INFO) + .then((res) => res.json()) + .then((user) => { + userSection.innerHTML = `

    ${user.name}

    Username: ${user.login}

    profile picture `; - }); + }); }; const getCommits = (pullRequestCommitsUrl, reponame) => { - fetch(pullRequestCommitsUrl) - .then(res => res.json()) - .then(commits => { - - let repoDiv = document.getElementById(`${reponame}-div`); - let repoDivContent = document.getElementById(`${reponame}-div-content`); - - let commitParagraph = document.createElement('p'); - commitParagraph.innerHTML = `Number of commits: ${commits.length}`; - repoDivContent.appendChild(commitParagraph); - - // Create a new div to put the commit messages and the hide commits button in - let commitDiv = document.createElement('div'); - commitDiv.className = 'commit-div'; - commitDiv.style.display = 'none'; - repoDiv.appendChild(commitDiv); - - let commitMessageList = document.createElement('ol'); - commitMessageList.className = 'message-list'; - commitDiv.appendChild(commitMessageList); - - commits.forEach(commit => { - let commitMessage = document.createElement('li'); - commitMessage.innerHTML = commit.commit.message; - commitMessageList.appendChild(commitMessage); - }); - - // Buttons to show or hide commit comments - let showCommitsButton = document.createElement('button'); - showCommitsButton.className = 'commits-button'; - showCommitsButton.innerHTML = 'Show commits'; - repoDivContent.appendChild(showCommitsButton); - - let hideCommitsButton = document.createElement('button'); - hideCommitsButton.className = 'commits-button'; - hideCommitsButton.innerHTML = 'Hide commits'; - commitDiv.appendChild(hideCommitsButton); - - const showCommitMessageList = () => { - repoDivContent.style.display = 'none'; - commitDiv.style.display = 'block'; - } - - const hideCommitMessageList = () => { - commitDiv.style.display = 'none'; - repoDivContent.style.display = 'flex'; - } - - showCommitsButton.addEventListener('click', showCommitMessageList); - hideCommitsButton.addEventListener('click', hideCommitMessageList); - }) -} + fetch(pullRequestCommitsUrl) + .then((res) => res.json()) + .then((commits) => { + let repoDiv = document.getElementById(`${reponame}-div`); + let repoDivContent = document.getElementById(`${reponame}-div-content`); + + let commitParagraph = document.createElement('p'); + commitParagraph.innerHTML = `Number of commits: ${commits.length}`; + repoDivContent.appendChild(commitParagraph); + + // Create a new div to put the commit messages and the hide commits button in + let commitDiv = document.createElement('div'); + commitDiv.className = 'commit-div'; + commitDiv.style.display = 'none'; + repoDiv.appendChild(commitDiv); + + let commitMessageList = document.createElement('ol'); + commitMessageList.className = 'message-list'; + commitDiv.appendChild(commitMessageList); + + commits.forEach((commit) => { + let commitMessage = document.createElement('li'); + commitMessage.innerHTML = commit.commit.message; + commitMessageList.appendChild(commitMessage); + }); + + // Buttons to show or hide commit comments + let showCommitsButton = document.createElement('button'); + showCommitsButton.className = 'commits-button'; + showCommitsButton.innerHTML = 'Show commits'; + repoDivContent.appendChild(showCommitsButton); + + let hideCommitsButton = document.createElement('button'); + hideCommitsButton.className = 'commits-button'; + hideCommitsButton.innerHTML = 'Hide commits'; + commitDiv.appendChild(hideCommitsButton); + + const showCommitMessageList = () => { + repoDivContent.style.display = 'none'; + commitDiv.style.display = 'block'; + }; + + const hideCommitMessageList = () => { + commitDiv.style.display = 'none'; + repoDivContent.style.display = 'flex'; + }; + + showCommitsButton.addEventListener('click', showCommitMessageList); + hideCommitsButton.addEventListener('click', hideCommitMessageList); + }); +}; const getPullRequests = (repos) => { - repos.forEach(repo => { - - fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`) - .then(res => res.json()) - .then(pullRequests => { - - // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? - const firstTitleToSearchFor = 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; - const secondTitleToSearchFor = 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; - const thirdTitleToSearchFor = 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; - const fourthTitleToSearchFor = 'Project Elephant Quiz made by Sofie Pellegrini, Lisa Bergström, Jessica Sandler, Terese Claesson and Emma Berg' - const fifthTitleToSearchFor = 'project-auth Lisa & Jessica'; - - const myPullRequests = pullRequests - .filter(pullRequest => pullRequest.user.login === username || pullRequest.title === firstTitleToSearchFor || pullRequest.title === secondTitleToSearchFor || pullRequest.title === thirdTitleToSearchFor || pullRequest.title === fourthTitleToSearchFor || pullRequest.title === fifthTitleToSearchFor) - - //If the length is 0 no pull request has been made - if (myPullRequests.length === 0) { - - let repoDivContent = document.getElementById(`${repo.name}-div-content`); - let commitParagraph = document.createElement('p'); - - commitParagraph.innerHTML = `No pull request found`; - commitParagraph.className = "no-pullrequest"; - - repoDivContent.appendChild(commitParagraph); - } - - //Fetches the commits for all the projects where a pull request has been made - myPullRequests.forEach(myPullRequest => { - getCommits(myPullRequest.commits_url, repo.name); - }); - }) - }) -} + repos.forEach((repo) => { + fetch( + `https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100` + ) + .then((res) => res.json()) + .then((pullRequests) => { + // How can I get the pull requests for the repos that I am not the owner of without hardcoding like this? + const firstTitleToSearchFor = + 'Week 4 project - Sofie Pellegrini & Jessica Sandler'; + const secondTitleToSearchFor = + 'Week 6 project : Jessica - Maurii - Nadia - Rijad - Terese'; + const thirdTitleToSearchFor = + 'Week 9: Jessica Sandler, Laura Sjölander and Nadia Lefebvre'; + const fourthTitleToSearchFor = + 'Project Elephant Quiz made by Sofie Pellegrini, Lisa Bergström, Jessica Sandler, Terese Claesson and Emma Berg'; + const fifthTitleToSearchFor = 'project-auth Lisa & Jessica'; + + const myPullRequests = pullRequests.filter( + (pullRequest) => + pullRequest.user.login === username || + pullRequest.title === firstTitleToSearchFor || + pullRequest.title === secondTitleToSearchFor || + pullRequest.title === thirdTitleToSearchFor || + pullRequest.title === fourthTitleToSearchFor || + pullRequest.title === fifthTitleToSearchFor + ); + + //If the length is 0 no pull request has been made + if (myPullRequests.length === 0) { + let repoDivContent = document.getElementById( + `${repo.name}-div-content` + ); + let commitParagraph = document.createElement('p'); + + commitParagraph.innerHTML = `No pull request found`; + commitParagraph.className = 'no-pullrequest'; + + repoDivContent.appendChild(commitParagraph); + } + + //Fetches the commits for all the projects where a pull request has been made + myPullRequests.forEach((myPullRequest) => { + getCommits(myPullRequest.commits_url, repo.name); + }); + }); + }); +}; // This function filters out repos that are forked and start with "project" const getTechnigoRepos = (repos) => { - return repos - .filter(repo => repo.fork === true && repo.name.startsWith("project")) + return repos.filter( + (repo) => repo.fork === true && repo.name.startsWith('project') + ); }; const fetchRepos = () => { - fetch(API_REPOS) - .then(res => res.json()) - .then(repos => { + fetch(API_REPOS) + .then((res) => res.json()) + .then((repos) => { + const technigoRepos = getTechnigoRepos(repos); - const technigoRepos = getTechnigoRepos(repos); + getPullRequests(technigoRepos); - getPullRequests(technigoRepos); - - projectSection.innerHTML = ` + projectSection.innerHTML = `

    My Technigo projects:

    `; - // Get the number of forked Technigo projects and draw the chart - const numberOfTechnigoRepos = technigoRepos.length; - drawChart(numberOfTechnigoRepos); - - technigoRepos.forEach((repo) => { + // Get the number of forked Technigo projects and draw the chart + const numberOfTechnigoRepos = technigoRepos.length; + drawChart(numberOfTechnigoRepos); - const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString('en-GB'); + technigoRepos.forEach((repo) => { + const mostRecentPush = new Date(repo.pushed_at).toLocaleDateString( + 'en-GB' + ); - repoContainer.innerHTML += ` + repoContainer.innerHTML += `

    ${repo.name}

    @@ -152,13 +164,9 @@ const fetchRepos = () => {
    `; - - }); - }); + }); + }); }; - fetchUserInfo(); fetchRepos(); - -