@rcsb/rcsb-statistics 0.3.44-dev.aipcb.1 → 0.3.44-dev.aipcb.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- (self.webpackChunk_rcsb_rcsb_statistics=self.webpackChunk_rcsb_rcsb_statistics||[]).push([[81],{8596(e,t,r){function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach(function(t){i(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function i(e,t,r){return(t=function(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const o=r(3482),l=e=>Boolean(e&&"object"==typeof e&&!Array.isArray(e)),s=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),c=e=>{throw new Error(e)};function u(e,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"Chart";if(t.$ref)return u(e,r.$defs[t.$ref.split("/").pop()],r,n);if(t.anyOf)return void(t.anyOf.some(t=>{try{return u(e,t,r,n),!0}catch(e){return!1}})||c("".concat(n," has an invalid value.")));const a=t.type;("object"===a&&!l(e)||"array"===a&&!Array.isArray(e)||"integer"===a&&!Number.isInteger(e)||"number"===a&&("number"!=typeof e||!Number.isFinite(e))||"string"===a&&"string"!=typeof e||"boolean"===a&&"boolean"!=typeof e)&&c("".concat(n," must be ").concat(a,".")),t.enum&&!t.enum.includes(e)&&c("".concat(n," is not supported.")),"number"==typeof e&&(void 0!==t.minimum&&e<t.minimum||void 0!==t.maximum&&e>t.maximum)&&c("".concat(n," is outside the supported range.")),"string"==typeof e&&(t.minLength&&e.trim().length<t.minLength||t.maxLength&&e.length>t.maxLength||/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/.test(e))&&c("".concat(n," has invalid text.")),Array.isArray(e)&&((t.minItems&&e.length<t.minItems||t.maxItems&&e.length>t.maxItems||t.uniqueItems&&new Set(e.map(e=>JSON.stringify(e))).size!==e.length)&&c("".concat(n," has an invalid number of items.")),e.forEach((e,a)=>u(e,t.items,r,"".concat(n,"[").concat(a,"]")))),l(e)&&((t.required||[]).forEach(t=>{s(e,t)||c("".concat(n,".").concat(t," is required."))}),Object.keys(e).forEach(a=>{s(t.properties||{},a)?u(e[a],t.properties[a],r,"".concat(n,".").concat(a)):!1===t.additionalProperties&&c("".concat(n,".").concat(a," is not supported."))}))}function m(e){u(e,o.specSchema);const t=JSON.parse(JSON.stringify(e)),r=o.dimensions[t.dimension];return"line"!==t.chartType||r.ordered&&"vertical"===t.orientation&&"labelAsc"===t.sort||c("Line charts require release year or resolution, vertical orientation, and ascending labels."),"pie"===t.chartType&&(r.overlapping||1!==t.series.length||t.cumulative||"linear"!==t.scale)&&c("Pie charts require a single non-overlapping series (release year or methodology), linear scale, and non-cumulative values."),!t.cumulative||"releaseYear"===t.dimension&&"labelAsc"===t.sort||c("Cumulative charts require release year in chronological order."),"percent"===t.measure&&"linear"!==t.scale&&c("Percentages require a linear scale."),new Set(t.series.map(e=>e.label)).size!==t.series.length&&c("Give each comparison series a different label."),[t.filters,...t.series.map(e=>e.filters)].forEach(e=>e.forEach(e=>{const t=o.filters[e.field];t.operators.includes(e.operator)||c("Unsupported operator for ".concat(t.label,".")),"in"===e.operator?(Array.isArray(e.value)||c("".concat(t.label," requires a list.")),e.value.forEach(e=>{"taxonomy"===t.kind?(!Number.isInteger(e)||e<=0)&&c("Taxonomy IDs must be positive integers."):("string"!=typeof e||t.values&&!t.values.includes(e)||"identifier"===t.kind&&!/^[A-Z0-9]{1,10}$/.test(e))&&c("Invalid value for ".concat(t.label,"."))})):("number"!=typeof e.value||e.value<t.minimum||e.value>t.maximum||"year"===t.kind&&!Number.isInteger(e.value))&&c("Invalid range for ".concat(t.label,"."))})),t.series.forEach(e=>{const r=[...t.filters,...e.filters];["releaseYear","resolution"].forEach(e=>{const t=r.filter(t=>t.field===e&&"gte"===t.operator).map(e=>e.value),n=r.filter(t=>t.field===e&&"lte"===t.operator).map(e=>e.value);t.length&&n.length&&Math.max(...t)>Math.min(...n)&&c("The ".concat(e," lower bound exceeds its upper bound."))}),"integrativeInput"===t.dimension&&r.some(e=>"methodology"===e.field&&!e.value.includes("integrative"))&&c("Integrative input charts cannot exclude integrative structures.")}),t}function p(e){const t=o.filters[e.field];let r=e.value;return"year"===t.kind&&(r="".concat(r,"-").concat("gte"===e.operator?"01-01":"12-31")),{type:"terminal",service:"text",parameters:{attribute:t.attribute,operator:{in:"in",gte:"greater_or_equal",lte:"less_or_equal"}[e.operator],value:r}}}function d(e){const t=new Set;return e.flatMap(r=>{const n=o.filters[r.field];if(!["number","year"].includes(n.kind))return[p(r)];if(t.has(r.field))return[];t.add(r.field);const i=e.filter(e=>e.field===r.field),l=i.filter(e=>"gte"===e.operator).map(e=>e.value),s=i.filter(e=>"lte"===e.operator).map(e=>e.value);if(!l.length||!s.length)return[p(a(a({},r),{},{operator:l.length?"gte":"lte",value:l.length?Math.max(...l):Math.min(...s)}))];const c=Math.max(...l),u=Math.min(...s);return[{type:"terminal",service:"text",parameters:{attribute:n.attribute,operator:"range",value:{from:"year"===n.kind?"".concat(c,"-01-01"):c,to:"year"===n.kind?"".concat(u,"-12-31"):u,include_lower:!0,include_upper:!0}}}]})}function h(e){return"".concat(o.filters[e.field].label," ").concat("in"===e.operator?"is any of":"gte"===e.operator?"≥":"≤"," ").concat(Array.isArray(e.value)?e.value.join(", "):e.value)}function g(e){const t=[];return o.dimensions[e.dimension].overlapping&&t.push("An entry may occur in more than one category. Bucket counts must not be summed as a unique entry total."),e.series.length>1&&t.push("Comparison cohorts may overlap; each is counted independently."),"sourceOrganism"===e.dimension&&t.push("Source organisms are those recorded for any matching entry; they are not expression hosts. All source types are included."),"releaseYear"===e.dimension&&t.push("Counts describe the current archive by initial release year, not historical archive snapshots. The current year is incomplete."),e.cumulative&&t.push("Cumulative values begin at the earliest year included by the filters."),"logarithmic"===e.scale&&t.push("Zero values are omitted from the logarithmic chart; the table retains them."),"percent"===e.measure&&t.push("The denominator is every matching entry in that series, including entries missing the chart attribute."),t}e.exports={catalog:o,validateSchema:u,validateChartSpec:m,buildChartRequests:function(e){const t=m(e),r=o.dimensions[t.dimension],n={name:"chart",aggregation_type:r.aggregation,attribute:r.attribute,min_interval_population:1};return"terms"===r.aggregation&&(n.max_num_intervals=1e3),"date_histogram"===r.aggregation&&(n.interval="year"),"histogram"===r.aggregation&&(n.interval=t.interval),t.series.map(e=>{const a=[...t.filters,...e.filters,...r.requiredFilter?[r.requiredFilter]:[]],i={return_type:"entry",request_options:{results_content_type:["experimental"],paginate:{start:0,rows:0},facets:[n]}};return a.length&&(i.query={type:"group",logical_operator:"and",nodes:d(a).map(e=>({type:"group",logical_operator:"and",nodes:[e]}))}),i})},describeFilter:h,describeChart:function(e){return m(e),"".concat(e.cumulative?"Cumulative ":"").concat("count"===e.measure?"PDB entry counts":"Percentage of matching PDB entries"," by ").concat(o.dimensions[e.dimension].label.toLowerCase(),"; ").concat(e.chartType," chart; ").concat(e.series.length," ").concat(1===e.series.length?"series":"comparison series",".")},chartWarnings:g,chartChanges:function(e,t){return e?(m(e),Object.keys(t).filter(r=>JSON.stringify(e[r])!==JSON.stringify(t[r])).map(r=>"filters"===r?"Filters: ".concat(t.filters.length?t.filters.map(h).join("; "):"none","."):"series"===r?"Series: ".concat(t.series.map(e=>"".concat(e.label).concat(e.filters.length?" (".concat(e.filters.map(h).join("; "),")"):"")).join("; "),"."):"".concat(r,": ").concat(String(e[r])," → ").concat(String(t[r])))):["Create a new chart."]},formatChartData:function(e,t){const r=m(e);Array.isArray(t)&&t.length===r.series.length||c("A response is required for every chart series.");const n=o.dimensions[r.dimension];let i=!1;const s=t.map((e,t)=>{var n;(!l(e)||!Number.isInteger(e.total_count)||e.total_count<0)&&c("The Search API did not return a valid entry count.");const a=null===(n=e.facets)||void 0===n||null===(n=n.find(e=>"chart"===e.name))||void 0===n?void 0:n.buckets;Array.isArray(a)||0===e.total_count||c("The Search API did not return the requested chart aggregation."),(a||[]).length>=1e3&&(i=!0);const o=new Map;return(a||[]).forEach(t=>{(!Number.isInteger(t.population)||t.population<0||t.population>e.total_count||!["string","number"].includes(typeof t.label)||String(t.label).length>300)&&c("The Search API returned an invalid chart bucket.");let n=String(t.label);if("releaseYear"===r.dimension){const e=n.match(/\d{4}/);e||c("The Search API returned an invalid release year."),n=e[0]}"resolution"===r.dimension&&((!Number.isFinite(Number(n))||Number(n)<0)&&c("The Search API returned an invalid resolution interval."),n=String(Number(Number(n).toPrecision(12)))),o.has(n)&&c("The Search API returned duplicate chart buckets."),o.set(n,t.population)}),{label:r.series[t].label,total:e.total_count,values:o}});let u=[...new Set(s.flatMap(e=>[...e.values.keys()]))];const p=u.every(e=>Number.isFinite(Number(e)));if(u.sort((e,t)=>p?Number(e)-Number(t):e.localeCompare(t)),"releaseYear"===r.dimension&&u.length){const e=Number(u[0]),t=Number(u[u.length-1]);t-e>200&&c("The Search API returned an unsupported year range."),u=Array.from({length:t-e+1},(t,r)=>String(e+r))}if("resolution"===r.dimension&&u.length){const e=Number(u[0]),t=Math.round((Number(u[u.length-1])-e)/r.interval)+1;t>1e3&&c("This resolution histogram exceeds 1,000 bins. Increase the bin width or narrow the resolution range."),u=Array.from({length:t},(t,n)=>String(Number((e+n*r.interval).toPrecision(12))))}const d=u.map(e=>({label:e,counts:s.map(t=>t.values.get(e)||0)}));if(r.cumulative){const e=s.map(()=>0);d.forEach(t=>{t.counts=t.counts.map((t,r)=>e[r]+=t)})}"countDesc"===r.sort&&d.sort((e,t)=>t.counts.reduce((e,t)=>e+t,0)-e.counts.reduce((e,t)=>e+t,0)||e.label.localeCompare(t.label));const h=!n.ordered,y=(h?d.slice(0,r.topN):d).map(e=>a(a({},e),{},{values:e.counts.map((e,t)=>"percent"===r.measure?s[t].total?100*e/s[t].total:0:e)})),f=g(r);return h&&d.length>y.length&&f.push("Showing ".concat(y.length," of ").concat(d.length).concat(i?"+":""," categories returned. Omitted categories are not combined into an invented “Other” count.")),i&&f.push("The category aggregation reached its 1,000-bucket limit. Narrow the filters for a more complete category listing."),"pie"!==r.chartType||!i&&y.length===d.length||c("A pie chart must show all categories. Increase the category limit or use a bar chart."),"pie"===r.chartType&&y.reduce((e,t)=>e+t.counts[0],0)!==s[0].total&&c("A pie chart requires complete, non-overlapping categories covering every matching entry. Use a bar chart for this population."),{rows:y,series:s.map(e=>({label:e.label,total:e.total})),warnings:f,retrievedAt:(new Date).toISOString(),categoryCount:d.length}}}},8081(e,t,r){"use strict";r.r(t),r.d(t,{default:()=>R});var n=r(9711),a=r(4062),i=r(8354),o=r(2917),l=r(5411),s=r(5042);const c=s.YrT,u=s.cO3,m=s.kGk,p=s.VSk,d=s.yGN,h=s.a4x,g=s.QPV,y=s.vQY;var f=r(9281),b=r(8596);function v(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function E(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?v(Object(r),!0).forEach(function(t){w(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):v(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function w(e,t,r){return(t=function(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const A=e=>{const t=String(e);return'"'.concat((/^[\s]*[=+@-]|^[\t\r\n]/.test(t)?"'".concat(t):t).replace(/"/g,'""'),'"')};function S(e,t,r){const n=URL.createObjectURL(new Blob([e],{type:r})),a=document.createElement("a");a.href=n,a.download=t,a.click(),setTimeout(()=>URL.revokeObjectURL(n),0)}var O=r(8804),N=r(6619);function P(e,t,r){const n=[];let a="";for(const i of t.split(/\s+/)){const t=a?"".concat(a," ").concat(i):i;for(a&&e.measureText(t).width>r?(n.push(a),a=i):a=t;e.measureText(a).width>r&&a.length>1;){let t=a.length-1;for(;t>1&&e.measureText(a.slice(0,t)).width>r;)t--;n.push(a.slice(0,t)),a=a.slice(t)}}return a.trim()&&n.push(a.trim()),n}function x(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function C(e,t,r){return(t=function(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function I(e){let t=e.spec,r=e.data,i=e.preview,o=void 0!==i&&i;const l=(0,f.t)().settings,s=(0,n.useRef)(null),c=(k=(0,n.useState)(!1),j=2,function(e){if(Array.isArray(e))return e}(k)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,o,l=[],s=!0,c=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(l.push(n.value),l.length!==t);s=!0);}catch(e){c=!0,a=e}finally{try{if(!s&&null!=r.return&&(o=r.return(),Object(o)!==o))return}finally{if(c)throw a}}return l}}(k,j)||function(e,t){if(e){if("string"==typeof e)return _(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_(e,t):void 0}}(k,j)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),u=c[0],m=c[1],p=l.colorScheme,d=t.categoryLabel||b.catalog.dimensions[t.dimension].label,v=t.valueLabel||("percent"===t.measure?"Matching PDB entries (%)":"Number of PDB entries"),E="bar"===t.chartType&&"horizontal"===t.orientation,w={labels:r.rows.map(e=>"resolution"===t.dimension?"".concat(e.label,"–").concat(Number((Number(e.label)+t.interval).toFixed(3))," Å"):e.label),datasets:r.series.map((e,n)=>({label:e.label,data:r.rows.map(e=>"logarithmic"===t.scale&&0===e.values[n]?null:e.values[n]),backgroundColor:"pie"===t.chartType?r.rows.map((e,t)=>p[t%p.length]):p[n%p.length],borderColor:p[n%p.length],borderWidth:"line"===t.chartType?2:1,pointRadius:r.rows.length>40?1:3,tension:.15}))},N=function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?x(Object(r),!0).forEach(function(t){C(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):x(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}({responsive:!0,maintainAspectRatio:!1,animation:!1,indexAxis:E?"y":"x",plugins:{legend:{display:"pie"===t.chartType||r.series.length>1,position:"bottom"},tooltip:{callbacks:{label:e=>"".concat(e.dataset.label,": ").concat(Number(e.raw).toLocaleString(void 0,{maximumFractionDigits:2})).concat("percent"===t.measure?"%":" entries")}}}},"pie"===t.chartType?{}:{scales:{[E?"x":"y"]:{type:t.scale,beginAtZero:"linear"===t.scale,title:{display:!0,text:v}},[E?"y":"x"]:{type:"category",title:{display:!0,text:d},ticks:{autoSkip:!E,maxRotation:55}}}}),I="line"===t.chartType?O.N1:"pie"===t.chartType?O.Fq:O.yP;var k,j;return n.createElement("section",{className:"ai-chart-result".concat(o?" ai-chart-preview":""),"aria-label":o?"Proposed chart preview":"Applied chart"},n.createElement("div",{className:"ai-chart-result-heading"},n.createElement("div",null,n.createElement("div",{className:"ai-chart-eyebrow"},o?"Proposed chart · not yet applied":"Applied chart"),n.createElement("h2",null,t.title)),n.createElement(a.A,{size:"sm",variant:"outline-secondary",onClick:()=>m(!u)},u?n.createElement(y,null):n.createElement(g,null)," ",u?"Chart":"Data table")),n.createElement("div",{className:"ai-chart-totals"},r.series.map(e=>n.createElement("span",{key:e.label},n.createElement("strong",null,e.total.toLocaleString())," matching entries · ",e.label))),r.rows.length?u?n.createElement("div",{className:"ai-chart-table"},n.createElement("table",{className:"table table-striped table-sm"},n.createElement("caption",null,"Live PDB entry counts. ","percent"===t.measure?"Percentages use each series total as the denominator.":""),n.createElement("thead",null,n.createElement("tr",null,n.createElement("th",{scope:"col"},d),r.series.map(e=>n.createElement("th",{scope:"col",key:e.label},e.label)))),n.createElement("tbody",null,r.rows.map(e=>n.createElement("tr",{key:e.label},n.createElement("th",{scope:"row"},e.label),e.values.map((r,a)=>n.createElement("td",{key:a},r.toLocaleString(void 0,{maximumFractionDigits:2}),"percent"===t.measure?"% (".concat(e.counts[a].toLocaleString()," entries)"):""))))))):n.createElement("div",{style:{height:E?Math.min(900,Math.max(340,25*r.rows.length+100)):400}},n.createElement(I,{ref:s,data:w,options:N})):n.createElement("div",{className:"ai-chart-empty"},"No entries have chart values for these filters. Refine the request to broaden the population."),n.createElement("div",{className:"ai-chart-export-row"},n.createElement(a.A,{size:"sm",variant:"outline-secondary",onClick:()=>S(function(e,t){return[[e.categoryLabel||"Category",...t.series.flatMap(t=>["".concat(t.label,": entry count"),..."percent"===e.measure?["".concat(t.label,": percent of ").concat(t.total," matching entries")]:[]])],...t.rows.map(t=>[t.label,...t.counts.flatMap((r,n)=>[r,..."percent"===e.measure?[t.values[n]]:[]])])].map(e=>e.map(A).join(",")).join("\r\n")}(t,r),"pdb-chart-data.csv","text/csv;charset=utf-8")},n.createElement(h,null)," CSV"),n.createElement(a.A,{size:"sm",variant:"outline-secondary",onClick:()=>S(JSON.stringify({chart:t,data:r,searchRequests:(0,b.buildChartRequests)(t)},null,2),"pdb-chart.json","application/json")},n.createElement(h,null)," Chart + data JSON"),!u&&r.rows.length>0&&n.createElement(a.A,{size:"sm",variant:"outline-secondary",onClick:()=>{if(!s.current)return;const e=document.createElement("a");e.href=function(e,t,r){const n=document.createElement("canvas"),a=n.getContext("2d");if(!a)throw new Error("PNG export is not supported in this browser.");const i=e.width/(e.clientWidth||e.width),o=Math.round(20*i),l=Math.max(e.width,Math.round(400*i)),s=l-2*o;a.font="600 ".concat(18*i,"px sans-serif");const c=P(a,t.title,s);a.font="".concat(11*i,"px sans-serif");const u=P(a,"Source: RCSB PDB Search API · Retrieved ".concat(new Date(r.retrievedAt).toISOString().slice(0,10)," · Released PDB entries only."),s),m=25*c.length*i,p=16*u.length*i;n.width=l,n.height=Math.ceil(e.height+m+p+4*o),a.fillStyle="#ffffff",a.fillRect(0,0,n.width,n.height),a.fillStyle="#243746",a.font="600 ".concat(18*i,"px sans-serif"),a.textBaseline="top",c.forEach((e,t)=>a.fillText(e,o,o+25*t*i));const d=2*o+m;return a.drawImage(e,(l-e.width)/2,d),a.fillStyle="#526675",a.font="".concat(11*i,"px sans-serif"),u.forEach((t,r)=>a.fillText(t,o,d+e.height+o+16*r*i)),n.toDataURL("image/png",1)}(s.current.canvas,t,r),e.download="pdb-chart.png",e.click()}},n.createElement(h,null)," PNG"),n.createElement("span",null,"Retrieved ",new Date(r.retrievedAt).toLocaleString())),n.createElement("details",{className:"ai-chart-provenance"},n.createElement("summary",null,"Data source, filters, and counting rules"),n.createElement("p",null,"Live ",n.createElement("a",{href:"https://search.rcsb.org/#faceted-queries",target:"_blank",rel:"noopener noreferrer"},"RCSB PDB Search API"),". Released PDB entries only; computed models excluded. Missing attribute values are not a category."),n.createElement("p",null,t.filters.length?t.filters.map(b.describeFilter).join("; "):"No population filters."),t.series.map(e=>n.createElement("p",{key:e.label},n.createElement("strong",null,e.label,":")," ",e.filters.length?e.filters.map(b.describeFilter).join("; "):"No additional cohort filters.")),r.warnings.length>0&&n.createElement("ul",null,r.warnings.map(e=>n.createElement("li",{key:e},e))),n.createElement("details",null,n.createElement("summary",null,"Reproducible Search API requests"),n.createElement("pre",null,JSON.stringify((0,b.buildChartRequests)(t),null,2)))))}function k(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,o,l=[],s=!0,c=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(l.push(n.value),l.length!==t);s=!0);}catch(e){c=!0,a=e}finally{try{if(!s&&null!=r.return&&(o=r.return(),Object(o)!==o))return}finally{if(c)throw a}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return j(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?j(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function j(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}N.t1.register(N.PP,N.kc,N.OJ,N.E8,N.No,N.Bs,N.FN,N.m_,N.s$);const T=[{title:"Follow an archive trend",prompt:"Compare annual releases of X-ray and electron microscopy structures since 2015 as a line chart."},{title:"Investigate integrative structures",prompt:"Chart the input data types used in integrative PDB structures."}];function R(){const e=function(e){const t=e.aiCommands||("undefined"!=typeof window?window.__RCSB_AI_COMMANDS__:void 0);return t&&"function"==typeof t.execute&&"function"==typeof t.getStatus?t:void 0}((0,f.t)().settings.config),t=k((0,n.useState)(null),2),r=t[0],s=t[1],h=k((0,n.useState)([]),2),g=h[0],y=h[1],v=k((0,n.useState)(""),2),w=v[0],A=v[1],S=k((0,n.useState)(null),2),O=S[0],N=S[1],P=k((0,n.useState)(null),2),x=P[0],C=P[1],_=k((0,n.useState)([]),2),j=_[0],R=_[1],D=k((0,n.useState)(!1),2),q=D[0],L=D[1],F=k((0,n.useState)("Interpreting your chart request…"),2),B=F[0],M=F[1],Y=k((0,n.useState)(""),2),U=Y[0],z=Y[1],$=(0,n.useRef)(null),J=(0,n.useRef)(0),G=(0,n.useRef)(null),V=(0,n.useRef)(null),W=(0,n.useRef)(null);(0,n.useEffect)(()=>{var t;let r=!0;const n=e=>{if(!r)return;const t=JSON.stringify([e.connected,e.provider,e.model,e.connectionId]);var n;null!==W.current&&t!==W.current&&(J.current+=1,null===(n=$.current)||void 0===n||n.abort(),$.current=null,L(!1),N(null),R([]),z(e.connected?"Your AI connection or model changed. Prepare a new preview before applying it.":"Reconnect your AI provider in AI Settings. Your applied chart has not changed.")),W.current=t,s(e)},a=()=>null==e?void 0:e.getStatus().then(n).catch(()=>n({connected:!1})),i=null==e||null===(t=e.subscribe)||void 0===t?void 0:t.call(e,n);return a(),window.addEventListener("focus",a),()=>{var e;r=!1,null==i||i(),window.removeEventListener("focus",a),J.current+=1,null===(e=$.current)||void 0===e||e.abort()}},[e]),(0,n.useEffect)(()=>{var e,t;null===(e=G.current)||void 0===e||null===(t=e.scrollTo)||void 0===t||t.call(e,{top:g.length?G.current.scrollHeight:0,behavior:g.length?"smooth":"auto"})},[g,q,j]);const Q=async function(){const t=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:w).trim();if(!t||t.length>4e3||q||$.current||!e||null==r||!r.connected)return;const n=++J.current,a=new AbortController;$.current=a;const i=[...g,{role:"user",content:t}].slice(-15);y(i),A(""),R([]),z(""),L(!0),M("Interpreting your chart request…");try{const t=function(e){var t,r;if(!e||!e.ok||!["ready","clarification"].includes(e.status)||"string"!=typeof e.message)throw new Error("The AI service returned an incomplete chart response. Your current chart has not changed.");if("clarification"===e.status){if(!Array.isArray(e.questions)||e.questions.length>4||e.questions.some(e=>"string"!=typeof e.question||e.options&&(!Array.isArray(e.options)||e.options.length>8||e.options.some(e=>"string"!=typeof e))))throw new Error("The AI service returned an invalid clarification. Please rephrase your request.");return e}if("configureChart"!==(null===(t=e.command)||void 0===t?void 0:t.action))throw new Error("The AI service returned an unsupported command.");const n=(0,b.validateChartSpec)(e.command.spec),a=null===(r=e.preview)||void 0===r?void 0:r.chartData;if(!a||!Array.isArray(a.rows)||a.rows.length>1e3||!Array.isArray(a.series)||a.series.length!==n.series.length||!Array.isArray(a.warnings)||a.warnings.length>20||a.warnings.some(e=>"string"!=typeof e||e.length>1e3)||!Number.isInteger(a.categoryCount)||a.categoryCount<a.rows.length||!Number.isFinite(Date.parse(a.retrievedAt)))throw new Error("Live chart data was not returned. Your current chart has not changed.");if(a.series.some((e,t)=>e.label!==n.series[t].label||!Number.isInteger(e.total)||e.total<0)||a.rows.some(e=>"string"!=typeof e.label||!Array.isArray(e.counts)||e.counts.length!==a.series.length||!Array.isArray(e.values)||e.values.length!==a.series.length||e.counts.some(e=>!Number.isInteger(e)||e<0)||e.values.some(e=>!Number.isFinite(e)||e<0)))throw new Error("Live chart data did not pass validation. Your current chart has not changed.");if(new Set(a.rows.map(e=>e.label)).size!==a.rows.length||a.rows.some(e=>e.counts.some((t,r)=>t>a.series[r].total||Math.abs(e.values[r]-("percent"===n.measure?a.series[r].total?100*t/a.series[r].total:0:t))>1e-6)))throw new Error("Chart values do not match the validated entry counts.");return E(E({},e),{},{command:{action:"configureChart",spec:n}})}(await e.execute({action:"configureChart",messages:i,context:{currentChart:(null==x?void 0:x.command.spec)||null,pendingChart:(null==O?void 0:O.command.spec)||null},previousCommand:(null==O?void 0:O.command)||(null==x?void 0:x.command)||null},{signal:a.signal,onProgress:e=>{if(n!==J.current||a.signal.aborted)return;const t={planning:"Interpreting your chart request…",lookup:"Looking up PDB metadata…",building:"Preparing the chart specification…",validating:"Validating the chart and loading live PDB counts…"};t[e]&&M(t[e])}}));if(n!==J.current||a.signal.aborted)return;y([...i,{role:"assistant",content:t.message}]),R(t.questions||[]),"ready"===t.status&&N({command:t.command,data:t.preview.chartData,preview:t.preview})}catch(e){if(n!==J.current||a.signal.aborted)return;z(e instanceof Error?e.message:"The chart could not be prepared. Your current chart has not changed.")}finally{n===J.current&&(L(!1),$.current=null)}},X=()=>{var e;J.current+=1,null===(e=$.current)||void 0===e||e.abort(),$.current=null,L(!1),z("Request cancelled. Your current chart and previous proposal have not changed.")},Z=(null==e?void 0:e.settingsUrl)||"/search/ai-settings",H=Boolean(e&&(null==r?void 0:r.connected)),K=O||x,ee=O?(0,b.chartChanges)((null==x?void 0:x.command.spec)||null,O.command.spec):[];return n.createElement("article",{className:"ai-chart-workspace"},n.createElement("header",{className:"ai-chart-page-heading"},n.createElement("div",null,n.createElement("h1",null,"AI Powered Chart Builder"),n.createElement("p",null,"Describe a question. Review a chart grounded in live PDB data.")),n.createElement(a.A,{variant:"outline-secondary",href:Z},n.createElement(p,null)," AI Settings")),!H&&n.createElement(i.A,{variant:"info",className:"ai-chart-connect"},e&&null===r?"Checking your AI connection…":n.createElement(n.Fragment,null,"Connect a provider in ",n.createElement("a",{href:Z},"AI Settings")," to create and refine charts. The chart builder uses the same connection as the AI Query Builder."),!e&&n.createElement("div",{className:"small mt-1"},"AI commands are available when this app is hosted in a configured Sierra environment.")),n.createElement("div",{className:"ai-chart-layout"},n.createElement("section",{className:"ai-chart-chat","aria-label":"Chart conversation"},n.createElement("div",{className:"ai-chart-panel-heading"},n.createElement("strong",null,"Build a chart"),n.createElement(a.A,{variant:"link",size:"sm",onClick:()=>{var e;X(),y([]),N(null),C(null),R([]),A(""),z(""),null===(e=V.current)||void 0===e||e.focus()},disabled:!g.length&&!x},n.createElement(u,null)," Start over")),n.createElement("div",{ref:G,className:"ai-chart-conversation","aria-live":"polite"},!g.length&&n.createElement(n.Fragment,null,n.createElement("p",{className:"ai-chart-welcome"},"What would you like to learn about the PDB archive?"),n.createElement("p",{className:"ai-chart-muted"},"Compare methods, organisms, ligands, release-year trends, resolution distributions, or integrative input data. Start with an example or ask your own question."),n.createElement("div",{className:"ai-chart-examples"},T.map(e=>n.createElement("button",{key:e.title,onClick:()=>{var t;A(e.prompt),null===(t=V.current)||void 0===t||t.focus()}},n.createElement("strong",null,e.title),n.createElement("span",null,e.prompt))))),g.map((e,t)=>n.createElement("div",{key:t,className:"ai-chart-message ai-chart-message-".concat(e.role)},n.createElement("span",{className:"visually-hidden"},"user"===e.role?"You":"AI",": "),e.content)),j.map((e,t)=>{var r;return n.createElement("div",{key:t,className:"ai-chart-question"},n.createElement("strong",null,e.question),n.createElement("div",null,null===(r=e.options)||void 0===r?void 0:r.map(t=>n.createElement(a.A,{key:t,size:"sm",variant:"outline-primary",disabled:q||!H,onClick:()=>Q("".concat(e.question,"\n").concat(t))},t))))}),q&&n.createElement("div",{role:"status",className:"ai-chart-wait"},n.createElement(o.A,{animation:"border",size:"sm"}),n.createElement("span",null,B))),U&&n.createElement(i.A,{variant:"danger",className:"m-3 mb-0",dismissible:!0,onClose:()=>z("")},U),n.createElement(l.A,{className:"ai-chart-composer",onSubmit:e=>{e.preventDefault(),Q()}},n.createElement(l.A.Label,{htmlFor:"ai-chart-prompt"},K?"Refine this chart":"Describe your chart"),n.createElement(l.A.Control,{as:"textarea",id:"ai-chart-prompt",ref:V,rows:3,maxLength:4e3,value:w,onChange:e=>A(e.target.value),placeholder:K?"Try “make it a line chart” or “only show structures released since 2020”…":"For example, compare X-ray and cryo-EM structure releases over time…",disabled:q}),n.createElement("div",{className:"ai-chart-composer-actions"},n.createElement("span",null,(null==r?void 0:r.model)||"Your connected AI model"),q?n.createElement(a.A,{variant:"outline-secondary",onClick:X},n.createElement(d,null)," Cancel"):n.createElement(a.A,{type:"submit",disabled:!H||!w.trim()},n.createElement(m,null)," Build Chart")))),n.createElement("div",{className:"ai-chart-canvas"},O&&n.createElement("div",{className:"ai-chart-review"},n.createElement("div",null,n.createElement("strong",null,"Review before applying"),n.createElement("p",null,(0,b.describeChart)(O.command.spec))),ee.length?n.createElement("ul",null,ee.map(e=>n.createElement("li",{key:e},e))):n.createElement("p",null,"No chart settings changed."),O.data.warnings.length>0&&n.createElement("details",null,n.createElement("summary",null,O.data.warnings.length," counting ",1===O.data.warnings.length?"note":"notes"),n.createElement("ul",null,O.data.warnings.map(e=>n.createElement("li",{key:e},e)))),n.createElement("div",{className:"ai-chart-review-actions"},n.createElement(a.A,{disabled:q,onClick:()=>{C(O),N(null)}},n.createElement(c,null)," Apply chart"),n.createElement(a.A,{variant:"outline-secondary",disabled:q,onClick:()=>N(null)},"Discard proposal"))),K?n.createElement(I,{key:"".concat(K.data.retrievedAt,"-").concat(Boolean(O)),spec:K.command.spec,data:K.data,preview:Boolean(O)}):n.createElement("div",{className:"ai-chart-placeholder"},n.createElement("p",null,"A validated preview will appear here. Nothing is applied until you choose Apply chart.")),x&&O&&n.createElement("details",{className:"ai-chart-previous"},n.createElement("summary",null,"View currently applied chart"),n.createElement(I,{spec:x.command.spec,data:x.data})))))}},3482(e){"use strict";e.exports=JSON.parse('{"version":1,"action":"configureChart","name":"AI Powered Chart Builder","checkedAt":"2026-09-13","sources":["https://search.rcsb.org/#faceted-queries","https://search.rcsb.org/rcsbsearch/v2/metadata/schema"],"countingRules":["Every value is a live count of released PDB entries, not polymer entities, atoms, chains, downloads, citations, or unique sequences. Computed models are excluded.","Categories may overlap when an entry has multiple methods, organisms, polymer types, input datasets, or resolution values. Do not sum overlapping buckets to claim a unique total.","Percentages use all matching entries in each cohort as the denominator, including entries missing the chart attribute. They are not normalized to the displayed top categories.","All filters are entry-level requirements. An organism and ligand filter may match different entities in the same entry. Do not promise same-chain, binding-site, or same-entity relationships.","Lower and upper bounds on one numeric or date attribute are combined into one inclusive interval. At least one value must satisfy both bounds; different reported resolutions cannot satisfy opposite ends of the interval.","Cumulative release-year counts start at the selected lower release-year bound, not necessarily the beginning of the archive. Current-year counts are incomplete.","Comparisons use up to four explicit named cohorts with independent additional filters; cohorts may overlap. Never fabricate counts or arbitrary Search API attributes.","Ask a clarification when a request needs unsupported statistics, ambiguous units or entity relationships, or an unknown organism taxon. Preserve the existing chart and filters during refinement unless the user requests a change."],"dimensions":{"releaseYear":{"label":"Release year","attribute":"rcsb_accession_info.initial_release_date","aggregation":"date_histogram","interval":"year","ordered":true,"overlapping":false},"method":{"label":"Experimental method","attribute":"exptl.method","aggregation":"terms","ordered":false,"overlapping":true},"sourceOrganism":{"label":"Source organism","attribute":"rcsb_entity_source_organism.ncbi_scientific_name","aggregation":"terms","ordered":false,"overlapping":true},"resolution":{"label":"Resolution (Å)","attribute":"rcsb_entry_info.resolution_combined","aggregation":"histogram","ordered":true,"overlapping":true},"polymerType":{"label":"Polymer type","attribute":"entity_poly.rcsb_entity_polymer_type","aggregation":"terms","ordered":false,"overlapping":true},"integrativeInput":{"label":"Integrative input data type","attribute":"rcsb_ihm_dataset_list.name","aggregation":"terms","ordered":false,"overlapping":true,"requiredFilter":{"field":"methodology","operator":"in","value":["integrative"]}},"methodology":{"label":"Structure determination methodology","attribute":"rcsb_entry_info.structure_determination_methodology","aggregation":"terms","ordered":false,"overlapping":false}},"filters":{"releaseYear":{"label":"Release year","attribute":"rcsb_accession_info.initial_release_date","kind":"year","operators":["gte","lte"],"minimum":1971,"maximum":2100},"method":{"label":"Experimental method","attribute":"exptl.method","kind":"enum","operators":["in"],"values":["X-RAY DIFFRACTION","ELECTRON MICROSCOPY","SOLUTION NMR","SOLID-STATE NMR","NEUTRON DIFFRACTION","ELECTRON CRYSTALLOGRAPHY","FIBER DIFFRACTION","POWDER DIFFRACTION","SOLUTION SCATTERING","INFRARED SPECTROSCOPY","EPR","FLUORESCENCE TRANSFER"]},"resolution":{"label":"Resolution (Å)","attribute":"rcsb_entry_info.resolution_combined","kind":"number","operators":["gte","lte"],"minimum":0.01,"maximum":1000},"sourceTaxonomy":{"label":"Source organism NCBI taxonomy ID (including descendants)","attribute":"rcsb_entity_source_organism.taxonomy_lineage.id","kind":"taxonomy","operators":["in"]},"sourceOrganism":{"label":"Exact source organism scientific name","attribute":"rcsb_entity_source_organism.ncbi_scientific_name","kind":"text","operators":["in"]},"ligand":{"label":"Non-polymer chemical component ID present in entry","attribute":"rcsb_nonpolymer_entity.rcsb_nonpolymer_comp_id","kind":"identifier","operators":["in"]},"polymerType":{"label":"Polymer type present in entry","attribute":"entity_poly.rcsb_entity_polymer_type","kind":"enum","operators":["in"],"values":["Protein","DNA","RNA","NA-hybrid","Other"]},"methodology":{"label":"Structure determination methodology","attribute":"rcsb_entry_info.structure_determination_methodology","kind":"enum","operators":["in"],"values":["experimental","integrative"]}},"knownTaxa":{"human":9606,"mouse":10090,"Escherichia coli":562,"Saccharomyces cerevisiae":4932},"specSchema":{"type":"object","additionalProperties":false,"required":["version","title","categoryLabel","valueLabel","dimension","chartType","measure","scale","orientation","sort","topN","interval","cumulative","filters","series"],"properties":{"version":{"type":"integer","enum":[1]},"title":{"type":"string","minLength":1,"maxLength":140},"categoryLabel":{"type":"string","minLength":1,"maxLength":100},"valueLabel":{"type":"string","minLength":1,"maxLength":100},"dimension":{"type":"string","enum":["releaseYear","method","sourceOrganism","resolution","polymerType","integrativeInput","methodology"]},"chartType":{"type":"string","enum":["bar","line","pie"]},"measure":{"type":"string","enum":["count","percent"]},"scale":{"type":"string","enum":["linear","logarithmic"]},"orientation":{"type":"string","enum":["vertical","horizontal"]},"sort":{"type":"string","enum":["labelAsc","countDesc"]},"topN":{"type":"integer","minimum":1,"maximum":60},"interval":{"type":"number","minimum":0.1,"maximum":100},"cumulative":{"type":"boolean"},"filters":{"type":"array","maxItems":12,"items":{"$ref":"#/$defs/filter"}},"series":{"type":"array","minItems":1,"maxItems":4,"items":{"type":"object","additionalProperties":false,"required":["label","filters"],"properties":{"label":{"type":"string","minLength":1,"maxLength":80},"filters":{"type":"array","maxItems":8,"items":{"$ref":"#/$defs/filter"}}}}}},"$defs":{"filter":{"type":"object","additionalProperties":false,"required":["field","operator","value"],"properties":{"field":{"type":"string","enum":["releaseYear","method","resolution","sourceTaxonomy","sourceOrganism","ligand","polymerType","methodology"]},"operator":{"type":"string","enum":["in","gte","lte"]},"value":{"anyOf":[{"type":"number"},{"type":"array","minItems":1,"maxItems":10,"uniqueItems":true,"items":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"integer","minimum":1,"maximum":999999999}]}}]}}}}}}')}}]);