Fossil SCM
Use the longer hash prefix for the click-to-copy.
Commit
2196555351f62337c65108206408c9590064b63544e3813f440bc2f038324ae0
Parent
46f91da1a8d867c…
3 files changed
+4
-4
+3
-3
+1
-7
+4
-4
| --- src/graph.js | ||
| +++ src/graph.js | ||
| @@ -19,11 +19,11 @@ | ||
| 19 | 19 | ** "scrollToSelect": BOOLEAN, // Scroll to selection on first render |
| 20 | 20 | ** "nrail": INTEGER, // Number of vertical "rails" |
| 21 | 21 | ** "baseUrl": TEXT, // Top-level URL |
| 22 | 22 | ** "dwellTimeout": INTEGER, // Tooltip show delay in milliseconds |
| 23 | 23 | ** "closeTimeout": INTEGER, // Tooltip close delay in milliseconds |
| 24 | -** "digitHuman": INTEGER, // Limit of tooltip hashes ("hash-digits") | |
| 24 | +** "hashDigits": INTEGER, // Limit of tooltip hashes ("hash-digits") | |
| 25 | 25 | ** "rowinfo": ROWINFO-ARRAY } |
| 26 | 26 | ** |
| 27 | 27 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 28 | 28 | ** where each structure has the following fields: |
| 29 | 29 | ** |
| @@ -98,11 +98,11 @@ | ||
| 98 | 98 | |
| 99 | 99 | /* State information for the tooltip popup and its timers */ |
| 100 | 100 | window.tooltipInfo = { |
| 101 | 101 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 102 | 102 | closeTimeout: 3000, /* The tooltip close timeout. */ |
| 103 | - digitHuman: 10, /* Limit of tooltip hashes ("hash-digits"). */ | |
| 103 | + hashDigits: 16, /* Limit of tooltip hashes ("hash-digits"). */ | |
| 104 | 104 | idTimer: 0, /* The tooltip dwell timer id. */ |
| 105 | 105 | idTimerClose: 0, /* The tooltip close timer id. */ |
| 106 | 106 | ixHover: -1, /* The id of the element with the mouse. */ |
| 107 | 107 | ixActive: -1, /* The id of the element with the tooltip. */ |
| 108 | 108 | nodeHover: null, /* Graph node under mouse when ixHover==-2 */ |
| @@ -143,11 +143,11 @@ | ||
| 143 | 143 | function TimelineGraph(tx){ |
| 144 | 144 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 145 | 145 | amendCss(tx.circleNodes, tx.showArrowheads); |
| 146 | 146 | tooltipInfo.dwellTimeout = tx.dwellTimeout |
| 147 | 147 | tooltipInfo.closeTimeout = tx.closeTimeout |
| 148 | - tooltipInfo.digitHuman = tx.digitHuman | |
| 148 | + tooltipInfo.hashDigits = tx.hashDigits | |
| 149 | 149 | topObj.onclick = clickOnGraph |
| 150 | 150 | topObj.ondblclick = dblclickOnGraph |
| 151 | 151 | topObj.onmousemove = function(e) { |
| 152 | 152 | var ix = findTxIndex(e); |
| 153 | 153 | topObj.style.cursor = (ix<0) ? "" : "pointer" |
| @@ -597,11 +597,11 @@ | ||
| 597 | 597 | var ix = -1 |
| 598 | 598 | if( tooltipInfo.ixHover==-2 ){ |
| 599 | 599 | ix = parseInt(tooltipInfo.nodeHover.id.match(/\d+$/)[0],10)-tx.iTopRow |
| 600 | 600 | var h = tx.rowinfo[ix].h |
| 601 | 601 | var dest = tx.baseUrl + "/info/" + h |
| 602 | - h = h.slice(0,tooltipInfo.digitHuman); // Assume single-byte characters. | |
| 602 | + h = h.slice(0,tooltipInfo.hashDigits); // Assume single-byte characters. | |
| 603 | 603 | if( tx.fileDiff ){ |
| 604 | 604 | html = "artifact <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 605 | 605 | }else{ |
| 606 | 606 | html = "check-in <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 607 | 607 | } |
| 608 | 608 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -19,11 +19,11 @@ | |
| 19 | ** "scrollToSelect": BOOLEAN, // Scroll to selection on first render |
| 20 | ** "nrail": INTEGER, // Number of vertical "rails" |
| 21 | ** "baseUrl": TEXT, // Top-level URL |
| 22 | ** "dwellTimeout": INTEGER, // Tooltip show delay in milliseconds |
| 23 | ** "closeTimeout": INTEGER, // Tooltip close delay in milliseconds |
| 24 | ** "digitHuman": INTEGER, // Limit of tooltip hashes ("hash-digits") |
| 25 | ** "rowinfo": ROWINFO-ARRAY } |
| 26 | ** |
| 27 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 28 | ** where each structure has the following fields: |
| 29 | ** |
| @@ -98,11 +98,11 @@ | |
| 98 | |
| 99 | /* State information for the tooltip popup and its timers */ |
| 100 | window.tooltipInfo = { |
| 101 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 102 | closeTimeout: 3000, /* The tooltip close timeout. */ |
| 103 | digitHuman: 10, /* Limit of tooltip hashes ("hash-digits"). */ |
| 104 | idTimer: 0, /* The tooltip dwell timer id. */ |
| 105 | idTimerClose: 0, /* The tooltip close timer id. */ |
| 106 | ixHover: -1, /* The id of the element with the mouse. */ |
| 107 | ixActive: -1, /* The id of the element with the tooltip. */ |
| 108 | nodeHover: null, /* Graph node under mouse when ixHover==-2 */ |
| @@ -143,11 +143,11 @@ | |
| 143 | function TimelineGraph(tx){ |
| 144 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 145 | amendCss(tx.circleNodes, tx.showArrowheads); |
| 146 | tooltipInfo.dwellTimeout = tx.dwellTimeout |
| 147 | tooltipInfo.closeTimeout = tx.closeTimeout |
| 148 | tooltipInfo.digitHuman = tx.digitHuman |
| 149 | topObj.onclick = clickOnGraph |
| 150 | topObj.ondblclick = dblclickOnGraph |
| 151 | topObj.onmousemove = function(e) { |
| 152 | var ix = findTxIndex(e); |
| 153 | topObj.style.cursor = (ix<0) ? "" : "pointer" |
| @@ -597,11 +597,11 @@ | |
| 597 | var ix = -1 |
| 598 | if( tooltipInfo.ixHover==-2 ){ |
| 599 | ix = parseInt(tooltipInfo.nodeHover.id.match(/\d+$/)[0],10)-tx.iTopRow |
| 600 | var h = tx.rowinfo[ix].h |
| 601 | var dest = tx.baseUrl + "/info/" + h |
| 602 | h = h.slice(0,tooltipInfo.digitHuman); // Assume single-byte characters. |
| 603 | if( tx.fileDiff ){ |
| 604 | html = "artifact <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 605 | }else{ |
| 606 | html = "check-in <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 607 | } |
| 608 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -19,11 +19,11 @@ | |
| 19 | ** "scrollToSelect": BOOLEAN, // Scroll to selection on first render |
| 20 | ** "nrail": INTEGER, // Number of vertical "rails" |
| 21 | ** "baseUrl": TEXT, // Top-level URL |
| 22 | ** "dwellTimeout": INTEGER, // Tooltip show delay in milliseconds |
| 23 | ** "closeTimeout": INTEGER, // Tooltip close delay in milliseconds |
| 24 | ** "hashDigits": INTEGER, // Limit of tooltip hashes ("hash-digits") |
| 25 | ** "rowinfo": ROWINFO-ARRAY } |
| 26 | ** |
| 27 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 28 | ** where each structure has the following fields: |
| 29 | ** |
| @@ -98,11 +98,11 @@ | |
| 98 | |
| 99 | /* State information for the tooltip popup and its timers */ |
| 100 | window.tooltipInfo = { |
| 101 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 102 | closeTimeout: 3000, /* The tooltip close timeout. */ |
| 103 | hashDigits: 16, /* Limit of tooltip hashes ("hash-digits"). */ |
| 104 | idTimer: 0, /* The tooltip dwell timer id. */ |
| 105 | idTimerClose: 0, /* The tooltip close timer id. */ |
| 106 | ixHover: -1, /* The id of the element with the mouse. */ |
| 107 | ixActive: -1, /* The id of the element with the tooltip. */ |
| 108 | nodeHover: null, /* Graph node under mouse when ixHover==-2 */ |
| @@ -143,11 +143,11 @@ | |
| 143 | function TimelineGraph(tx){ |
| 144 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 145 | amendCss(tx.circleNodes, tx.showArrowheads); |
| 146 | tooltipInfo.dwellTimeout = tx.dwellTimeout |
| 147 | tooltipInfo.closeTimeout = tx.closeTimeout |
| 148 | tooltipInfo.hashDigits = tx.hashDigits |
| 149 | topObj.onclick = clickOnGraph |
| 150 | topObj.ondblclick = dblclickOnGraph |
| 151 | topObj.onmousemove = function(e) { |
| 152 | var ix = findTxIndex(e); |
| 153 | topObj.style.cursor = (ix<0) ? "" : "pointer" |
| @@ -597,11 +597,11 @@ | |
| 597 | var ix = -1 |
| 598 | if( tooltipInfo.ixHover==-2 ){ |
| 599 | ix = parseInt(tooltipInfo.nodeHover.id.match(/\d+$/)[0],10)-tx.iTopRow |
| 600 | var h = tx.rowinfo[ix].h |
| 601 | var dest = tx.baseUrl + "/info/" + h |
| 602 | h = h.slice(0,tooltipInfo.hashDigits); // Assume single-byte characters. |
| 603 | if( tx.fileDiff ){ |
| 604 | html = "artifact <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 605 | }else{ |
| 606 | html = "check-in <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" |
| 607 | } |
| 608 |
+3
-3
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -48,11 +48,11 @@ | ||
| 48 | 48 | /* |
| 49 | 49 | ** Return the number of artifact hash digits to display. The number is for |
| 50 | 50 | ** human output if the bForUrl is false and is destined for a URL if |
| 51 | 51 | ** bForUrl is false. |
| 52 | 52 | */ |
| 53 | -static int hashDigits(int bForUrl){ | |
| 53 | +int hash_digits(int bForUrl){ | |
| 54 | 54 | static int nDigitHuman = 0; |
| 55 | 55 | static int nDigitUrl = 0; |
| 56 | 56 | if( nDigitHuman==0 ){ |
| 57 | 57 | nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); |
| 58 | 58 | if( nDigitHuman < 6 ) nDigitHuman = 6; |
| @@ -66,11 +66,11 @@ | ||
| 66 | 66 | |
| 67 | 67 | /* |
| 68 | 68 | ** Return the number of characters in a %S output. |
| 69 | 69 | */ |
| 70 | 70 | int length_of_S_display(void){ |
| 71 | - return hashDigits(0); | |
| 71 | + return hash_digits(0); | |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | /* |
| 75 | 75 | ** Conversion types fall into various categories as defined by the |
| 76 | 76 | ** following enumeration. |
| @@ -679,11 +679,11 @@ | ||
| 679 | 679 | if( bufpt==0 ){ |
| 680 | 680 | bufpt = ""; |
| 681 | 681 | }else if( xtype==etDYNSTRING ){ |
| 682 | 682 | zExtra = bufpt; |
| 683 | 683 | }else if( xtype==etSTRINGID ){ |
| 684 | - precision = hashDigits(flag_altform2); | |
| 684 | + precision = hash_digits(flag_altform2); | |
| 685 | 685 | } |
| 686 | 686 | length = StrNLen32(bufpt, limit); |
| 687 | 687 | if( precision>=0 && precision<length ) length = precision; |
| 688 | 688 | break; |
| 689 | 689 | } |
| 690 | 690 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -48,11 +48,11 @@ | |
| 48 | /* |
| 49 | ** Return the number of artifact hash digits to display. The number is for |
| 50 | ** human output if the bForUrl is false and is destined for a URL if |
| 51 | ** bForUrl is false. |
| 52 | */ |
| 53 | static int hashDigits(int bForUrl){ |
| 54 | static int nDigitHuman = 0; |
| 55 | static int nDigitUrl = 0; |
| 56 | if( nDigitHuman==0 ){ |
| 57 | nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); |
| 58 | if( nDigitHuman < 6 ) nDigitHuman = 6; |
| @@ -66,11 +66,11 @@ | |
| 66 | |
| 67 | /* |
| 68 | ** Return the number of characters in a %S output. |
| 69 | */ |
| 70 | int length_of_S_display(void){ |
| 71 | return hashDigits(0); |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | ** Conversion types fall into various categories as defined by the |
| 76 | ** following enumeration. |
| @@ -679,11 +679,11 @@ | |
| 679 | if( bufpt==0 ){ |
| 680 | bufpt = ""; |
| 681 | }else if( xtype==etDYNSTRING ){ |
| 682 | zExtra = bufpt; |
| 683 | }else if( xtype==etSTRINGID ){ |
| 684 | precision = hashDigits(flag_altform2); |
| 685 | } |
| 686 | length = StrNLen32(bufpt, limit); |
| 687 | if( precision>=0 && precision<length ) length = precision; |
| 688 | break; |
| 689 | } |
| 690 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -48,11 +48,11 @@ | |
| 48 | /* |
| 49 | ** Return the number of artifact hash digits to display. The number is for |
| 50 | ** human output if the bForUrl is false and is destined for a URL if |
| 51 | ** bForUrl is false. |
| 52 | */ |
| 53 | int hash_digits(int bForUrl){ |
| 54 | static int nDigitHuman = 0; |
| 55 | static int nDigitUrl = 0; |
| 56 | if( nDigitHuman==0 ){ |
| 57 | nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); |
| 58 | if( nDigitHuman < 6 ) nDigitHuman = 6; |
| @@ -66,11 +66,11 @@ | |
| 66 | |
| 67 | /* |
| 68 | ** Return the number of characters in a %S output. |
| 69 | */ |
| 70 | int length_of_S_display(void){ |
| 71 | return hash_digits(0); |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | ** Conversion types fall into various categories as defined by the |
| 76 | ** following enumeration. |
| @@ -679,11 +679,11 @@ | |
| 679 | if( bufpt==0 ){ |
| 680 | bufpt = ""; |
| 681 | }else if( xtype==etDYNSTRING ){ |
| 682 | zExtra = bufpt; |
| 683 | }else if( xtype==etSTRINGID ){ |
| 684 | precision = hash_digits(flag_altform2); |
| 685 | } |
| 686 | length = StrNLen32(bufpt, limit); |
| 687 | if( precision>=0 && precision<length ) length = precision; |
| 688 | break; |
| 689 | } |
| 690 |
+1
-7
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -832,11 +832,10 @@ | ||
| 832 | 832 | int fileDiff; /* True for file diff. False for check-in diff */ |
| 833 | 833 | int omitDescenders; /* True to omit descenders */ |
| 834 | 834 | int scrollToSelect; /* True to scroll to the selection */ |
| 835 | 835 | int dwellTimeout; /* Milliseconds to wait for tooltips to show */ |
| 836 | 836 | int closeTimeout; /* Milliseconds to wait for tooltips to close */ |
| 837 | - int nDigitHuman; /* The "hash-digits" limit for tooltip hash prefixes */ | |
| 838 | 837 | u8 *aiMap; /* The rail map */ |
| 839 | 838 | |
| 840 | 839 | iRailPitch = atoi(PD("railpitch","0")); |
| 841 | 840 | showArrowheads = skin_detail_boolean("timeline-arrowheads"); |
| 842 | 841 | circleNodes = skin_detail_boolean("timeline-circle-nodes"); |
| @@ -845,15 +844,10 @@ | ||
| 845 | 844 | omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 846 | 845 | fileDiff = (tmFlags & TIMELINE_FILEDIFF)!=0; |
| 847 | 846 | scrollToSelect = (tmFlags & TIMELINE_NOSCROLL)==0; |
| 848 | 847 | dwellTimeout = atoi(db_get("timeline-dwelltime","100")); |
| 849 | 848 | closeTimeout = atoi(db_get("timeline-closetime","250")); |
| 850 | -/* Preprocessor definitions copied from src\printf.c. */ | |
| 851 | -#ifndef FOSSIL_HASH_DIGITS | |
| 852 | -# define FOSSIL_HASH_DIGITS 10 | |
| 853 | -#endif | |
| 854 | - nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); | |
| 855 | 849 | @ <script id='timeline-data-%d(iTableId)' type='application/json'>{ |
| 856 | 850 | @ "iTableId": %d(iTableId), |
| 857 | 851 | @ "circleNodes": %d(circleNodes), |
| 858 | 852 | @ "showArrowheads": %d(showArrowheads), |
| 859 | 853 | @ "iRailPitch": %d(iRailPitch), |
| @@ -865,11 +859,11 @@ | ||
| 865 | 859 | @ "scrollToSelect": %d(scrollToSelect), |
| 866 | 860 | @ "nrail": %d(pGraph->mxRail+1), |
| 867 | 861 | @ "baseUrl": "%R", |
| 868 | 862 | @ "dwellTimeout": %d(dwellTimeout), |
| 869 | 863 | @ "closeTimeout": %d(closeTimeout), |
| 870 | - @ "digitHuman": %d(nDigitHuman), | |
| 864 | + @ "hashDigit": %d(hash_digits(1)), | |
| 871 | 865 | @ "bottomRowId": "btm-%d(iTableId)", |
| 872 | 866 | if( pGraph->nRow==0 ){ |
| 873 | 867 | @ "rowinfo": null |
| 874 | 868 | }else{ |
| 875 | 869 | @ "rowinfo": [ |
| 876 | 870 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -832,11 +832,10 @@ | |
| 832 | int fileDiff; /* True for file diff. False for check-in diff */ |
| 833 | int omitDescenders; /* True to omit descenders */ |
| 834 | int scrollToSelect; /* True to scroll to the selection */ |
| 835 | int dwellTimeout; /* Milliseconds to wait for tooltips to show */ |
| 836 | int closeTimeout; /* Milliseconds to wait for tooltips to close */ |
| 837 | int nDigitHuman; /* The "hash-digits" limit for tooltip hash prefixes */ |
| 838 | u8 *aiMap; /* The rail map */ |
| 839 | |
| 840 | iRailPitch = atoi(PD("railpitch","0")); |
| 841 | showArrowheads = skin_detail_boolean("timeline-arrowheads"); |
| 842 | circleNodes = skin_detail_boolean("timeline-circle-nodes"); |
| @@ -845,15 +844,10 @@ | |
| 845 | omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 846 | fileDiff = (tmFlags & TIMELINE_FILEDIFF)!=0; |
| 847 | scrollToSelect = (tmFlags & TIMELINE_NOSCROLL)==0; |
| 848 | dwellTimeout = atoi(db_get("timeline-dwelltime","100")); |
| 849 | closeTimeout = atoi(db_get("timeline-closetime","250")); |
| 850 | /* Preprocessor definitions copied from src\printf.c. */ |
| 851 | #ifndef FOSSIL_HASH_DIGITS |
| 852 | # define FOSSIL_HASH_DIGITS 10 |
| 853 | #endif |
| 854 | nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); |
| 855 | @ <script id='timeline-data-%d(iTableId)' type='application/json'>{ |
| 856 | @ "iTableId": %d(iTableId), |
| 857 | @ "circleNodes": %d(circleNodes), |
| 858 | @ "showArrowheads": %d(showArrowheads), |
| 859 | @ "iRailPitch": %d(iRailPitch), |
| @@ -865,11 +859,11 @@ | |
| 865 | @ "scrollToSelect": %d(scrollToSelect), |
| 866 | @ "nrail": %d(pGraph->mxRail+1), |
| 867 | @ "baseUrl": "%R", |
| 868 | @ "dwellTimeout": %d(dwellTimeout), |
| 869 | @ "closeTimeout": %d(closeTimeout), |
| 870 | @ "digitHuman": %d(nDigitHuman), |
| 871 | @ "bottomRowId": "btm-%d(iTableId)", |
| 872 | if( pGraph->nRow==0 ){ |
| 873 | @ "rowinfo": null |
| 874 | }else{ |
| 875 | @ "rowinfo": [ |
| 876 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -832,11 +832,10 @@ | |
| 832 | int fileDiff; /* True for file diff. False for check-in diff */ |
| 833 | int omitDescenders; /* True to omit descenders */ |
| 834 | int scrollToSelect; /* True to scroll to the selection */ |
| 835 | int dwellTimeout; /* Milliseconds to wait for tooltips to show */ |
| 836 | int closeTimeout; /* Milliseconds to wait for tooltips to close */ |
| 837 | u8 *aiMap; /* The rail map */ |
| 838 | |
| 839 | iRailPitch = atoi(PD("railpitch","0")); |
| 840 | showArrowheads = skin_detail_boolean("timeline-arrowheads"); |
| 841 | circleNodes = skin_detail_boolean("timeline-circle-nodes"); |
| @@ -845,15 +844,10 @@ | |
| 844 | omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 845 | fileDiff = (tmFlags & TIMELINE_FILEDIFF)!=0; |
| 846 | scrollToSelect = (tmFlags & TIMELINE_NOSCROLL)==0; |
| 847 | dwellTimeout = atoi(db_get("timeline-dwelltime","100")); |
| 848 | closeTimeout = atoi(db_get("timeline-closetime","250")); |
| 849 | @ <script id='timeline-data-%d(iTableId)' type='application/json'>{ |
| 850 | @ "iTableId": %d(iTableId), |
| 851 | @ "circleNodes": %d(circleNodes), |
| 852 | @ "showArrowheads": %d(showArrowheads), |
| 853 | @ "iRailPitch": %d(iRailPitch), |
| @@ -865,11 +859,11 @@ | |
| 859 | @ "scrollToSelect": %d(scrollToSelect), |
| 860 | @ "nrail": %d(pGraph->mxRail+1), |
| 861 | @ "baseUrl": "%R", |
| 862 | @ "dwellTimeout": %d(dwellTimeout), |
| 863 | @ "closeTimeout": %d(closeTimeout), |
| 864 | @ "hashDigit": %d(hash_digits(1)), |
| 865 | @ "bottomRowId": "btm-%d(iTableId)", |
| 866 | if( pGraph->nRow==0 ){ |
| 867 | @ "rowinfo": null |
| 868 | }else{ |
| 869 | @ "rowinfo": [ |
| 870 |