• The forum software that supports hummy.tv has been upgraded to XenForo 2.3!

    Please bear with us as we continue to tweak things, and feel free to post any questions, issues or suggestions in the upgrade thread.

Media List Sort Order

However, as I said, I realise that this is a minority issue so won't waste any more of any one's time. I'll either just live with it or figure out my own solution.
That's not how this forum became what it is! You've spotted some kind of bug, wherever it might originate, resulting in the mis-ordering of items in the media list. That makes it worthy of investigation.
 
Thanks for that. I hope that you don't think that I've gone off in a huff. :)

Again, I emphasise that I'm not claiming that it's necessarily a 'bug'. Just that the changes that I believe were made to the rename routine last summer changed the prefixes on these strings (changes that were otherwise extremely positive). It's possible that they were made for a very good functional reason. It's possible that it was to provide a more faithful implementation of the spec. It's equally possible that it was unintentional - the effects are obviously almost always invisible. And as prpr said, trying to get anything 'right' by reverse engineering is fiendishly difficult. The only way we can ever know for certain is by asking the people who wrote the code. But that's a big ask, and is hardly justified just to satisfy my curiosity.

Thanks again. If anybody is in a position to pursue it, I'd be more than happy to provide whatever support I can. But I'm sure that I can live with, or find a way round, my problem. Rather that than become a bore. :)
 
In the sort, all those recordings whose names have the inserted '15' prefix will precede all those (mainly older) recordings that have retained their starting genuine alphanumeric character.

This seems to be the nub of it.

I actually had no idea how the settop program sorts when alphabetic is chosen. From @raydon's documentation, the 0x29A field (Title) is used for the settop program's media list, while the 0x516 field (ITitle) is shown in the I-plate. So I guess it's the Title.

Testing with HD Fox-T2 CFW3.13, indeed a 0x15 at the start of the Title does make it sort incorrectly. Apparently the Title is in some pre-determined encoding that doesn't need to be tagged. Testing indicates that this is the 7-bit ISO 6937 subset aka ASCII aka the system character set: you can't make it display characters whose encoding has the top bit set (£, accented characters. eg) or characters encoded with a two-byte sequence, regardless of prefixes

The sidecar utility sets the Title with no tag and the ITitle with a 0x106937 tag.

hmt +settitle=... sets the same value in both fields.

Now look at commit "Prevent raw utf8 display" with this rationale.
@af123
If you use the WebIf's Rename function to set a new Medialist Title or New Synopsis, it doesn't include the 0x15 prefix on the string.
This usually doesn't seem to matter... except when you get to something like "Les Misérables" when it does.
Without the 0x15, it displays the UTF-8 literally, which makes it show funny characters (technical term!).

The Humax software seems to put these 0x15's in the .hmt file by default.
The rationale doesn't seem to apply to the Title and ITitle fields. As above, I can't make it show any 'funny characters' in the Title at all; they're just stripped for display (but still count for sorting, apparently). In the ITitle field 'funny characters' (€, eg) are shown when there is no prefix or the 0x106937 prefix, but not with the 0x15 prefix. This is all quite dispiriting.
 
Last edited:
We can't, we don't have permission

a 0x15 at the start of the Title does make it sort incorrectly.
Would it sort correctly if all titles were prefixed instead of only some? Would it do any harm to prefix all titles?

The Humax software seems to put these 0x15's in the .hmt file by default.
Every time or only when the title includes a particular encoding? If not every time, how does the Humax manage to sort correctly? Or doesn't it??
 
We can't, we don't have permission
Well, not no permission (403), but the link works now. The change is also shown in the post linked in the same line.

Would it sort correctly if all titles were prefixed instead of only some? Would it do any harm to prefix all titles?

Apparently Title should be converted to ASCII and untagged. I'm open to suggestions, though.

The Humax software seems to put these 0x15's in the .hmt file by default.

Every time or only when the title includes a particular encoding? If not every time, how does the Humax manage to sort correctly? Or doesn't it??

More research needed, I would say. Perhaps that's true for Synopsis and not for ITitle.
 
Not sure if this is related/relevant, but I recall seeing odd characters in the standard user interface titles (or description?) when attempting to show some accented character. It may have had something like café in either the title or description. Although I may have remembered wrong because it copes with Pokémon.

Edit: on checking a Pokémon recording. The title was ok, but the title in the synopsis was wrong. The synopsis description was ok.
 
Last edited:
Thanks for all the comments. A few observations in response:

1) The hmt file (according to Raydon's description and my own analysis) contains five relevant separate string fields for a given recording: a) the Title (as displayed in the media list); b) the ITitle ( as displayed in the information plate); c) the Synopsis; d) the viewing Guidance; e) the channel name. They have different conventions for the string prefix (none, X'15' or X'106937'). There is some suggestion in Raydon's material that there may be differences between SD and HD recordings as to how these are used, I don't normally record in HD, so I haven't yet pursued this. I did have some exchanges with Raydon many years ago about trying to be more definitive about the uses of these fields, but it didn't come to anything.

2) For any off-air recording, the Humax obviously creates the hmt file according to its own conventions. hmt files are also created by the sidecar utility and Raydon's AV2HDR-T2 off-line utility. I'm not aware how many other packages manipulate these fields, other than the rename function, which sparked this line of investigation in the first place. Does anybody know of any?


Would it sort correctly if all titles were prefixed instead of only some? Would it do any harm to prefix all titles?

Every time or only when the title includes a particular encoding? If not every time, how does the Humax manage to sort correctly? Or doesn't it??

3) This may not work. Any list of recordings is going to include those that are untouched by custom firmware, some that have been renamed before last summer, and some that have been renamed since then. If we want them all to be sorted correctly, then none of them should include non-ASCII characters in their media list titles, nor have X'15' prefixes.

4) My hunch is that we could fix the problem by ensuring that the media list title field at offset 029A has no non-ASCII characters, and no string prefix. But before we could do that, I'd want to do more analysis as to what conventions the native humax firmware follows in various circumstances and more investigation into what other pieces of custom firmware manipulate this field. Is there any possibility of finding out from the author of the changes to the rename function why the field was changed last year? If we did apply such a rule, I would happily go back and delete the prefix from the field in each of my recordings made over the past few months.

Thanks again.
 
I'd want to do more analysis as to what conventions the native humax firmware follows in various circumstances
I think a definitive analysis of what the native code does will help enormously. If (unmodified) it produces consistent sort results, that's the target all custom facilities should conform with.

If the standard firmware does not produce consistent results, maybe a custom facility can routinely correct it... and/or, indeed, correct any inconsistencies introduced by the various custom facilities without having to rewrite them for the time being.
 
I'm not aware how many other packages manipulate these fields, other than the rename function, which sparked this line of investigation in the first place. Does anybody know of any?
These are the ones listed as dependencies of the hmt package, but some will probably just be querying information:
webif, soundout, dedup, nicesplice-magic-folders, progbackup, auto-unprotect
Is there any possibility of finding out from the author of the changes to the rename function why the field was changed last year?
I can't remember the details now, but you need to have a look at the attached which started the whole investigation. I'm not in a position to do loads of testing at the moment.
 

Attachments

Only a small test, but as far as I can tell there is a small inconsistency.
When I use humax CLI hmt function - the results are opposite to what the Humax UI shows on screen.
Recording2 - Timer recording. Used detectads (chaserun) - then it queued shrink. Humax UI shows file information ITitle incorrectly.
Recording1 - Timer recording. Recorded program, then manual queued decrypt, detectads, shrink. Humax Ui shows file information ITitle correctly.
So when I run hmt against these 2 files, it shows results opposite to the Humax UI.
It is the accented é in ITitle that is the issue.
Rich (BB code):
humax# hmt -list Pokémon\ Master\ Journeys_____20220317_1630.hmt
Format:SD
Title:Pokémon Master Journeys:...
ITitle:Pokémon Master Journeys:...
Channel:206 (POP)
Episode:0,0/0
Folder:/mnt/hd2/My Video/Pokémon Master Journeys____/
Filename:pokémon Master Journeys_____20220317_1630
Genre:Children (80)
EPG:...The Series: Detective Drizzile!: Cerise Laboratory's research data has been deleted, and everyone is determined to find out why! (S1 Ep30)

Recording Status: Valid (OK)
Flags: SD,New,Unlimited Copies,Shrunk,Addetection,
Copy count:0

Scheduled start:1647534600 (Thu Mar 17 16:30:00 2022)
Scheduled duration:1860
Recording start:1647534606 (Thu Mar 17 16:30:06 2022)
Recording end:1647536460 (Thu Mar 17 17:01:00 2022)
Duration:1854
Stored duration:1854
Play resumes at:0 seconds in.
Timezone offset:0

Service ID (SID):27424
Event ID:44350
Transport Stream ID (TSID):24640
Originating Network ID (ONID):9018
Programme Map Table PID (PMTPID):1012
Video PID:631
Audio PID:632
Bookmarks:5 = 12 648 865 1559 1854
Rich (BB code):
humax# hmt -list Pokémon\ Master\ Journeys_____20220317_0800.hmt
Format:SD
Title:Pokémon Master Journeys:...
ITitle:Pok�emon Master Journeys:...
Channel:206 (POP)
Episode:0,0/0
Folder:/mnt/hd2/My Video/Pokémon Master Journeys____/
Filename:pokémon Master Journeys_____20220317_0800
Genre:Children (80)
EPG:...The Series: Excitement From the Ultra-Shocking Start!: It's time for Ash's first Ultra Class battle, and the competition is formidable indeed! (S1 Ep29)

Recording Status: Valid (OK)
Flags: SD,Unlimited Copies,Shrunk,Addetection,
Copy count:0

Scheduled start:1647504000 (Thu Mar 17 08:00:00 2022)
Scheduled duration:1860
Recording start:1647504001 (Thu Mar 17 08:00:01 2022)
Recording end:1647505862 (Thu Mar 17 08:31:02 2022)
Duration:1861
Stored duration:1859
Play resumes at:0 seconds in.
Timezone offset:0

Service ID (SID):27424
Event ID:44317
Transport Stream ID (TSID):24640
Originating Network ID (ONID):9018
Programme Map Table PID (PMTPID):1012
Video PID:631
Audio PID:632
Bookmarks:7 = 23 785 995 1459 1767 1863 1864
Code:
humax# ls -al
total 791644
drwxr-xr-x  3 root root      4096 Mar 17 17:02 .
drwxr-xr-x 28 root root     12288 Mar 17 11:55 ..
-rw-r--r--  1 root root       276 Mar 17 16:30 .series
-rw-r--r--  1 root root      2072 Mar 17 08:31 Pok??mon Master Journeys_____20220317_0800.hmt
-rw-r--r--  1 root root   1489600 Mar 17 08:31 Pok??mon Master Journeys_____20220317_0800.nts
-rw-r--r--  1 root root     43680 Mar 17 08:31 Pok??mon Master Journeys_____20220317_0800.thm
-rw-r--r--  1 root root 420486528 Mar 17 08:31 Pok??mon Master Journeys_____20220317_0800.ts
-rw-r--r--  1 root root      2072 Mar 17 17:01 Pok??mon Master Journeys_____20220317_1630.hmt
-rw-r--r--  1 root root   1483072 Mar 17 17:01 Pok??mon Master Journeys_____20220317_1630.nts
-rw-r--r--  1 root root 386288832 Mar 17 17:01 Pok??mon Master Journeys_____20220317_1630.ts
It's almost as though the Humax UI is using a different character set to the CLI.
 
Last edited:
I think a definitive analysis of what the native code does will help enormously.

Well, I can't claim a definitive analysis, but I've made a start. I've scanned through my archive of recordings over the past ten years. I've pulled out a dozen or so hmt files that illustrate the various problems that I have noticed over the years - specifically in the positioning and encoding of strings. In the attached spreadsheet, I hope that I've provided a simple enough overview of the variations. My archive recordings will have been cropped and renamed, some time after recording. The HMT Date field gives the last date that the hmt file was modified. (I've deliberately chosen recordings that haven't been watched recently.) The variations between the recordings give a feel for how the crop and rename functions have produced different results at different times. For comparison, I have also included the information in the hmt file of a programme recorded this afternoon, with no subsequent processing. The red entries indicate how the hmt files of the earlier processed recordings vary from this latest pristine one.

In particular, you will notice that the media display list title field at offset 029A has maintained a consistent non-prefixed representation until 13/14 June last year, when the X'15' prefix was introduced, hence causing the sort anomaly.

My next step is to see whether other new recordings, specifically HD ones, all produce the same format of the htm file as the one I've included in the spreadsheet. I also plan to look more closely at the format of explicitly generated hmt files from sidecar and AV2HDR-T2. I should probably also run some tests on a system without the custom firmware.

These are the ones listed as dependencies of the hmt package, but some will probably just be querying information:
webif, soundout, dedup, nicesplice-magic-folders, progbackup, auto-unprotect

I can't remember the details now, but you need to have a look at the attached which started the whole investigation. I'm not in a position to do loads of testing at the moment.

Thanks for the list of packages, I think I may have used nicesplice-magic-folders in the past, but it's not in my current repertoire. Apart from webif, I haven't used the others. From a quick glance, and from your earlier post, I think you may have been focussed on the problem of non-ASCII characters, which I haven't been involved with so far. But I'll take a closer look later. Fear not, I'm not asking anyone else to do a lot of work. But I would certainly welcome any feed back on whether the attached is of any interest, before I spend much more effort on it. I'm confident that I now have enough information to fix my own problem on my own systems if necessary.

Thanks again.
 

Attachments

This Jim TCL code from my WIP port of hmt implements my understanding of the character encodings
You appear to be missing:
Code:
if { c1 == 0x15 } {
# UTF-8 in bytes 1..end
            return [string byterange $ttxstr 1 end]
}
 
Apparently the Title is in some pre-determined encoding that doesn't need to be tagged. Testing indicates that this is the 7-bit ISO 6937 subset aka ASCII aka the system character set: you can't make it display characters whose encoding has the top bit set (£, accented characters. eg) or characters encoded with a two-byte sequence, regardless of prefixes
I think it's tagless UTF-8 not ISO-6937. The Les Mis .hmt files I posted earlier have C3 A9 for the accented e. It certainly displays correctly on-screen like this.
The sidecar utility sets the Title with no tag and the ITitle with a 0x106397 tag.
But what happens if ITitle contains characters that 6937 can't cope with? Sidecar gets it wrong that's what. Raydon's .HMT format analysis is incomplete (shock horror, he's never wrong, except when he is!) and so is his utility.
The strings at 0x516 and 0x616 don't have to start with 0x106937 - they can start with 0x15 (UTF-8).
The confusion around 0x3E2-0x3E5 can also be either format.
hmt +settitle=... sets the same value in both fields.
That would appear to be wrong too (in the presence of non-ASCII characters). As is the display apparently which doesn't try to decode, according to bottletop's tests.

And the nicesplice stuff is also wrong, using the wrong offsets (0x17F/0x180).
What a mess.

This is the trouble with taking liberties with character set processing, where it mostly doesn't matter in English... until it does.
 
Last edited:
Some of the preceeding technical descriptions are over my head, so I thought I'd detail what I did for future reference (may be useful to someone).
Accented characters on Humax UI (they may appear on the guide). This allows user to add program onto timer schedule and introduce them into the HDR file system. I couldn't enter the characters on the Humax UI, I used WebIF/EPG/EPG search, searching for title with accented characters.

Some accented characters I used from https://howtotypeanything.com/letters-with-accents
Code:
acute           Á  á  É  é  Í  í  Ó  ó  Ú  ú  Ý  ý
grave           À  à  È  è  Ì  ì  Ò  ò  Ù  ù  À  à  È
circumflex      Â  â  Ê  ê  Î  î  Ô  ô  Û  û  Â  â  Ê
tilde           Ã  ã  Ñ  ñ  Õ  õ                      
umlaut          Ä  ä  Ë  ë  Ï  ï  Ö  ö  Ü  ü  Ÿ  ÿ
Checking for odd characters - Humax CLI (works best via telnet/ssh). CLI may show what appears to be corrupt characters that the Humax UI copes with (and vice versa)
Code:
ls    -al *.hmt
hmt -list *.hmt |grep Title
My limited testing indicates the Humax UI records the programs and displays them fine.
Using custom firmware processes individually decrypt, detectads and shrink also seemed fine.
Using detectads (chaserun) seem to cause a change of ITitle.
The oddities doesn't bother me at all - just something I noticed.
 
Last edited:
You appear to be missing:
Code:
if { c1 == 0x15 } {
# UTF-8 in bytes 1..end
            return [string byterange $ttxstr 1 end]
}
Yes. I had a look at the specs again and the code needed to be revised.
 
Last edited:
Tests with hmt +settitle=x
Code:
hmt "+settitle=$(printf 'title string with funny characters')"  "$ts_name"
Let's look at Title (0x29A) and ITitle (0x516).
  1. x is ISO6937 containing "é" == 0xc265, no tag: Title displays e for é, ITitle correct.
  2. x is ISO6937 containing "é" == 0xc265, tag 0x106937: Title gets "i7" prefix and e for é, ITitle correct.
  3. x is UTF-8 containing "é" == 0xc3a9, no tag: Title displays OK, ITitle corrupted.
  4. x is UTF-8 containing "é" == 0xc3a9, tag \x15: Title displays OK, ITitle displays OK.
  5. x is ISO8859-1,15 containing "é" == 0xe9, no tag: Title loses é, ITitle has Ø for é.
  6. x is ISO8859-15 containing "é" == 0xe9, tag \x0b: Title loses é, ITitle correct.
  7. x is ISO8859-1 containing "é" == 0xe9, tag 0x100001: Title loses é, ITitle missing.
  8. x is UCS-2 containing "é" == 0x00e9, tag \x0b: Title loses é, ITitle corrupted.
The HD Fox-T2 CFW3.13 settop program sets the Title with no tag and and the ITitle and Synopsis with tag 0x106937.

In the Glums test archive, the Title and Synopsis are untagged and the ITitle has tag 0x15. These may have been processed by WebIf in some way. Also, WTF is going on in the pathname field (0x80) where the é is encoded as 0xcc82e28098?

So apparently the only ways to have "funny characters" in the Title and ITitle using the same encoding for both are:
  • UTF-8 with no tag in Title, with 0x15 tag in ITitle
  • UTF-8 with 0x15 tag in Title and ITitle.
Neither is what the system creates by default.

To make sorting work properly, perhaps we should omit the tag in Title when updating a .hmt.

In passing, the box OS theoretically understands only ASCII, but it can't tell that from UTF-8. The telnet executable knows how to display UTF-8. Things like vi's cursor can get confused by multibyte character encodings.
 
Last edited:
I've carried out further tests, and captured the results in the attached updated spreadsheet. I hope that you can read it, and that it's obvious. There are three types of entry: those produced directly by the system which are included, for reference; those modified by different versions of the custom software over the years; those generated by Raydon's utilities. Please let me know if you have any questions.

I'll try to answer as many of your points as I can; apologies for the resultant length of the post.

I'm curious how the hmt utility (which provides a decode of the .hmt file in human-readable form) handles these variations, in particular whether it mimics what's seen on-screen. It should, and if it doesn't it needs updating.

If the firmware history includes an alteration of the start index for the display title from 017F to 0180, how does the new firmware interoperate with old recordings? If the start index is actually variable, how is it indicated? If the index has changed, have the utilities (such as rename) been updated in accordance?

The display function of hmt seems to handle them without difficulty. The string encoding problem is relatively invisible, unless one goes outside the ASCII character set. However, both bottletop and /df are looking into this. I haven't yet done any tests on using hmt to modify the contents of the file.

The note that I attached to Raydon's hmt map in the Wiki many years ago, suggests that the offset 017F/0180 problem went back even further than that. It also suggests that af123 might have changed hmt the utility to accommodate the ambiguity.

As a test, I moved the file name in an original recording from offset 0180 to 0178 (sic). The Webif rename routine seemed quite happy to display the correct name, rename it, and store it back at 0178. I speculated earlier that it might be just working on the path and file name fields as a concatenated string, but I don't know.

There may have been slightly different HMT versions in different OEM FW versions.

All the differences that I have found arise from various aspects of the custom firmware. The only anomaly I've ever encountered in hmt files produced by the the Humax firmware itself is in the encoding of the text fields in the iPlate. For some reason, SD files use ISO 6937, whilst HD recordings use utf8. Raydon noted this in his map of the hmt format - but...

But what happens if ITitle contains characters that 6937 can't cope with? Sidecar gets it wrong that's what. Raydon's .HMT format analysis is incomplete (shock horror, he's never wrong, except when he is!) and so is his utility.

In fact, Raydon developed two mechanisms for generating hmt files: sidecar as part of the Webif and AVHDR-T2 as an offline utility. They disagree with each other both with regard to the offset 017F/0180 problem, and in the use of encoding standards. (examples attached). I apologise for not being able to persuade him to look into this subject. But it didn't seem to affect anybody else at the time. It's only the sort problem that has caused me to look at it again.

Why does crop have any input to this?

And the nicesplice stuff is also wrong, using the wrong offsets (0x17F/0x180).

I thought at first that crop that was causing the the 017F/0180 problem, but it also happens with rename without crop. And history shows that nicesplice is also involved somewhere. Perhaps someone who understands the structure of the custom software better than I do will know if there's a common source to the problem.

Tests with hmt +settitle=x
Code:
hmt "+settitle=$(printf 'title string with funny characters')"  "$ts_name"
Let's look at Title (0x29A) and ITitle (0x516).
  1. x is ISO6937 containing "é" == 0xc265, no tag: Title displays e for é, ITitle correct.
  2. x is ISO6937 containing "é" == 0xc265, tag 0x106937: Title gets "i7" prefix and e for é, ITitle correct.
  3. x is UTF-8 containing "é" == 0xc3a9, no tag: Title displays OK, ITitle corrupted.
  4. x is UTF-8 containing "é" == 0xc3a9, tag \x15: Title displays OK, ITitle displays OK.
  5. x is ISO8859-1,15 containing "é" == 0xe9, no tag: Title loses é, ITitle has Ø for é.
  6. x is ISO8859-15 containing "é" == 0xe9, tag \x0b: Title loses é, ITitle correct.
  7. x is ISO8859-1 containing "é" == 0xe9, tag 0x100001: Title loses é, ITitle missing.
  8. x is UCS-2 containing "é" == 0x00e9, tag \x0b: Title loses é, ITitle corrupted.
The HD Fox-T2 CFW3.13 settop program sets the Title with no tag and and the ITitle and Synopsis with tag 0x106937.

In the Glums test archive, the Title and Synopsis are untagged and the Ititle has tag 0x15. These may have been processed by WebIf in some way. Also, WTF is going on in the pathname field (0x80) where the é is encoded as 0xcc82e28098?

So apparently the only ways to have "funny characters" in the Title and ITitle using the same encoding for both are:
  • UTF-8 with no tag in Title, with 0x15 tag in ITitle
  • UTF-8 with 0x15 tag in Title and ITitle.
Neither is what the system creates by default.

To make sorting work properly, perhaps we should omit the tag in Title when updating a .hmt.

In passing, the box OS theoretically understands only ASCII, but it can't tell that from UTF-8. The telnet executable knows how to display UTF-8. Things like vi's cursor can get confused by multibyte character encodings.

I hope that the attached gives you a clear view of what the system does by default - specifically which fields are prefix-less, which have a utf8 prefix, and which have an ISO 6937 prefix. It also shows the ways in which some of our custom packages differ from this convention. Sorry, but I can't answer your question about the pathname!

This is all quite dispiriting.

What a mess.

Indeed so. But it's also actually quite an encouraging sign. I hope that the attached spreadsheet gives at least some tentative reassurance that a) we know what encoding the base system uses in all the relevant text fields; b) apart from the sort problem with the title field (offset 029A), we know that both the underlying and the custom software is quite tolerant of errors. That gives me some confidence that these various problems might be remedied without undue difficulty, and without undue compatibility issues.

But that depends on whether we think it's a worthwhile goal.
 

Attachments

The main issue, the sort order, can be fixed by not putting a 0x15 in the Title, since the system seems to treat that as UTF-8 by default. But that means changing the hmt utility.

The tag in the ITitle is explained once one remembers that SD and HD have different formats. Is this a standard feature, or related to the CFW EPG decoder?

I'm sure we could come up with a Jim script that would retrospectively remove any 0x15 from the Title in a .hmt, and so to all in a folder, etc.
 
Last edited:
Using custom firmware processes individually decrypt, detectads and shrink also seemed fine.
Using detectads (chaserun) seem to cause a change of ITitle.
The oddities doesn't bother me at all - just something I noticed.
Detectads uses the hmt program to modify titles, I believe nicesplice (used in chaserun and crop/join) modifies the hmt directly but haven't looked at it for a few years
 
From the spreadsheet, the filename position issue seems to be localised to the period before 2014, and so to whatever OEM firmware version applied then. Grantchester (2014) looks to have been recorded before the firmware was upgraded.
 
Back
Top