@@ -8,105 +8,162 @@ class PublicationsLoader {
88 this . userGoogleScholarId = 'XVt7BYQAAAAJ' ;
99 this . cacheKey = 'scholar_publications' ;
1010 this . publicationsJsonUrl = '/assets/data/publications.json' ;
11+ this . fallbackPatents = [
12+ {
13+ title : "TxPert: AI-Driven Perturbation Prediction System" ,
14+ authors : "Russell, C.T., et al." ,
15+ year : 2025 ,
16+ venue : "Patent Pending" ,
17+ link : "#" ,
18+ doi : null ,
19+ citations : 0
20+ } ,
21+ {
22+ title : "HOOK-1: Novel Therapeutic Target Discovery Platform" ,
23+ authors : "Russell, C.T., et al." ,
24+ year : 2025 ,
25+ venue : "Patent Pending" ,
26+ link : "#" ,
27+ doi : null ,
28+ citations : 0
29+ }
30+ ] ;
1131 this . fallbackPublications = [
1232 {
1333 title : "TxPert: Leveraging Biochemical Relationships for Out-of-Distribution Perturbation Prediction" ,
1434 authors : "Russell, C.T., et al." ,
1535 year : 2025 ,
16- venue : "arXiv preprint" ,
17- link : "https://arxiv.org/abs/2505.14919" ,
18- doi : null
36+ venue : "NeurIPS 2025" ,
37+ link : "https://neurips.cc/virtual/2025/loc/san-diego/poster/116558" ,
38+ doi : null ,
39+ citations : 0
1940 } ,
2041 {
2142 title : "DL4MicEverywhere: Deep learning for microscopy made flexible, shareable and reproducible" ,
2243 authors : "Gómez-de-Mariscal, E., Russell, C.T., et al." ,
2344 year : 2024 ,
2445 venue : "Nature Methods" ,
2546 link : "https://doi.org/10.1038/s41592-024-02295-6" ,
26- doi : "10.1038/s41592-024-02295-6"
47+ doi : "10.1038/s41592-024-02295-6" ,
48+ citations : 12
49+ } ,
50+ {
51+ title : "The BioImage Archive–building a home for life-sciences microscopy data" ,
52+ authors : "Hartley, M., Gault, D., Donovan, C., Mahood, R., Oyetunde, A., Russell, C.T., et al." ,
53+ year : 2023 ,
54+ venue : "Nucleic Acids Research" ,
55+ link : "https://doi.org/10.1093/nar/gkac1072" ,
56+ doi : "10.1093/nar/gkac1072" ,
57+ citations : 15
2758 } ,
2859 {
2960 title : "The COVID-19 Data Portal: accelerating SARS-CoV-2 and COVID-19 research through rapid open access data sharing" ,
3061 authors : "Harrison, P.W., Lopez, R., Rahman, N., Russell, C.T., et al." ,
3162 year : 2021 ,
3263 venue : "Nucleic Acids Research" ,
3364 link : "https://doi.org/10.1093/nar/gkab417" ,
34- doi : "10.1093/nar/gkab417"
65+ doi : "10.1093/nar/gkab417" ,
66+ citations : 89
3567 } ,
3668 {
3769 title : "Frame localisation optical projection tomography" ,
3870 authors : "Russell, C.T., Vallejo Ramirez, P.P., Rees, E.J." ,
3971 year : 2021 ,
4072 venue : "Scientific Reports" ,
4173 link : "https://doi.org/10.1038/s41598-021-84002-5" ,
42- doi : "10.1038/s41598-021-84002-5"
74+ doi : "10.1038/s41598-021-84002-5" ,
75+ citations : 3
4376 } ,
4477 {
4578 title : "mmSIM: An open toolbox for accessible structured illumination microscopy" ,
4679 authors : "Russell, C.T., Shaw, M." ,
4780 year : 2021 ,
4881 venue : "Philosophical Transactions A" ,
4982 link : "https://doi.org/10.1098/rsta.2020.0353" ,
50- doi : "10.1098/rsta.2020.0353"
83+ doi : "10.1098/rsta.2020.0353" ,
84+ citations : 7
5185 } ,
5286 {
5387 title : "An open-hardware sample mounting solution for inverted lightsheet microscopes" ,
5488 authors : "Russell, C.T., Rees, E.J." ,
5589 year : 2020 ,
5690 venue : "Journal of Microscopy" ,
5791 link : "https://doi.org/10.1111/jmi.12935" ,
58- doi : "10.1111/jmi.12935"
92+ doi : "10.1111/jmi.12935" ,
93+ citations : 4
5994 } ,
6095 {
6196 title : "Helminth Defense Molecules as Design Templates for Membrane Active Antibiotics" ,
6297 authors : "Hammond, K., Lewis, H., Faruqui, N., Russell, C.T., et al." ,
6398 year : 2019 ,
6499 venue : "ACS Infectious Diseases" ,
65100 link : "https://doi.org/10.1021/acsinfecdis.9b00157" ,
66- doi : "10.1021/acsinfecdis.9b00157"
101+ doi : "10.1021/acsinfecdis.9b00157" ,
102+ citations : 21
67103 } ,
68104 {
69105 title : "Homographically generated light sheets for the microscopy of large specimens" ,
70106 authors : "Russell, C.T., Rees, E.J., Kaminski, C.F." ,
71107 year : 2018 ,
72108 venue : "Optics Letters" ,
73109 link : "https://doi.org/10.1364/OL.43.000663" ,
74- doi : "10.1364/OL.43.000663"
110+ doi : "10.1364/OL.43.000663" ,
111+ citations : 8
75112 }
76113 ] ;
77114 this . corsProxy = 'https://api.allorigins.win/raw?url=' ;
78115 }
79116
80117 async init ( ) {
81118 try {
82- // Try to load from JSON file first (stored in repo)
119+ let publications = null ;
120+ let patents = null ;
121+ let source = 'fallback' ;
122+
123+ // Try JSON file
83124 const jsonData = await this . loadFromJson ( ) ;
84125 if ( jsonData ) {
85- console . log ( 'Loading publications from JSON file' ) ;
86- this . renderPublications ( jsonData , 'json' ) ;
87- return ;
126+ if ( jsonData . publications && jsonData . publications . length > 0 ) {
127+ publications = jsonData . publications ;
128+ source = 'json' ;
129+ console . log ( 'Loaded publications from JSON file' ) ;
130+ }
131+ if ( jsonData . patents && jsonData . patents . length > 0 ) {
132+ patents = jsonData . patents ;
133+ console . log ( 'Loaded patents from JSON file' ) ;
134+ }
88135 }
89136
90- // Fallback to localStorage cache
91- const cachedData = this . getCachedPublications ( ) ;
92- if ( cachedData ) {
93- console . log ( 'Loading publications from localStorage cache' ) ;
94- this . renderPublications ( cachedData . publications , 'cache' ) ;
95- return ;
137+ // Try localStorage cache if JSON failed
138+ if ( ! publications || ! patents ) {
139+ const cachedData = this . getCachedPublications ( ) ;
140+ if ( cachedData ) {
141+ if ( ! publications && cachedData . publications ) {
142+ publications = cachedData . publications ;
143+ source = 'cache' ;
144+ }
145+ if ( ! patents && cachedData . patents ) {
146+ patents = cachedData . patents ;
147+ }
148+ }
96149 }
97150
98- // Last resort: fetch from API
99- const publications = await this . fetchPublications ( ) ;
100- if ( publications && publications . length > 0 ) {
101- this . cachePublications ( publications ) ;
102- this . renderPublications ( publications , 'api' ) ;
103- } else {
104- console . warn ( 'No publications available from any source' ) ;
105- this . showError ( ) ;
151+ // Use fallback if we have nothing
152+ if ( ! publications || publications . length < this . fallbackPublications . length ) {
153+ publications = this . fallbackPublications ;
154+ source = 'fallback' ;
155+ }
156+ if ( ! patents || patents . length < this . fallbackPatents . length ) {
157+ patents = this . fallbackPatents ;
106158 }
159+
160+ this . renderPatents ( patents , source ) ;
161+ this . renderPublications ( publications , source ) ;
162+
107163 } catch ( error ) {
108- console . warn ( 'Failed to load publications:' , error ) ;
109- this . showError ( ) ;
164+ console . warn ( 'Error in init, using fallback:' , error ) ;
165+ this . renderPatents ( this . fallbackPatents , 'fallback' ) ;
166+ this . renderPublications ( this . fallbackPublications , 'fallback' ) ;
110167 }
111168 }
112169
@@ -216,6 +273,24 @@ class PublicationsLoader {
216273 return yearMatch ? parseInt ( yearMatch [ 0 ] ) : new Date ( ) . getFullYear ( ) ;
217274 }
218275
276+ renderPatents ( patents , source = 'unknown' ) {
277+ const container = document . getElementById ( 'patents-list' ) ;
278+ if ( ! container ) return ;
279+
280+ patents . sort ( ( a , b ) => ( b . year || 0 ) - ( a . year || 0 ) ) ;
281+
282+ const html = patents . map ( ( patent , index ) => {
283+ return `
284+ <div class="patent-item" data-year="${ patent . year } ">
285+ <p><strong>${ index + 1 } .</strong> ${ patent . authors } (${ patent . year } ).
286+ "${ patent . title } " <em>${ patent . venue } </em>.</p>
287+ </div>
288+ ` ;
289+ } ) . join ( '' ) ;
290+
291+ container . innerHTML = html ;
292+ }
293+
219294 renderPublications ( publications , source = 'unknown' ) {
220295 const container = document . getElementById ( 'publications-list' ) ;
221296 if ( ! container ) return ;
@@ -241,8 +316,9 @@ class PublicationsLoader {
241316 // Add source indicator
242317 const sourceLabels = {
243318 'json' : 'repository data' ,
244- 'cache' : 'cached data' ,
245- 'api' : 'live API'
319+ 'cache' : 'cached data' ,
320+ 'api' : 'live API' ,
321+ 'fallback' : 'curated list'
246322 } ;
247323
248324 const updateInfo = document . createElement ( 'p' ) ;
@@ -257,7 +333,7 @@ class PublicationsLoader {
257333 const response = await fetch ( this . publicationsJsonUrl ) ;
258334 if ( response . ok ) {
259335 const data = await response . json ( ) ;
260- return data . publications || data ; // Handle different JSON structures
336+ return data ;
261337 }
262338 } catch ( error ) {
263339 console . warn ( 'Failed to load JSON file:' , error ) ;
@@ -280,14 +356,15 @@ class PublicationsLoader {
280356 }
281357 }
282358
283- cachePublications ( publications ) {
359+ cachePublications ( publications , patents ) {
284360 try {
285361 const data = {
286362 publications : publications ,
363+ patents : patents ,
287364 timestamp : Date . now ( )
288365 } ;
289366 localStorage . setItem ( this . cacheKey , JSON . stringify ( data ) ) ;
290- console . log ( 'Publications cached successfully' ) ;
367+ console . log ( 'Publications and patents cached successfully' ) ;
291368 } catch ( error ) {
292369 console . warn ( 'Error caching publications:' , error ) ;
293370 }
0 commit comments