示例#1
0
 def __init__(self):
     self.m_vcStart = GCGregorianDate()
     self.m_vcEnd = GCGregorianDate()
     self.m_options = 0
     self.m_location = GCLocation()
     self.p_events = []
     self.b_sorted = True
def unittests():
    GCUT.info('result app')
    loc = GCLocation(
        data={
            'latitude': 48.150002,
            'longitude': 17.116667,
            'tzid': 321,
            'name': 'Bratislava, Slovakia'
        })
    earth = loc.GetEarthData()
    today = Today()

    tc = TAppDay()

    print('start calculate', datetime.datetime.now())
    tc.calculateAppDay(loc, today)
    print('end calculate', datetime.datetime.now())

    with open('test/app.xml', 'wt') as wf:
        tc.formatXml(wf)
    with open('test/app.txt', 'wt') as wf:
        tc.formatPlainText(wf)
    with open('test/app.rtf', 'wt') as wf:
        tc.formatRtf(wf)
    with open('test/app.html', 'wt') as wf:
        tc.writeHtml(wf)
示例#3
0
def unittests():
    GCUT.info('core events results')
    loc = GCLocation(
        data={
            'latitude': 48.150002,
            'longitude': 17.116667,
            'tzid': 321,
            'name': 'Bratislava, Slovakia'
        })
    earth = loc.GetEarthData()
    today = Today()
    future = GCGregorianDate(date=today, addDays=100)

    tc = TCoreEvents()

    print('start calculate', datetime.datetime.now())
    tc.CalculateEvents(loc, today, future)
    print('end calculate', datetime.datetime.now())

    with open('test/events.xml', 'wt') as wf:
        tc.formatXml(wf)
    with open('test/events.txt', 'wt') as wf:
        tc.formatText(wf)
    with open('test/events.rtf', 'wt') as wf:
        tc.formatRtf(wf)
    with open('test/events.html', 'wt') as wf:
        tc.writeHtml(wf)
 def __init__(self):
     self.m_location = GCLocation()
     self.eventTime = GCGregorianDate()
     self.details = GCDayData()
     self.b_adhika = False
     self.celeb_gy = [0] * TRESULT_APP_CELEBS
     self.celeb_date = [
         GCGregorianDate() for i in range(TRESULT_APP_CELEBS)
     ]
def ImportFile(pszFile, bDeleteCurrent=False):
    global locationList
    with open(pszFile, 'rt', encoding='utf-8') as json_file:
        locations = json.load(json_file)
        if bDeleteCurrent:
            locationList = []
        for a in locations:
            locationList.append(GCLocation(data=a))
        m_bModified = True
    def CalculateMasaList(self, loc, year, count):
        day = GCDayData()
        earth = loc.GetEarthData()

        self.startYear = year
        self.countYears = count
        self.start = GCGregorianDate(date=GetFirstDayOfYear(earth, year))
        self.end = GCGregorianDate(date=GetFirstDayOfYear(earth, year + count))
        self.location = GCLocation()
        self.location.Set(loc)

        i = 0
        prev_masa = -1
        prev_paksa = -1
        prev_gyear = -1
        current = 0
        d = GCGregorianDate(date=self.start)

        while d.IsBeforeThis(self.end):
            day.DayCalc(d, earth)
            if prev_paksa != day.nPaksa:
                day.nMasa = day.MasaCalc(d, earth)
                if prev_masa != day.nMasa:
                    if len(self.arr) > 0:
                        self.arr[-1]['end'] = GCGregorianDate(date=d,
                                                              addDays=-1)
                    prev_masa = day.nMasa
                    self.arr.append({
                        'masa':
                        day.nMasa,
                        'masaName':
                        GCStrings.GetMasaName(day.nMasa),
                        'year':
                        day.nGaurabdaYear,
                        'start':
                        GCGregorianDate(date=d)
                    })
            prev_paksa = day.nPaksa
            d.NextDay()

        self.arr[-1]['end'] = GCGregorianDate(date=d, addDays=-1)
        return len(self.arr)
def unittests():
    GCUT.info('sankranti')
    vc = Today()
    vc2 = GCGregorianDate()
    vc3 = GCGregorianDate(date=vc)
    vc3.AddDays(100)
    n = GetSankMethodName(GetSankrantiType())
    GCUT.msg('Sankranti Type: {}'.format(n))
    import io
    s = io.StringIO()
    clr = GCLocation()
    writeXml(s, clr, vc, vc3)
    GCUT.msg(s.getvalue())
示例#8
0
def unittests():
    GCUT.info('today results')
    loc = GCLocation(data={
        'latitude': 48.150002,
        'longitude': 17.116667,
        'tzid': 321,
        'name': 'Bratislava, Slovakia'
    })
    earth = loc.GetEarthData()
    today = Today()

    tc = TToday()

    print('start calculate', datetime.datetime.now())
    tc.Calculate(today,loc)
    print('end calculate', datetime.datetime.now())

    with open('test/today.txt','wt') as wf:
        tc.formatPlain(wf)
    with open('test/today.rtf','wt') as wf:
        tc.formatRtf(wf)
    with open('test/today.html','wt') as wf:
        tc.writeHtml(wf)
def unittests():
    tm = TMasaList()
    loc = GCLocation(
        data={
            'latitude': 48.150002,
            'longitude': 17.116667,
            'tzid': 321,
            'name': 'Bratislava, Slovakia'
        })
    tm.CalculateMasaList(loc, 2020, 2)

    with open('test/masalist.rtf', 'wt') as wf:
        tm.formatRtf(wf)
    with open('test/masalist.html', 'wt') as wf:
        tm.writeHtml(wf)
class TMasaList:
    def __init__(self):
        self.start = None
        self.end = None
        self.countYears = 0
        self.countMasa = 0
        self.startYear = 0
        self.location = None
        self.arr = []

    def CalculateMasaList(self, loc, year, count):
        day = GCDayData()
        earth = loc.GetEarthData()

        self.startYear = year
        self.countYears = count
        self.start = GCGregorianDate(date=GetFirstDayOfYear(earth, year))
        self.end = GCGregorianDate(date=GetFirstDayOfYear(earth, year + count))
        self.location = GCLocation()
        self.location.Set(loc)

        i = 0
        prev_masa = -1
        prev_paksa = -1
        prev_gyear = -1
        current = 0
        d = GCGregorianDate(date=self.start)

        while d.IsBeforeThis(self.end):
            day.DayCalc(d, earth)
            if prev_paksa != day.nPaksa:
                day.nMasa = day.MasaCalc(d, earth)
                if prev_masa != day.nMasa:
                    if len(self.arr) > 0:
                        self.arr[-1]['end'] = GCGregorianDate(date=d,
                                                              addDays=-1)
                    prev_masa = day.nMasa
                    self.arr.append({
                        'masa':
                        day.nMasa,
                        'masaName':
                        GCStrings.GetMasaName(day.nMasa),
                        'year':
                        day.nGaurabdaYear,
                        'start':
                        GCGregorianDate(date=d)
                    })
            prev_paksa = day.nPaksa
            d.NextDay()

        self.arr[-1]['end'] = GCGregorianDate(date=d, addDays=-1)
        return len(self.arr)

    def formatText(self, stream):
        sb = GCStringBuilder.GCStringBuilder(stream)
        sb.Format = GCStringBuilder.SBTF_TEXT

        stream.write(" {}\r\n\r\n{}: {}\r\n".format(
            GCStrings.getString(39), GCStrings.getString(40),
            self.location.m_strFullName))
        stream.write("{} {} {} {}\r\n".format(GCStrings.getString(41),
                                              str(self.start),
                                              GCStrings.getString(42),
                                              str(self.end)))
        stream.write("=" * 65)
        stream.write("\r\n\r\n")

        for m in self.arr:
            stream.write('{:30s}'.format('{} {}'.format(
                m['masaName'], m['year'])))
            stream.write('   {} - {}\r\n'.format(
                str(m['start']).rjust(12, ' '),
                str(m['end']).rjust(12, ' ')))

        sb.AppendNote()
        sb.AppendDocumentTail()
        return 1

    def formatRtf(self, stream):
        sb = GCStringBuilder.GCStringBuilder(stream)
        sb.Format = GCStringBuilder.SBTF_RTF
        sb.fontSizeH1 = GCLayoutData.textSizeH1
        sb.fontSizeH2 = GCLayoutData.textSizeH2
        sb.fontSizeText = GCLayoutData.textSizeText
        sb.fontSizeNote = GCLayoutData.textSizeNote

        sb.AppendDocumentHeader()

        stream.write(
            "{{\\fs{}\\f2 {} }}\\par\\tx{}\\tx{}\\f2\\fs{}\r\n\\par\r\n{}: {}\\par\r\n"
            .format(GCLayoutData.textSizeH1, GCStrings.getString(39),
                    1000 * GCLayoutData.textSizeText / 24,
                    4000 * GCLayoutData.textSizeText / 24,
                    GCLayoutData.textSizeText, GCStrings.getString(40),
                    self.location.m_strFullName))
        stream.write("{} {} {} {}\\par\r\n".format(GCStrings.getString(41),
                                                   str(self.start),
                                                   GCStrings.getString(42),
                                                   str(self.end)))
        sb.AppendSeparatorWithWidth(65)
        sb.AppendLine()
        sb.AppendLine()

        for m in self.arr:
            stream.write('\\tab {} {}\\tab '.format(m['masaName'], m['year']))
            stream.write('{} - '.format(str(m['start'])))
            stream.write('{}\\par\r\n'.format(str(m['end'])))

        sb.AppendNote()
        sb.AppendDocumentTail()

        return 1

    def writeXml(self, stream):
        stream.write("<xml>\r\n")
        stream.write("   <body title=\"Masa List\">\n\n")
        stream.write("      <location>{}</location>\r\n".format(
            self.location.m_strFullName))
        stream.write("      <masalist>\r\n")
        for m in self.arr:
            stream.write(
                "         <masa name=\"{}\" year=\"{}\" start=\"{}\" end=\"{}\" />\r\n"
                .format(m['masaName'], m['year'], str(m['start']),
                        str(m['end'])))
        stream.write("      </masalist>\r\n")
        stream.write("      <author>{}</author>\r\n".format(
            GCStrings.getString(130)))
        stream.write("   </body>\r\n</xml>\r\n")
        return 1

    def writeHtml(self, stream):
        stream.write("<html>\n<head>\n<title>Masa List</title>\n\n")
        stream.write(
            "<style>\n<!--\nbody {\n  font-family:Verdana;\n  font-size:11pt;\n}\n\ntd.hed {\n  font-size:11pt;\n  font-weight:bold;\n"
        )
        stream.write(
            "  background:#aaaaaa;\n  color:white;\n  text-align:center;\n  vertical-align:center;\n  padding-left:15pt;\n  padding-right:15pt;\n"
        )
        stream.write(
            "  padding-top:5pt;\n  padding-bottom:5pt;\n}\n-->\n</style>\n")
        stream.write("</head>\n")
        stream.write("<body>\n\n")

        stream.write(
            "<p style=\'text-align:center\'><span style=\'font-size:14pt\'>Masa List</span></br>{}: {}</p>\n"
            .format(GCStrings.getString(40), self.location.m_strFullName))
        stream.write("<p align=center>{} {} {} {} </p>\n".format(
            GCStrings.getString(41), str(self.start), GCStrings.getString(42),
            str(self.end)))
        stream.write("<hr width=\"50%\">")

        stream.write("<table align=center>")
        stream.write(
            "<tr><td class=\"hed\" style=\'text-align:left\'>MASA NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td class=\"hed\">START</td><td class=\"hed\">END</td></tr>"
        )

        for m in self.arr:
            stream.write("<tr>")
            stream.write("<td>{} {}&nbsp;&nbsp;&nbsp;&nbsp;</td>".format(
                m['masaName'], m['year']))
            stream.write("<td>{}</td>".format(str(m['start'])))
            stream.write("<td>{}</td>".format(str(m['end'])))
            stream.write("</tr>")

        stream.write("</table>")
        stream.write(
            "<hr width=\"50%%\">\n<p align=center>Generated by {}</p>".format(
                GCStrings.getString(130)))
        stream.write("</body></html>")
        return 1

    def write(self, stream, format='html'):
        if format == 'plain':
            self.formatText(stream)
        elif format == 'rtf':
            self.formatRtf(stream)
        elif format == 'xml':
            self.writeXml(stream)
        elif format == 'html':
            self.writeHtml(stream)
示例#11
0
class TAppDay:
    def __init__(self):
        self.m_location = GCLocation()
        self.eventTime = GCGregorianDate()
        self.details = GCDayData()
        self.b_adhika = False
        self.celeb_gy = [0] * TRESULT_APP_CELEBS
        self.celeb_date = [
            GCGregorianDate() for i in range(TRESULT_APP_CELEBS)
        ]

    def calculateAppDay(self, location, eventDate):
        d = self.details
        vc = GCGregorianDate(date=eventDate)
        vcsun = GCGregorianDate(date=eventDate)
        dprev = GCGregorianDate()
        dnext = GCGregorianDate()
        m_earth = location.GetEarthData()

        self.b_adhika = False
        self.eventTime.Set(eventDate)
        self.m_location.Set(location)

        vcsun.shour -= vcsun.tzone / 24.0
        vcsun.NormalizeValues()
        vcsun.tzone = 0.0
        d.sun.SunPosition(vcsun, m_earth, vcsun.shour - 0.5)
        d.moon.Calculate(vcsun.GetJulianComplete(), m_earth)
        d.msDistance = GCMath.putIn360(d.moon.longitude_deg -
                                       d.sun.longitude_deg - 180.0)
        d.msAyanamsa = GCAyanamsha.GetAyanamsa(vc.GetJulianComplete())

        # tithi
        dd = d.msDistance / 12.0
        d.nTithi = int(floor(dd))
        d.nTithiElapse = (dd - floor(dd)) * 100.0

        # naksatra
        dd = GCMath.putIn360(d.moon.longitude_deg - d.msAyanamsa)
        dd = (dd * 3.0) / 40.0
        d.nNaksatra = int(floor(dd))
        d.nNaksatraElapse = (dd - floor(dd)) * 100.0
        d.nMasa = d.MasaCalc(vc, m_earth)
        d.nMoonRasi = GCRasi.GetRasi(d.moon.longitude_deg, d.msAyanamsa)
        d.nSunRasi = GCRasi.GetRasi(d.sun.longitude_deg, d.msAyanamsa)

        if (d.nMasa == ADHIKA_MASA):
            d.nMasa = GCRasi.GetRasi(d.sun.longitude_deg, d.msAyanamsa)
            self.b_adhika = True

        vc.Today()
        vc.tzone = m_earth.tzone
        m = 0
        va = GCGaurabdaDate()
        vctemp = GCGregorianDate()

        va.tithi = d.nTithi
        va.masa = d.nMasa
        va.gyear = GCCalendar.GetGaurabdaYear(vc, m_earth)
        if (va.gyear < d.nGaurabdaYear):
            va.gyear = d.nGaurabdaYear

        for i in range(6):
            GCCalendar.Gaurabda2Gregorian(va, vctemp, m_earth)
            if (va.gyear > d.nGaurabdaYear):
                if (m < TRESULT_APP_CELEBS):
                    self.celeb_date[m].Set(vctemp)
                    self.celeb_gy[m] = va.gyear
                    m += 1
            va.gyear += 1

    def formatPlainText(self, stream):
        d = self.details
        vc = GCGregorianDate(date=self.eventTime)
        m_earth = self.m_location.GetEarthData()

        sb = GCStringBuilder(stream)
        sb.Format = SBTF_TEXT

        sb.AppendLine(GCStrings.getString(25))
        sb.AppendLine("")

        sb.AppendLine("{:15s} : {} {} {}".format(
            GCStrings.getString(7), vc.day,
            GCStrings.GetMonthAbreviation(vc.month), vc.year))

        sb.AppendLine("{:15s} : {}:{:02d}".format(GCStrings.getString(8),
                                                  vc.GetHour(),
                                                  vc.GetMinuteRound()))
        sb.AppendLine("")

        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(9),
                                           self.m_location.m_strName))
        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(10),
                                           self.m_location.m_strLatitude))
        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(11),
                                           self.m_location.m_strLongitude))
        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(12),
                                           self.m_location.m_strTimeZone))
        sb.AppendLine("{:15s} : N/A".format("DST"))
        sb.AppendLine("")

        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(13),
                                           GCStrings.GetTithiName(d.nTithi)))
        sb.AppendLine("{:15s} : {:.2f} %".format(GCStrings.getString(14),
                                                 d.nTithiElapse))
        sb.AppendLine("{:15s} : {}".format(
            GCStrings.getString(15), GCStrings.GetNaksatraName(d.nNaksatra)))
        sb.AppendLine("{:15s} : {:.2f} % ({} pada)".format(
            GCStrings.getString(16), d.nNaksatraElapse,
            GCStrings.getString(811 + int(d.nNaksatraElapse / 25.0))))
        sb.AppendLine("{:15s} : {} ({})".format(
            "Moon Rasi", GCStrings.GetSankrantiName(d.nMoonRasi),
            GCStrings.GetSankrantiNameEn(d.nMoonRasi)))
        sb.AppendLine("{:15s} : {} ({})".format(
            "Sun Rasi", GCStrings.GetSankrantiName(d.nSunRasi),
            GCStrings.GetSankrantiNameEn(d.nSunRasi)))

        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(20),
                                           GCStrings.GetPaksaName(d.nPaksa)))
        if (self.b_adhika == True):
            sb.AppendLine("{:15s} : {} {}".format(
                GCStrings.getString(22), GCStrings.GetMasaName(d.nMasa),
                GCStrings.getString(21)))
        else:
            sb.AppendLine("{:15s} : {}".format(GCStrings.getString(22),
                                               GCStrings.GetMasaName(d.nMasa)))
        sb.AppendLine("{:15s} : {}".format(GCStrings.getString(23),
                                           d.nGaurabdaYear))

        if (GCDisplaySettings.getValue(48)):
            sb.AppendLine()
            sb.AppendLine(GCStrings.getString(17))
            sb.AppendLine()

            sb.AppendLine("%25s : {}... ".format(
                GCStrings.getString(18),
                GCStrings.GetNaksatraChildSylable(
                    d.nNaksatra, int(d.nNaksatraElapse / 25.0))))
            sb.AppendLine("%25s : {}... ".format(
                GCStrings.getString(19),
                GCStrings.GetRasiChildSylable(d.nMoonRasi)))

        sb.AppendLine()
        sb.AppendLine(GCStrings.getString(24))
        sb.AppendLine()

        for o in range(TRESULT_APP_CELEBS):
            sb.AppendLine("   Gaurabda {:3d} : {} ".format(
                self.celeb_gy[o], self.celeb_date[o]))

        sb.AppendNote()

    def formatRtf(self, stream):
        d = self.details
        vc = GCGregorianDate(date=self.eventTime)
        m_earth = self.m_location.GetEarthData()

        sb = GCStringBuilder(stream)
        sb.fontSizeH1 = GCLayoutData.textSizeH1
        sb.fontSizeH2 = GCLayoutData.textSizeH2
        sb.fontSizeText = GCLayoutData.textSizeText
        sb.fontSizeNote = GCLayoutData.textSizeNote
        sb.Format = SBTF_RTF

        sb.AppendDocumentHeader()

        sb.AppendHeader1(GCStrings.getString(25))

        sb.AppendLine("\\tab {} : {{\\b {} {} {} }}".format(
            GCStrings.getString(7), vc.day,
            GCStrings.GetMonthAbreviation(vc.month), vc.year))

        sb.AppendLine("\\tab {} : {{\\b {}:{:02d} }}".format(
            GCStrings.getString(8), vc.GetHour(), vc.GetMinuteRound()))
        sb.AppendLine("")

        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(9), self.m_location.m_strName))
        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(10), self.m_location.m_strLatitude))
        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(11), self.m_location.m_strLongitude))
        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(12),
            GCTimeZone.GetTimeZoneName(self.m_location.m_nTimezoneId)))
        sb.AppendLine("\\tab {} : {{\\b N/A }}".format("DST"))
        sb.AppendLine("")

        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(13), GCStrings.GetTithiName(d.nTithi)))
        sb.AppendLine("\\tab {} : {{\\b {:.2f} % }}".format(
            GCStrings.getString(14), d.nTithiElapse))
        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(15), GCStrings.GetNaksatraName(d.nNaksatra)))
        sb.AppendLine("\\tab {} : {{\\b {:.2f} % ({} pada) }}".format(
            GCStrings.getString(16), d.nNaksatraElapse,
            GCStrings.getString(811 + int(d.nNaksatraElapse / 25.0))))
        sb.AppendLine("\\tab {} : {{\\b {} ({}) }}".format(
            "Moon Rasi", GCStrings.GetSankrantiName(d.nMoonRasi),
            GCStrings.GetSankrantiNameEn(d.nMoonRasi)))
        sb.AppendLine("\\tab {} : {{\\b {} ({}) }}".format(
            "Sun Rasi", GCStrings.GetSankrantiName(d.nSunRasi),
            GCStrings.GetSankrantiNameEn(d.nSunRasi)))

        sb.AppendLine("\\tab {} : {{\\b {} }}".format(
            GCStrings.getString(20), GCStrings.GetPaksaName(d.nPaksa)))
        if (self.b_adhika == True):
            sb.AppendLine("\\tab {} : {{\\b {} {} }}".format(
                GCStrings.getString(22), GCStrings.GetMasaName(d.nMasa),
                GCStrings.getString(21)))
        else:
            sb.AppendLine("\\tab {} : {{\\b {} }}".format(
                GCStrings.getString(22), GCStrings.GetMasaName(d.nMasa)))
        sb.AppendLine("\\tab {} : {{\\b {} }}".format(GCStrings.getString(23),
                                                      d.nGaurabdaYear))

        if (GCDisplaySettings.getValue(48)):
            sb.AppendLine("")
            sb.AppendHeader2(GCStrings.getString(17))
            sb.AppendLine("")
            sb.AppendLine("\\tab {} : {{\\b {}...  }}".format(
                GCStrings.getString(18),
                GCStrings.GetNaksatraChildSylable(
                    d.nNaksatra, int(d.nNaksatraElapse / 25.0))))
            sb.AppendLine("\\tab {} : {{\\b {}...  }}".format(
                GCStrings.getString(19),
                GCStrings.GetRasiChildSylable(d.nMoonRasi)))

        sb.AppendLine("{{\\fs{} {} }}".format(GCLayoutData.textSizeH2,
                                              GCStrings.getString(24)))
        sb.AppendLine("")

        for o in range(TRESULT_APP_CELEBS):
            sb.AppendLine("\\tab Gaurabda {} : {{\\b {} }}".format(
                self.celeb_gy[o], self.celeb_date[o]))

        sb.AppendDocumentTail()

    def formatXml(self, stream):
        d = self.details
        vc = GCGregorianDate(date=self.eventTime)
        m_earth = self.m_location.GetEarthData()
        loc = self.m_location
        bDuringAdhika = False

        stream.write('''<xml>
    <request name="AppDay" version="{}">
        <arg name="longitude" value="{}" />
        <arg name="latitude" value="{}" />
        <arg name="timezone" value="{}" />
        <arg name="year" value="{}" />
        <arg name="month" value="{}" />
        <arg name="day" value="{}" />
        <arg name="hour" value="{}" />
        <arg name="minute" value="{}" />
    </request>'''.format(GCStrings.getString(130), loc.m_fLongitude,
                         loc.m_fLatitude, loc.m_fTimezone, self.eventTime.year,
                         self.eventTime.month, self.eventTime.day,
                         self.eventTime.GetHour(),
                         self.eventTime.GetMinuteRound()))

        npada = int(floor(d.nNaksatraElapse / 25.0)) + 1
        if (npada > 4): npada = 4
        is_adhika = "yes" if bDuringAdhika else "no"
        stream.write(
            "\t<result name=\"AppDay\" >\n\t\t<tithi name=\"{}\" elapse=\"%f\" />\n\t\t<naksatra name=\"{}\" elapse=\"%f\" pada=\"{}\"/>\n\t\t<paksa name=\"{}\" />\n\t\t<masa name=\"{}\" adhikamasa=\"{}\"/>\n\t\t<gaurabda value=\"{}\" />\n"
            .format(GCStrings.GetTithiName(d.nTithi), d.nTithiElapse,
                    GCStrings.GetNaksatraName(d.nNaksatra), d.nNaksatraElapse,
                    npada, GCStrings.GetPaksaName(d.nPaksa),
                    GCStrings.GetMasaName(d.nMasa), is_adhika,
                    d.nGaurabdaYear))

        stream.write("\t\t<celebrations>\n")
        for i in range(TRESULT_APP_CELEBS):
            stream.write(
                "\t\t\t<celebration gaurabda=\"{}\" day=\"{}\" month=\"{}\" monthabr=\"{}\" year=\"{}\" />\n"
                .format(
                    self.celeb_gy[i], self.celeb_date[i].day,
                    self.celeb_date[i].month,
                    GCStrings.GetMonthAbreviation(self.celeb_date[i].month),
                    self.celeb_date[i].year))

        stream.write("\t\t</celebrations>\n\t</result>\n</xml>\n")

    def writeHtml(self, stream):
        d = self.details
        vc = GCGregorianDate(date=self.eventTime)
        m_earth = self.m_location.GetEarthData()

        stream.write("<html><head><title>Appearance day</title>")
        stream.write(
            "<style>\n<!--\nbody {\n  font-family:Verdana;\n  font-size:11pt;\n}\n\ntd.hed {\n  font-size:11pt;\n  font-weight:bold;\n"
        )
        stream.write(
            "  background:#aaaaaa;\n  color:white;\n  text-align:center;\n  vertical-align:center;\n  padding-left:15pt;\n  padding-right:15pt;\n"
        )
        stream.write(
            "  padding-top:5pt;\n  padding-bottom:5pt;\n}\n-->\n</style>\n")
        stream.write("</head>\n\n<body>\n")
        stream.write("<h2 align=center>Appearance day Calculation</h2>")
        stream.write("<table align=center><tr><td valign=top>\n\n")
        stream.write("<table align=center>")
        stream.write("<tr><td colspan=3 class=hed>Details</td></tr>\n")
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(7), vc))
        stream.write(
            "<tr><td colspan=2>{}</td><td> {}:{:02d}</td></tr>\n\n".format(
                GCStrings.getString(8), vc.GetHour(), vc.GetMinuteRound()))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(9), self.m_location.m_strName))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(10),
            GCEarthData.GetTextLatitude(self.m_location.m_fLatitude)))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(11),
            GCEarthData.GetTextLongitude(self.m_location.m_fLongitude)))
        stream.write("<tr><td colspan=2>{}</td><td> ".format(
            GCStrings.getString(12)))
        stream.write(
            GCTimeZone.GetTimeZoneOffsetText(self.m_location.m_fTimezone))
        stream.write("</td></tr>\n")
        stream.write("<tr><td colspan=2>DST</td><td>N/A</td></tr>\n")
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(13), GCStrings.GetTithiName(d.nTithi)))
        stream.write(
            "<tr><td colspan=2>{}</td><td> {:.2f} %</td></tr>\n".format(
                GCStrings.getString(14), d.nTithiElapse))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(15), GCStrings.GetNaksatraName(d.nNaksatra)))
        stream.write(
            "<tr><td colspan=2>{}</td><td> {:.2f} %</td></tr>\n".format(
                GCStrings.getString(16), d.nNaksatraElapse))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
            GCStrings.getString(20), GCStrings.GetPaksaName(d.nPaksa)))
        if (self.b_adhika == True):
            stream.write(
                "<tr><td colspan=2>{}</td><td> {} {}</td></tr>\n".format(
                    GCStrings.getString(22), GCStrings.GetMasaName(d.nMasa),
                    GCStrings.getString(21)))
        else:
            stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n".format(
                GCStrings.getString(22), GCStrings.GetMasaName(d.nMasa)))
        stream.write("<tr><td colspan=2>{}</td><td> {}</td></tr>\n\n".format(
            GCStrings.getString(23), d.nGaurabdaYear))

        stream.write("</table></td><td valign=top><table>")
        stream.write("<tr><td colspan=3 class=hed>{}</td></tr>\n".format(
            GCStrings.getString(24)))

        for o in range(TRESULT_APP_CELEBS):
            stream.write(
                "<tr><td>Gaurabda {}</td><td>&nbsp;&nbsp;:&nbsp;&nbsp;</td><td><b>{}</b></td></tr>"
                .format(self.celeb_gy[o], self.celeb_date[o]))
        stream.write("</table>")
        stream.write("</td></tr></table>\n\n")
        stream.write(
            "<hr align=center width=\"50%\">\n<p style=\'text-align:center;font-size:8pt\'>Generated by {}</p>"
            .format(GCStrings.getString(130)))
        stream.write("</body></html>")

    def write(self, stream, format='html', layout='list'):
        if format == 'plain':
            self.formatPlainText(stream)
        elif format == 'rtf':
            self.formatRtf(stream)
        elif format == 'xml':
            self.formatXml(stream)
        elif format == 'html':
            self.writeHtml(stream)
示例#12
0
class TCoreEvents:
    header_text = {
        CCTYPE_DATE: " DATE ",
        CCTYPE_S_ARUN: " SUNRISE, SUNSET ",
        CCTYPE_S_RISE: " SUNRISE, SUNSET ",
        CCTYPE_S_NOON: " SUNRISE, SUNSET ",
        CCTYPE_S_SET: " SUNRISE, SUNSET ",
        CCTYPE_TITHI: " TITHI ",
        CCTYPE_NAKS: " NAKSATRA ",
        CCTYPE_SANK: " SANKRANTI ",
        CCTYPE_CONJ: " SUN-MOON CONJUNCTION ",
        CCTYPE_YOGA: " YOGA ",
        CCTYPE_KALA_START: " KALAS ",
        CCTYPE_KALA_END: " KALAS ",
        CCTYPE_M_RISE: " MOONRISE, MOONSET ",
        CCTYPE_M_SET: " MOONRISE, MOONSET ",
        CCTYPE_M_RASI: " MOON RASI ",
        CCTYPE_ASCENDENT: " ASCENDENT "
    }

    def __init__(self):
        self.m_vcStart = GCGregorianDate()
        self.m_vcEnd = GCGregorianDate()
        self.m_options = 0
        self.m_location = GCLocation()
        self.p_events = []
        self.b_sorted = True

    def AddEvent(self, inTime, inType, inData, inDst):
        p = TDayEvent()
        self.p_events.append(p)

        if inDst == 1:
            if (inTime.shour >= 2 / 24.0):
                inTime.shour += 1 / 24.0
                inTime.NormalizeValues()
                p.nDst = 1
        elif inDst == 2:
            inTime.shour += 1 / 24.0
            inTime.NormalizeValues()
            p.nDst = 1
        elif inDst == 3:
            if (inTime.shour <= 2 / 24.0):
                inTime.shour += 1 / 24.0
                inTime.NormalizeValues()
                p.nDst = 1
        p.Time.Set(inTime)
        p.Time.InitWeekDay()
        p.julianDay = p.Time.GetJulianComplete()
        p.nData = inData
        p.nType = inType
        return True

    def Sort(self):
        self.p_events = sorted(self.p_events, key=lambda k: k.julianDay)

    def CalculateEvents(self, loc, vcStart, vcEnd):
        sun = SUNDATA()
        ndst = 0

        self.m_location.Set(loc)
        self.m_vcStart.Set(vcStart)
        self.m_vcEnd.Set(vcEnd)

        vcNext = GCGregorianDate()
        earth = loc.GetEarthData()

        vc = GCGregorianDate(date=vcStart)
        vcAdd = GCGregorianDate(date=vcStart)
        vcAdd.InitWeekDay()

        previousLongitude = -100
        todayLongitude = 0
        fromTimeLimit = 0

        while vcAdd.IsBeforeThis(vcEnd):
            if (GCDisplaySettings.getValue(COREEVENTS_SUN)):
                ndst = GCTimeZone.determineDaylightChange(
                    vcAdd, loc.m_nTimezoneId)
                sun.SunCalc(vcAdd, earth)

                vcAdd.shour = sun.arunodaya.GetDayTime()
                self.AddEvent(vcAdd, CCTYPE_S_ARUN, 0, ndst)

                vcAdd.shour = sunRise = sun.rise.GetDayTime()
                self.AddEvent(vcAdd, CCTYPE_S_RISE, 0, ndst)

                vcAdd.shour = sun.noon.GetDayTime()
                self.AddEvent(vcAdd, CCTYPE_S_NOON, 0, ndst)

                vcAdd.shour = sunSet = sun.set.GetDayTime()
                self.AddEvent(vcAdd, CCTYPE_S_SET, 0, ndst)
            else:
                ndst = GCTimeZone.determineDaylightChange(
                    vcAdd, loc.m_nTimezoneId)
                sun.SunCalc(vcAdd, earth)
                sunRise = sun.rise.GetDayTime()
                sunSet = sun.set.GetDayTime()

            if (GCDisplaySettings.getValue(COREEVENTS_ASCENDENT)):
                todayLongitude = sun.longitude_deg
                vcAdd.shour = sunRise
                todaySunriseHour = sunRise
                if (previousLongitude < -10):
                    prevSunrise = GCGregorianDate(date=vcAdd)
                    prevSunrise.PreviousDay()
                    sun.SunCalc(prevSunrise, earth)
                    previousSunriseHour = sun.rise.GetDayTime() - 1
                    previousLongitude = sun.longitude_deg
                    fromTimeLimit = 0

                jd = vcAdd.GetJulianComplete()
                ayan = GCAyanamsha.GetAyanamsa(jd)
                r1 = GCMath.putIn360(previousLongitude - ayan) / 30
                r2 = GCMath.putIn360(todayLongitude - ayan) / 30

                while (r2 > r1 + 13):
                    r2 -= 12.0
                while (r2 < r1 + 11):
                    r2 += 12.0

                a = (r2 - r1) / (todaySunriseHour - previousSunriseHour)
                b = r2 - a * todaySunriseHour

                tr = ceil(r1)
                for tr in range(ceil(r1), ceil(r2)):
                    tm = (tr - b) / a
                    if (tm > fromTimeLimit):
                        vcNext.Set(vcAdd)
                        vcNext.shour = tm
                        vcNext.NormalizeValues()
                        self.AddEvent(vcNext, CCTYPE_ASCENDENT, tr, ndst)

                previousLongitude = todayLongitude
                previousSunriseHour = todaySunriseHour - 1
                fromTimeLimit = previousSunriseHour

            if (GCDisplaySettings.getValue(COREEVENTS_RAHUKALAM)):
                r1, r2 = CalculateKala(sunRise, sunSet, vcAdd.dayOfWeek,
                                       KT_RAHU_KALAM)
                vcAdd.shour = r1
                self.AddEvent(vcAdd, CCTYPE_KALA_START, KT_RAHU_KALAM, ndst)
                vcAdd.shour = r2
                self.AddEvent(vcAdd, CCTYPE_KALA_END, KT_RAHU_KALAM, ndst)

            if (GCDisplaySettings.getValue(COREEVENTS_YAMAGHANTI)):
                r1, r2 = CalculateKala(sunRise, sunSet, vcAdd.dayOfWeek,
                                       KT_YAMA_GHANTI)
                vcAdd.shour = r1
                self.AddEvent(vcAdd, CCTYPE_KALA_START, KT_YAMA_GHANTI, ndst)
                vcAdd.shour = r2
                self.AddEvent(vcAdd, CCTYPE_KALA_END, KT_YAMA_GHANTI, ndst)

            if (GCDisplaySettings.getValue(COREEVENTS_GULIKALAM)):
                r1, r2 = CalculateKala(sunRise, sunSet, vcAdd.dayOfWeek,
                                       KT_GULI_KALAM)
                vcAdd.shour = r1
                self.AddEvent(vcAdd, CCTYPE_KALA_START, KT_GULI_KALAM, ndst)
                vcAdd.shour = r2
                self.AddEvent(vcAdd, CCTYPE_KALA_END, KT_GULI_KALAM, ndst)

            if (GCDisplaySettings.getValue(COREEVENTS_ABHIJIT_MUHURTA)):
                r1, r2 = CalculateKala(sunRise, sunSet, vcAdd.dayOfWeek,
                                       KT_ABHIJIT)
                if (r1 > 0 and r2 > 0):
                    vcAdd.shour = r1
                    self.AddEvent(vcAdd, CCTYPE_KALA_START, KT_ABHIJIT, ndst)
                    vcAdd.shour = r2
                    self.AddEvent(vcAdd, CCTYPE_KALA_END, KT_ABHIJIT, ndst)

            vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_TITHI)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                nData = GCTithi.GetNextTithiStart(earth, vcAdd, vcNext)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(vcNext, CCTYPE_TITHI, nData, ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.shour += 0.2
                if (vcAdd.shour >= 1.0):
                    vcAdd.shour -= 1.0
                    vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_NAKSATRA)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                nData = GCNaksatra.GetNextNaksatra(earth, vcAdd, vcNext)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(vcNext, CCTYPE_NAKS, nData, ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.shour += 0.2
                if (vcAdd.shour >= 1.0):
                    vcAdd.shour -= 1.0
                    vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_YOGA)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                nData = GCYoga.GetNextYogaStart(earth, vcAdd, vcNext)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(vcNext, CCTYPE_YOGA, nData, ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.shour += 0.2
                if (vcAdd.shour >= 1.0):
                    vcAdd.shour -= 1.0
                    vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_SANKRANTI)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                date, nData = GCSankranti.GetNextSankranti(vcAdd)
                vcNext.Set(date)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(vcNext, CCTYPE_SANK, nData, ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_MOONRASI)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                nData = GetNextMoonRasi(earth, vcAdd, vcNext)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(vcNext, CCTYPE_M_RASI, nData, ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.shour += 0.5
                vcAdd.NormalizeValues()

        if (GCDisplaySettings.getValue(COREEVENTS_CONJUNCTION)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                dlong = GCConjunction.GetNextConjunctionEx(
                    vcAdd, vcNext, True, earth)
                if (vcNext.GetDayInteger() < vcEnd.GetDayInteger()):
                    vcNext.InitWeekDay()
                    ndst = GCTimeZone.determineDaylightChange(
                        vcNext, loc.m_nTimezoneId)
                    self.AddEvent(
                        vcNext, CCTYPE_CONJ,
                        GCRasi.GetRasi(
                            dlong,
                            GCAyanamsha.GetAyanamsa(
                                vcNext.GetJulianComplete())), ndst)
                else:
                    break
                vcAdd.Set(vcNext)
                vcAdd.NextDay()

        if (GCDisplaySettings.getValue(COREEVENTS_MOON)):
            vcAdd.Set(vc)
            vcAdd.shour = 0.0
            while vcAdd.IsBeforeThis(vcEnd):
                vcNext.Set(MOONDATA.GetNextRise(earth, vcAdd, True))
                self.AddEvent(vcNext, CCTYPE_M_RISE, 0, ndst)

                vcNext.Set(MOONDATA.GetNextRise(earth, vcNext, False))
                self.AddEvent(vcNext, CCTYPE_M_SET, 0, ndst)

                vcNext.shour += 0.05
                vcNext.NormalizeValues()
                vcAdd.Set(vcNext)

        if self.b_sorted:
            self.Sort()

    def formatText(self, stream):
        sb = GCStringBuilder(stream)
        sb.Format = SBTF_TEXT

        stream.write("Events from {} to {}.\r\n\r\n".format(
            self.m_vcStart, self.m_vcEnd))
        stream.write("{}\r\n\r\n".format(self.m_location.m_strFullName))

        prevd = GCGregorianDate()
        prevd.day = 0
        prevd.month = 0
        prevd.year = 0
        prevt = -1

        last_header = ''
        for dnr in self.p_events:
            new_header = ''
            if self.b_sorted:
                new_header = " {} - {} ".format(
                    dnr.Time, GCStrings.GetDayOfWeek(dnr.Time.dayOfWeek))
            else:
                new_header = header_text[dnr.nType]
            if last_header != new_header:
                sb.AppendLine()
                sb.AppendHeader3(new_header)
                sb.AppendLine()
                last_header = new_header

            stream.write("            {} {}    {}".format(
                dnr.Time.time_str(), GCStrings.GetDSTSignature(dnr.nDst),
                dnr.EventText()))
            sb.AppendLine()

        sb.AppendLine()
        sb.AppendNote()
        return 1

    def formatXml(self, strXml):
        strXml.write(
            "<xml>\r\n<program version=\"{}\">\r\n<location longitude=\"{}\" latitude=\"{}\" timezone=\"{}\" dst=\"{}\" />\n"
            .format(GCStrings.getString(130), self.m_location.m_fLongitude,
                    self.m_location.m_fLatitude, self.m_location.m_fTimezone,
                    GCTimeZone.GetTimeZoneName(self.m_location.m_nTimezoneId)))

        for dnr in self.p_events:
            strXml.write(
                "  <event type=\"{}\" date=\"{}\" time=\"{}\" dst=\"{}\" />\n".
                format(dnr.EventText(), str(dnr.Time), dnr.Time.time_str(),
                       dnr.nDst))

        strXml.write("</xml>\n")
        return 1

    def formatRtf(self, stream):
        sb = GCStringBuilder(stream)
        sb.Format = SBTF_RTF
        sb.fontSizeH1 = GCLayoutData.textSizeH1
        sb.fontSizeH2 = GCLayoutData.textSizeH2
        sb.fontSizeText = GCLayoutData.textSizeText
        sb.fontSizeNote = GCLayoutData.textSizeNote

        sb.AppendDocumentHeader()

        sb.AppendHeader1("Events")

        stream.write("\\par from {} to {}.\\par\r\n\\par\r\n".format(
            self.m_vcStart, self.m_vcEnd))
        stream.write("{}\\par\r\n\\par\r\n".format(
            self.m_location.m_strFullName))

        prevd = GCGregorianDate()
        prevd.day = 0
        prevd.month = 0
        prevd.year = 0
        prevt = -1

        last_header = ''
        for dnr in self.p_events:
            new_header = ''
            if self.b_sorted:
                new_header = " {} - {} ".format(
                    dnr.Time, GCStrings.GetDayOfWeek(dnr.Time.dayOfWeek))
            else:
                new_header = header_text[dnr.nType]
            if last_header != new_header:
                sb.AppendLine()
                sb.AppendHeader2(new_header)
                sb.AppendLine()
                last_header = new_header

            stream.write("\\par            {} {}    {}".format(
                dnr.Time.time_str(), GCStrings.GetDSTSignature(dnr.nDst),
                dnr.EventText()))

        sb.AppendLine()
        sb.AppendNote()
        sb.AppendDocumentTail()
        return 1

    def writeHtml(self, stream):
        stream.write("<html>\n<head>\n<title>Core Events</title>\n\n")
        stream.write(
            "<style>\n<!--\nbody {\n  font-family:Verdana;\n  font-size:11pt;\n}\n\ntd.hed {\n  font-size:11pt;\n  font-weight:bold;\n"
        )
        stream.write(
            "  background:#aaaaaa;\n  color:white;\n  text-align:center;\n  vertical-align:center;\n  padding-left:15pt;\n  padding-right:15pt;\n"
        )
        stream.write(
            "  padding-top:5pt;\n  padding-bottom:5pt;\n}\n-->\n</style>\n")
        stream.write("</head>\n")
        stream.write("<body>\n\n")
        stream.write(
            "<h1 align=center>Events</h1>\n<p align=center>From {} to {}.</p>\n\n"
            .format(self.m_vcStart, self.m_vcEnd))

        stream.write("<p align=center>{}</p>\n".format(
            self.m_location.m_strFullName))

        prevd = GCGregorianDate()
        prevd.day = 0
        prevd.month = 0
        prevd.year = 0
        prevt = -1

        stream.write("<table align=center><tr>\n")
        last_header = ''
        new_header = ''
        for dnr in self.p_events:
            if self.b_sorted:
                new_header = " {} - {} ".format(
                    dnr.Time, GCStrings.GetDayOfWeek(dnr.Time.dayOfWeek))
            else:
                new_header = self.header_text[dnr.nType]
            if last_header != new_header:
                stream.write(
                    f"<td class=\"hed\" colspan=2>{new_header}</td></tr>\n<tr>\n"
                )
                last_header = new_header

            stream.write("<td>{}</td><td>{}</td></tr><tr>\n".format(
                dnr.EventText(), dnr.Time.time_str()))

        stream.write("</tr></table>\n")
        stream.write(
            "<hr align=center width=\"50%%\">\n<p align=center>Generated by {}</p>"
            .format(GCStrings.getString(130)))
        stream.write("</body>\n</html>\n")
        return 1

    def write(self, stream, format='html', layout='list'):
        if format == 'plain':
            self.formatText(stream)
        elif format == 'rtf':
            self.formatRtf(stream)
        elif format == 'xml':
            self.formatXml(stream)
        elif format == 'html':
            self.writeHtml(stream)