SageTV Community  

Go Back   SageTV Community > SageTV Products > SageTV Software
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

SageTV Software Discussion related to the SageTV application produced by SageTV. Questions, issues, problems, suggestions, etc. relating to the SageTV software application should be posted here. (Check the descriptions of the other forums; all hardware related questions go in the Hardware Support forum, etc. And, post in the customizations forum instead if any customizations are active.)

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 03-12-2017, 03:58 PM
amg amg is offline
Sage Advanced User
 
Join Date: Jan 2005
Posts: 161
Search for actor yields no results and Java Exception

I am running SageTV v9 in a docker on unRaid using Schedules Direct. The wiz.bin was copied from a v7 windows install after v9 was installed.

I am encountering an error when I try to search for a Person. Below is from the log when I search for Tom Hanks from the airing for Big.


Code:
Sun 3/12 17:49:58.847 [EventRouter-001d6a4bfb2a@2852cff8] processOptionsMenu optionsMenu=default:OPUS4A-122528|OptionsMenu:People In Show Options
Sun 3/12 17:49:58.850 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:49:58.850 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:49:58.850 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=1335 name=Elizabeth Perkins
Sun 3/12 17:49:58.851 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=1335 name=Elizabeth Perkins
Sun 3/12 17:49:58.851 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=55343 name=Robert Loggia
Sun 3/12 17:49:58.851 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=55343 name=Robert Loggia
Sun 3/12 17:49:58.852 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=749 name=John Heard
Sun 3/12 17:49:58.852 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=749 name=John Heard
Sun 3/12 17:49:58.852 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=29840 name=Jared Rushton
Sun 3/12 17:49:58.852 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=29840 name=Jared Rushton
Sun 3/12 17:49:58.853 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:49:58.853 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:49:58.853 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=1335 name=Elizabeth Perkins
Sun 3/12 17:49:58.853 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=1335 name=Elizabeth Perkins
Sun 3/12 17:49:58.853 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=55343 name=Robert Loggia
Sun 3/12 17:49:58.854 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=55343 name=Robert Loggia
Sun 3/12 17:49:58.854 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=749 name=John Heard
Sun 3/12 17:49:58.854 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=749 name=John Heard
Sun 3/12 17:49:58.854 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=29840 name=Jared Rushton
Sun 3/12 17:49:58.854 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=29840 name=Jared Rushton
Sun 3/12 17:49:58.927 [FinalRender-001d6a4bfb2a@4b8b6b9e] MiniClient did not succeed with menu hint change to:menuName:LiveTVGuide w/ Optional Preview, popupName:People In Show Options, hasTextInput:false, errcode=1
Sun 3/12 17:50:01.820 [EventRouter-001d6a4bfb2a@2852cff8] processUserEvent-UserEvent[down] evtTime=Sun 3/12 17:50:01.820
Sun 3/12 17:50:01.821 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:50:01.821 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:50:02.528 [EventRouter-001d6a4bfb2a@2852cff8] processUserEvent-UserEvent[select] evtTime=Sun 3/12 17:50:02.528
Sun 3/12 17:50:02.528 [EventRouter-001d6a4bfb2a@2852cff8] ERROR Could not resolve aliased person back to original person id=62982 name=Tom Hanks
Sun 3/12 17:50:02.528 [EventRouter-001d6a4bfb2a@2852cff8] java.lang.NullPointerException
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Wizard.getAliasesForPerson(Wizard.java:7039)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Wizard.searchByExactPerson(Wizard.java:7022)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.api.Database$13.runSafely(Database.java:2145)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.PredefinedJEPFunction.run(PredefinedJEPFunction.java:110)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.jep.JEP$CommandEvaluator.evaluate(JEP.java:586)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.jep.JEP.getValueAsObject(JEP.java:428)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Catbert.evaluateExpression(Catbert.java:641)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.processChain(ZPseudoComp.java:4641)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.processChain(ZPseudoComp.java:4579)
Sun 3/12 17:50:02.529 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.actionPerformed(ZPseudoComp.java:4562)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.action(ZPseudoComp.java:3800)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.PseudoMenu.action(PseudoMenu.java:225)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.EventRouter.processUserEvent(EventRouter.java:882)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.EventRouter.run(EventRouter.java:942)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at java.lang.Thread.run(Thread.java:745)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8] EXCEPTION in getValueAsObject:sage.jep.ParseException: Error in method reflection of SearchByPerson of java.lang.NullPointerException for:SearchByPerson(Person,"TVD")
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8] sage.jep.ParseException: Error in method reflection of SearchByPerson of java.lang.NullPointerException
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.PredefinedJEPFunction.run(PredefinedJEPFunction.java:119)
Sun 3/12 17:50:02.530 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.jep.JEP$CommandEvaluator.evaluate(JEP.java:586)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.jep.JEP.getValueAsObject(JEP.java:428)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Catbert.evaluateExpression(Catbert.java:641)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.processChain(ZPseudoComp.java:4641)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.processChain(ZPseudoComp.java:4579)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.actionPerformed(ZPseudoComp.java:4562)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.ZPseudoComp.action(ZPseudoComp.java:3800)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.PseudoMenu.action(PseudoMenu.java:225)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.EventRouter.processUserEvent(EventRouter.java:882)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.EventRouter.run(EventRouter.java:942)
Sun 3/12 17:50:02.531 [EventRouter-001d6a4bfb2a@2852cff8]       at java.lang.Thread.run(Thread.java:745)
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8] Caused by: java.lang.NullPointerException
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Wizard.getAliasesForPerson(Wizard.java:7039)
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.Wizard.searchByExactPerson(Wizard.java:7022)
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.api.Database$13.runSafely(Database.java:2145)
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8]       at sage.PredefinedJEPFunction.run(PredefinedJEPFunction.java:110)
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8]       ... 11 more
Sun 3/12 17:50:02.532 [EventRouter-001d6a4bfb2a@2852cff8] processOptionsMenu optionsMenu=default:BASE-63501|OptionsMenu:Your search returned no results.
Sun 3/12 17:50:02.542 [FinalRender-001d6a4bfb2a@4b8b6b9e] MiniClient did not succeed with menu hint change to:menuName:LiveTVGuide w/ Optional Preview, popupName:Your search returned no results., hasTextInput:false, errcode=1
^C
__________________
unRaid Server:Quad-Core Xenon, 20 GB Ram, openDCT/sageTV Dockers, HDHR,HDHR Prime
Network Encoder:Dell Inspiron 1000 Laptop, 512MB Ram, Windows XP, HDPVR
Reply With Quote
  #2  
Old 03-12-2017, 06:51 PM
EnterNoEscape's Avatar
EnterNoEscape EnterNoEscape is offline
SageTVaholic
 
Join Date: Jun 2010
Location: Harrisburg, PA
Posts: 2,657
It looks like we're not checking for a null condition because Fiber always had the real names for all of the Persons. Unfortunately Schedules Direct does not provide nearly as much data as Google did and doesn't provide any way to get that information outside of the shows airing right now. I didn't want to provide an alias as an original name (because it's not correct), but it doesn't look like we have a choice if we are trying to do lookups like this. The way I'd attack it is to put the alias in as the original name and always overwrite the original name any time we encounter an instance of the original name. It's just very inefficient logic and I'm thinking I'd rather just handle the null pointer exception and remove all of that alias error logging instead because then we won't have incorrect aliases.
__________________
SageTV v9 Server: ASRock Z97 Extreme4, Intel i7-4790K @ 4.4Ghz, 32GB RAM, 6x 3TB 7200rpm HD, 2x 5TB 7200rpm HD, 2x 6TB 7200rpm HD, 4x 256GB SSD, 4x 500GB SSD, unRAID Pro 6.7.2 (Dual Parity + SSD Cache).
Capture: 1x Ceton InfiniTV 4 (ClearQAM), 2x Ceton InfiniTV 6, 1x BM1000-HDMI, 1x BM3500-HDMI.

Clients: 1x HD300 (Living Room), 1x HD200 (Master Bedroom).
Software: OpenDCT :: WMC Live TV Tuner :: Schedules Direct EPG
Reply With Quote
  #3  
Old 03-13-2017, 09:26 AM
amg amg is offline
Sage Advanced User
 
Join Date: Jan 2005
Posts: 161
I just started looking at the code, so forgive me if I'm off base....

I think there may be an issue in my DB. I dumped the DB by setting dump_db_on_startup to true.

In my Wiz.dump, I have a number of Person objects with extID with negative numbers. I think this means it is an alias and there should be another Person object with a non-negative extID, but there is not. Am I correct?
__________________
unRaid Server:Quad-Core Xenon, 20 GB Ram, openDCT/sageTV Dockers, HDHR,HDHR Prime
Network Encoder:Dell Inspiron 1000 Laptop, 512MB Ram, Windows XP, HDPVR
Reply With Quote
  #4  
Old 03-13-2017, 09:58 AM
EnterNoEscape's Avatar
EnterNoEscape EnterNoEscape is offline
SageTVaholic
 
Join Date: Jun 2010
Location: Harrisburg, PA
Posts: 2,657
Quote:
Originally Posted by amg View Post
I just started looking at the code, so forgive me if I'm off base....

I think there may be an issue in my DB. I dumped the DB by setting dump_db_on_startup to true.

In my Wiz.dump, I have a number of Person objects with extID with negative numbers. I think this means it is an alias and there should be another Person object with a non-negative extID, but there is not. Am I correct?
That's what I was describing above. I didn't mention how it knows they are aliases, but I was explaining how we can't get the original person object from Schedules Direct which leads to this problem. There are two ways to fix this detailed above. I'm leaning towards handling the NPE instead because we end up overwriting original person objects which can temporarily remove their image links until the end of the EPG update.
__________________
SageTV v9 Server: ASRock Z97 Extreme4, Intel i7-4790K @ 4.4Ghz, 32GB RAM, 6x 3TB 7200rpm HD, 2x 5TB 7200rpm HD, 2x 6TB 7200rpm HD, 4x 256GB SSD, 4x 500GB SSD, unRAID Pro 6.7.2 (Dual Parity + SSD Cache).
Capture: 1x Ceton InfiniTV 4 (ClearQAM), 2x Ceton InfiniTV 6, 1x BM1000-HDMI, 1x BM3500-HDMI.

Clients: 1x HD300 (Living Room), 1x HD200 (Master Bedroom).
Software: OpenDCT :: WMC Live TV Tuner :: Schedules Direct EPG
Reply With Quote
  #5  
Old 04-02-2017, 08:45 AM
amg amg is offline
Sage Advanced User
 
Join Date: Jan 2005
Posts: 161
Still following up on this. Had some time to look into the code and the JSON returned from Schedules direct, trying to come up to speed.

Using Bruce Willis as an example, since he is in my wiz.bin with a negative extID of -9653.

I found an episode of Late Night with Jimmy Fallon with Bruce Wilis and this is his cast entry:
Code:
  {
                "billingOrder": "02",
                "role": "Guest",
                "nameId": "9653",
                "personId": "9653",
                "name": "Bruce Willis"
            }
Now by the isAlias() in SDPerson
Code:
  public boolean isAlias()
  {
    return personId != null && personId.length() > 0 && personId.equals(nameId);
  }
this makes the entry an alias.

Why is personId == nameId an alias?

so in SDUtils.java:512 getPerson()
Code:
    if (person.isAlias())
      personId *= -1;
The (once valid?) ID for Bruce Willis becomes negative. Once it has a negative ID, searching by person no longer works.
__________________
unRaid Server:Quad-Core Xenon, 20 GB Ram, openDCT/sageTV Dockers, HDHR,HDHR Prime
Network Encoder:Dell Inspiron 1000 Laptop, 512MB Ram, Windows XP, HDPVR
Reply With Quote
  #6  
Old 04-02-2017, 09:48 AM
EnterNoEscape's Avatar
EnterNoEscape EnterNoEscape is offline
SageTVaholic
 
Join Date: Jun 2010
Location: Harrisburg, PA
Posts: 2,657
If you haven't already, upgrade to v9.0.14. The null pointer issue should be resolved.
__________________
SageTV v9 Server: ASRock Z97 Extreme4, Intel i7-4790K @ 4.4Ghz, 32GB RAM, 6x 3TB 7200rpm HD, 2x 5TB 7200rpm HD, 2x 6TB 7200rpm HD, 4x 256GB SSD, 4x 500GB SSD, unRAID Pro 6.7.2 (Dual Parity + SSD Cache).
Capture: 1x Ceton InfiniTV 4 (ClearQAM), 2x Ceton InfiniTV 6, 1x BM1000-HDMI, 1x BM3500-HDMI.

Clients: 1x HD300 (Living Room), 1x HD200 (Master Bedroom).
Software: OpenDCT :: WMC Live TV Tuner :: Schedules Direct EPG
Reply With Quote
  #7  
Old 04-02-2017, 09:53 AM
EnterNoEscape's Avatar
EnterNoEscape EnterNoEscape is offline
SageTVaholic
 
Join Date: Jun 2010
Location: Harrisburg, PA
Posts: 2,657
Quote:
Originally Posted by amg View Post
Still following up on this. Had some time to look into the code and the JSON returned from Schedules direct, trying to come up to speed.

Using Bruce Willis as an example, since he is in my wiz.bin with a negative extID of -9653.

I found an episode of Late Night with Jimmy Fallon with Bruce Wilis and this is his cast entry:
Code:
  {
                "billingOrder": "02",
                "role": "Guest",
                "nameId": "9653",
                "personId": "9653",
                "name": "Bruce Willis"
            }
Now by the isAlias() in SDPerson
Code:
  public boolean isAlias()
  {
    return personId != null && personId.length() > 0 && personId.equals(nameId);
  }
this makes the entry an alias.

Why is personId == nameId an alias?

so in SDUtils.java:512 getPerson()
Code:
    if (person.isAlias())
      personId *= -1;
The (once valid?) ID for Bruce Willis becomes negative. Once it has a negative ID, searching by person no longer works.
You are right about the alias being wrong. I don't know how I didn't catch that sooner. It's only an alias if the personId doesn't match the nameId. I pushed a commit to correct this logic.
__________________
SageTV v9 Server: ASRock Z97 Extreme4, Intel i7-4790K @ 4.4Ghz, 32GB RAM, 6x 3TB 7200rpm HD, 2x 5TB 7200rpm HD, 2x 6TB 7200rpm HD, 4x 256GB SSD, 4x 500GB SSD, unRAID Pro 6.7.2 (Dual Parity + SSD Cache).
Capture: 1x Ceton InfiniTV 4 (ClearQAM), 2x Ceton InfiniTV 6, 1x BM1000-HDMI, 1x BM3500-HDMI.

Clients: 1x HD300 (Living Room), 1x HD200 (Master Bedroom).
Software: OpenDCT :: WMC Live TV Tuner :: Schedules Direct EPG

Last edited by EnterNoEscape; 04-02-2017 at 09:56 AM.
Reply With Quote
  #8  
Old 04-02-2017, 02:07 PM
amg amg is offline
Sage Advanced User
 
Join Date: Jan 2005
Posts: 161
The NPE was fixed after 9.0.14 ( a few days). I built the latest on my dev machine, and I now get results for person searches.

Will there be any other ill effects for the thousands of people in the DB that are now aliases?

Still wondering about alias though. From an episode of Shades of Blue, Drea de Matteo's person entry:
Code:
            {
                "billingOrder": "03",
                "role": "Actor",
                "nameId": "202520",
                "personId": "200635",
                "name": "Drea de Matteo",
                "characterName": "Tess Nazario"
            }
Why would this entry then become an alias? What is it an alias to? It seems like an alias would be an entry that points to another real-person. The personId is the ID that SD uses to look up metadata, I cant find a use for the nameId, yet.

Sorry if I'm becoming a pain, just trying to understand the code.
__________________
unRaid Server:Quad-Core Xenon, 20 GB Ram, openDCT/sageTV Dockers, HDHR,HDHR Prime
Network Encoder:Dell Inspiron 1000 Laptop, 512MB Ram, Windows XP, HDPVR
Reply With Quote
  #9  
Old 04-02-2017, 05:35 PM
EnterNoEscape's Avatar
EnterNoEscape EnterNoEscape is offline
SageTVaholic
 
Join Date: Jun 2010
Location: Harrisburg, PA
Posts: 2,657
Schedules Direct doesn't really explain what's going on here very well. It does explain the that personID is used to get images. It doesn't explain that if the personID does not match the nameID, it's a former name/alias. The nameID correlates with a name. The personID correlates with the actual person which will not change regardless of what they call themselves today.

There really aren't any significant problems with having an alias, but no actual person. The alias from what I can tell is mostly just used to improve searches.

The request/implementation in SageTV starts being discussed in detail here.

Edit: You're right about the post 9.0.14 fix. I was looking at the wrong commit when I said that.
__________________
SageTV v9 Server: ASRock Z97 Extreme4, Intel i7-4790K @ 4.4Ghz, 32GB RAM, 6x 3TB 7200rpm HD, 2x 5TB 7200rpm HD, 2x 6TB 7200rpm HD, 4x 256GB SSD, 4x 500GB SSD, unRAID Pro 6.7.2 (Dual Parity + SSD Cache).
Capture: 1x Ceton InfiniTV 4 (ClearQAM), 2x Ceton InfiniTV 6, 1x BM1000-HDMI, 1x BM3500-HDMI.

Clients: 1x HD300 (Living Room), 1x HD200 (Master Bedroom).
Software: OpenDCT :: WMC Live TV Tuner :: Schedules Direct EPG

Last edited by EnterNoEscape; 04-02-2017 at 05:43 PM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
YouTube - how to see more search results bastafidli SageTV Software 1 07-21-2009 06:37 AM
IMDB Search Actor picture still missing! mkanet SageMC Custom Interface 4 04-09-2008 07:14 AM
strange Favorite search results dvd_maniac SageTV Software 2 09-19-2006 07:51 PM
Search brings up expired results malore SageTV Software 0 09-05-2003 10:52 AM
Beta V1.2.2 Java java.lang Null Pointer Exception hamptonhills SageTV Beta Test Software 1 03-27-2003 12:11 PM


All times are GMT -6. The time now is 07:12 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.