Did you know that by the time we reach our fifties, there's a chance that everything is not so clear and we need more light for our eyes? Recent research suggests that we need three times more light for reading by our sixties and even suggests that neglecting your eyes with the wrong lighting conditions could cause damage to the eye.
After speaking with the design team for Serious Readers about why their lights are so special (It's an interesting read by the way) I was eager to try one of their super duper lights.
Here I am above reading one of my new books and you can see how much light is being portrayed through that little bulb. Let me explain the difference.
Why choose a Serious Readers light for your eyes?
There are three different high definition lights available from Serious Readers. I've chosen the Alex and I will explain why. But the others may interest you more.
Serious Readers most powerful light – As close to natural light as is technically possible. Recommended if you suffer from Macular Degeneration and other eye conditions.
The latest Alex, eco-friendly LED technology delivers superb colour rending and detailed recognition. Projects a brighter wider beam than the classic light.
The original Serious Readers light is now being built in the format. The narrow beam is ideal for personal nighttime reading.
When my light arrived, I was impressed with the sturdy packaging and that the light came all in one piece. Nothing to put together was a bonus point! I've chosen my light in the Black and Nickel finish. It's the tall version rather than tabletop versions that are available.
I decided on the tall version, it's not that heavy that I can't move it around the house and I have a specific spot in mind for this sleek designed light as I get further into my home renovation.
I also liked the idea of a dimmable light. Dee hates bright light in the living room when watching TV (tut, tut, not good for you) So I will be able to sit in my armchair and read from now on without the light intruding other space. It's such a bright light and obviously, I needed to bend it as pictured above.
It actually works great as an up lighter too! The movability of the light is simple to adjust exactly where I want the light and it's a simple one switch that controls the on-off and dimmer.
Here's the table top version that's available. The lights come in three different colours White, Black and Grey with different finishes of Black, Nikel, or Brass.
I wanted to share this picture so that you can see the base of the light. It's not overpowering at all yet the base is sturdy. One thing I wish I had shared with you is me painting my nails the other night. It was a godsend for that!
My eyesight is slowly getting worse and it won't be long before I need glasses full time I think. Both of my brothers have been diagnosed with Glaucoma the past two years and I have to have regular checks for that. So this light is good for me, and the more I look after my eyesight the better!
You can read more about the Serious Readers lights here and purchase directly from them. It's an interesting read like I said. Getting older, we need to look after our eyes.
Thank you to Serious Readers for this great light – This is a sponsored post but all thought are my own and I love it!
Next Post Smart Buy Sunglasses – Just Add Sun!
These look like great light Laurie. Great for when your reading at night.
I have a Serious Reader in the sitting room where I like to read, and I wouldn't be without it! My eyes are definitely better with the focused light.
I just bought my first pair of readers. If I actually remember to use them and carry them around, I will probably invest in a nicer pair. Funny how once I hit my forties, small print has become my enemy!
We have daylight natural light (LED) bulbs in all our light fittings and lamps and they make. I have a difference, you can buy the bulbs in any diy store!
Put them in your bedside lamps ?


text:
New York City Asks for Ideas With Internal Crowdsourcing Effort
Mathew Ingram Jan 19, 2011 - 10:20 AM CST
Work Communications
New York City has launched an ambitious internal "crowdsourcing" project, aimed at getting ideas from city employees to help the giant metropolis function more efficiently. The program, called Simplicity, is being powered by Spigit, which makes a Software-as-a-Service platform that companies and governments can use to crowdsource ideas. New York mayor Michael Bloomberg announced the plan during his annual "State of The City" address on Wednesday afternoon, and the company said that it will initially be rolled out to 15,000 city workers before being extended to the city's entire workforce of more than 300,000.
Spigit provides a software platform that allows a company or government to set up an idea-submission site relatively quickly, and incorporates reward-based incentives, idea voting and trading, as well as providing analytics that can help anyone using the software to track submissions and those who provide them. A number of companies, including AT&T (s t) and Southwest Airlines (s luv), have used its software to get ideas from their employees. Other companies such as Dell (s dell) — which was one of the first to launch a crowdsourcing effort called IdeaStorm in 2007 — and Starbucks (s sbux), which launched a similar effort not long afterwards, have used the Salesforce.com (s crm) platform to get ideas from both inside and outside the company, while Jive Software and BrightIdea also offer similar platforms.
Spigit said that the Simplicity platform has been in beta testing with a small group of NYC employees, and some of the ideas that have been suggested include:
A central research and development unit that can help NYC agencies find more information about new programs and initiatives.
A web-based portal that would allow city agencies to bid on items that have been "relinquished" or made redundant by other city agencies.
A "just in time" inventory-management system that would prevent the over-stocking of supplies.
A way to identify internal experts who could train other employees at their desks in computer hardware and software, rather than sending employees for training.
A web-based help desk for employees, so that they could contact someone in another department about a particular topic within their expertise.
Whether the Spigit-powered program will actually help New York become more efficient remains to be seen. It could become just another dumping ground for ideas that never see the light of day — something collaboration experts call the "suggestion box problem." But at least the city government is trying to use social tools to improve the way it functions, which is an encouraging sign.
Related GigaOM Pro content (sub req'd):
Why Google Should Fear the Social Web
Lessons From Twitter: How to Play Nice With Ecosystem Partners
What We Can Learn From the Guardian's Open Platform
Post and thumbnail courtesy of Flickr user Celine
Spigit
One Response to "New York City Asks for Ideas With Internal Crowdsourcing Effort"
janelle January 19, 2011
Thanks for the mention of Brightidea. The government initiatives that have utilized Brightidea software include the City of San Francisco's ImproveSF campaign (2 implemented ideas to save the city hundreds of thousands) as well as Your Country Your Call out of Ireland which is already implementing top ideas. Currently the Dept. of State utilizes Brightidea's Innovation Suite to not only collect and power the 'Sounding Board' platform, but ensure ideas are followed through on and don't end up in the 'black hole' suggestion box. Having an end-to-end solution like Brightidea means that governments and companies alike not only have a way to collect and foster collaboration around ideas, but a way to manage and execute on them in real-time. See http://www.brightidea.com/products.bix
Voices in AI – Episode 90: A Conversation with Norman Sadeh
Byron Reese Jun 27, 2019 - 7:00 AM CDT
The Future of Software Innovation? Hardware-Enabled AI & ML Innovation
Greg Fisher Apr 1, 2019 - 10:12 AM CDT
Five questions for… Keri Gilder, Chief Commercial Officer, Colt Technology Services. Can Connectivity be linked to Customer Experience?
Jon Collins Mar 4, 2019 - 3:54 AM CST
Research Byte
Innovation without Compromise
How Industrial And Embedded Systems Providers Can Deliver Quality, Innovative Software
Across The Seams, Down To The Platform
Stowe Boyd Dec 4, 2019 - 12:00 PM CST
CIO Speaks – Episode 10: A Conversation with David Chou of Constellation Research
Steve Ginsberg

redpajama_set_name: RedPajamaCommonCrawl


text:
Seaton family desperate for donations to fund life-changing trike
Published: 10:50 AM November 25, 2020 Updated: 4:18 PM December 14, 2020
Jaydi trying out an adapted trike. Picture: Lisa Hawker. - Credit: Archant
A little girl from Seaton is short of funds to pay for an adapted trike which will allow her to experience independence and freedom.
Seven-year-old Jaydi Rose Hawker, whose body size resembles that of a four-year-old's, has ligase IV microcephalic primordial dwarfism - a condition which affects her growth. Jaydi is around 3ft and is not expected to grow much taller.
Despite her petite size, Jaydi, who is sight impaired, has hearing issues and hip dysplasia, is determined not to resort to sitting in a buggy and dreams of a comfortable, secure specialised trike to call her own.
Jaydi, who has 'a real zest for life', is unable to ride an average trike as she does not have the balance to stay on. Jaydi's mum, Lisa, explained that they owned a plastic toddler's bike, which her daughter loved, but couldn't ride it without mum holding on to her constantly which was dangerous.
Lisa said when the pair see other children riding around on bikes and scooters, Jaydi often looks at them and wishes she could do the same. Lisa said: "There's a walkway near our house, through wetlands and she loves it down there. She sees other children on bikes and has started to show an interest in what they're doing. She looks at them like 'ah, that looks fun!' and 'why can't I do that too?'
"I think the trike will give her some more independence and to get to have those experiences which other children may take for granted."
The children's charity Children Today recently awarded the family a £1,000 grant to go towards the cost of the equipment. But the family still need a further £491 to fully fund Jaydi's life-changing trike.
The equipment will not only mean Jaydi can relax and enjoy herself but Lisa will also be reassured that her little girl is safe and enjoying her trike, hazard-free.
Jaydi, who Lisa describes as 'happy, very mischievous and carefree' had the opportunity to try out the adapted trike, which fits her measurements, when the supplier Hickleys Healthcare paid a visit to their Devon home.
Lisa added: "Jaydi's occupational therapist put me in contact with the supplier who came out during the end of the first lockdown and she had a go sitting on the trike outside. They showed us how it works and which one would be most suitable for Jaydi.
"She had her feet on the pedals and a big grin on her face. She sat on it like Lady Muck!"
The youngster is tube fed, has glaucoma, cataracts and craniosynostosis - a rare condition which means her skull didn't grow properly when she was a baby. Despite this, Jaydi, who has also undergone a bone marrow transplant, is full of energy and according to mum, can go 'full pelt for 17 hours a day'.
Her hip dysplasia means Jaydi runs instead of walking and due to her limited eyesight, she is prone to falling into things. Lisa said: "She's so active - so the trike will help get rid of some of that physical energy and will hopefully build up the muscles in her legs too, which will be amazing.
Emma Prescott, Charity Director of Children Today Charitable Trust, said: "The specialised equipment we help fund for children like Jaydi can have a huge impact on not just the child's life but their loved ones too.
"For little Jaydi, an adapted trike to call her own will open up a world of opportunities and allow her to experience pure joy with a piece of equipment that will most likely last her for life.
"We've set up an online donation page to fund the remaining amount for Jaydi's life enhancing trike. Any funds raised over and above what we need to provide this equipment will go towards helping fund vitally important equipment for other vulnerable children."
To make a donation to help fund Jaydi's much-needed adapted trike visit: www.childrentoday.org.uk/help-jaydi/.


text:
Contributed photo South Surrey-based band The Escapes will play an 'End of Summer' bash at Ocean Park Hall Saturday.
The Escapes cap summer with hometown show
South Surrey-based band blends pop, jazz and funk influences
Alex Browne
The fresh jazz-funk-soul-meets-pop sound of South Surrey's The Escapes has already won the young group a developmental deal with Vancouver's 604 Records.
That's not too shabby for a group that – as bassist Keely Rammage-Scott explains – is largely made up of 19- and 20-year-olds only just going into their second year of university studies.
It's keeping them hard at work on their music, with gigs at least once a month – even more during the summer – at such preferred Vancouver venues as The Railway Club and The Biltmore, she said.
But they always love playing to hometown fans, which is why they're particularly looking forward to this Saturday's 'End of the Summer Bash' (Aug. 25, 7:30 p.m.) at Ocean Park Hall, 1577 128 St.
"The hall has always worked really well for us," Rammage-Scott said.
Another reason to look forward to the Flamingo Events Centre-organized, 19-plus show is that it will reunite them with Vancouver's R&B and Motown-based Derek Pitts and the Bullets.
"We're basically splitting the bill equally," Rammage-Scott said.
"We got placed in a lineup with Derek and his band a year-and-a-half ago and he asked us to join him on a show a couple of months later. We thought 'who better to invite to join us on this show?' It's a great vibe, the two bands together."
Formed close to three years ago, The Escapes brings together the pop-based sensibilities of Rammage-Scott and lead vocalist and guitarist Isobel Ralph, and the jazz background of brothers Max (lead guitar, vocals) and Rhett (drums) Cunningham, and Jack Wells (keyboards).
Teamed by musician, teacher and producer Jesse Burch (who turned Rammage-Scott from a guitarist to a bassist in the process), the members clicked musically and creatively around a mix of influences, including contemporary bands Hiatus Kaiyote and Vulfpeck, as well as old-school masters like Stevie Wonder and Prince.
Rammage-Scott calculated that it's "a 50-50 blend of lyrical and instrumental content" in which Ralph writes many of the lyrics, but everyone contributes to the musical development of each song.
"It's a real collaborative process for us," said Rammage-Scott, who said it gets them past the challenges of being at different schools (she and Max Cunningham are at SFU, Ralph is at UBC, Rhett Cunningham is finishing Grade 12 at Southridge School and Wells is Western University in Ontario, but comes back for gigs in the summer).
"Luckily, most of us still live at home in the White Rock-South Surrey area," she said.
Tickets are $15. For more information, visit www.theflamingo.ca
REVIEW: More panic than laughter in Rumors
Jane Goodall to appear at Vancouver International Film Festival


text:
Notices tagged with libreplanet2020
Free Software Foundation (fsf)'s status on Wednesday, 13-May-2020 20:43:00 UTC Free Software Foundation
Looking for some audio entertainment to get you through a slow afternoon, or to accompany you on a walk through the park? #LibrePlanet2020 sessions are now available as audio files! https://u.fsf.org/328 https://status.fsf.org/attachment/2144712
Wednesday, 13-May-2020 20:43:00 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Monday, 11-May-2020 16:47:33 UTC Free Software Foundation
Monday, 11-May-2020 16:47:33 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Thursday, 07-May-2020 16:57:57 UTC Free Software Foundation
Videos from #LibrePlanet2020 are live! https://u.fsf.org/31p Learn about "The importance of free software games" with Lori Nagel @Jastiv, and learn how to bring free software activism into your gaming! https://u.fsf.org/322
Thursday, 07-May-2020 16:57:57 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Tuesday, 05-May-2020 15:27:29 UTC Free Software Foundation
The #LibrePlanet2020 raffle has gone virtual: refer new members to the FSF before 5/31, and win amazing prizes from Technoethical, Vikings, JMP.chat, No Starch Press, ThinkPenguin, and the #GNU Press shop! https://u.fsf.org/31z https://status.fsf.org/attachment/2124267
Tuesday, 05-May-2020 15:27:29 UTC from status.fsf.org permalink
Have you heard about our new member drive and virtual raffle? Refer your friends to join the FSF and win fabulous prizes that were donated for the #LibrePlanet2020 raffle! A laptop, routers, gift certificates, T-shirts, stickers, and more: https://u.fsf.org/31z
Free Software Foundation (fsf)'s status on Friday, 01-May-2020 17:34:46 UTC Free Software Foundation
The #LibrePlanet2020 raffle has gone virtual: refer new members to the FSF before 5/31, and win amazing prizes from Technoethical, Vikings, JMP.chat, No Starch Press, ThinkPenguin, and the #GNU Press shop! https://u.fsf.org/31z
Friday, 01-May-2020 17:34:46 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Thursday, 30-Apr-2020 19:37:22 UTC Free Software Foundation
Thursday, 30-Apr-2020 19:37:22 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Wednesday, 29-Apr-2020 17:08:17 UTC Free Software Foundation
In case you missed it: the best possible thing to watch while you're stuck inside! Watch many, many hours of entertaining and educational talks from #LibrePlanet2020 on our Mediagoblin page -- made and shared entirely with free software: https://u.fsf.org/31p
Wednesday, 29-Apr-2020 17:08:17 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Monday, 27-Apr-2020 14:19:26 UTC Free Software Foundation
Read and watch: technology journalist Lucy Ingham posted a full transcript of her #LibrePlanet2020 talk, "Rented future – the dangerous rise of life as a service": https://u.fsf.org/31q
Monday, 27-Apr-2020 14:19:26 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Friday, 24-Apr-2020 14:25:43 UTC Free Software Foundation
Friday, 24-Apr-2020 14:25:43 UTC from status.fsf.org permalink
#LibrePlanet2020 videos are here!!!! Catch up on the sessions you missed on our Mediagoblin page, and share these entertaining and educational videos with everyone you know: https://u.fsf.org/31p
Our tech team is hard at work putting the videos from #LibrePlanet2020 online. In the meantime, we encourage you to enjoy the collection of past LibrePlanet talks at https://media.libreplanet.org/ !
Free Software Foundation (fsf)'s status on Tuesday, 14-Apr-2020 18:36:49 UTC Free Software Foundation
Another opportunity for the global free software community to come together online: ÖzgürKon, on May 16-17, organized by Turkish activists who spoke at #LibrePlanet2020! https://ozgurkon.org/
Tuesday, 14-Apr-2020 18:36:49 UTC from status.fsf.org permalink
April has brought some exciting changes to #Jitsi, the software that powered this year's #LibrePlanet2020 conference. Read the Jitsi team's latest round of updates, and the FSF's post on free communication tools here: https://u.fsf.org/317 https://u.fsf.org/311
Since #LibrePlanet2020 was online-only, our raffle prizes, donated by @Technoethical, Vikings, JMP, No Starch Press, and ThinkPenguin, will be given away at a later date (announcement coming soon!). Many thanks for these generous donations!
Free Software Foundation (fsf)'s status on Monday, 30-Mar-2020 15:46:14 UTC Free Software Foundation
Thank you to @fossbytes for helping to spread the word about the need to allow GNU/Linux systems to run old games, from the #LibrePlanet2020 conference! Read more: https://u.fsf.org/30u
Monday, 30-Mar-2020 15:46:14 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Friday, 27-Mar-2020 14:51:13 UTC Free Software Foundation
#LibrePlanet2020 was a huge success despite our inability to hold our traditional in-person gathering. Take a look at the highlights here: https://u.fsf.org/30r https://status.fsf.org/attachment/1979275
Friday, 27-Mar-2020 14:51:13 UTC from status.fsf.org permalink
Free Software Foundation (fsf)'s status on Wednesday, 25-Mar-2020 14:25:36 UTC Free Software Foundation
Wednesday, 25-Mar-2020 14:25:36 UTC from status.fsf.org permalink


text:
Fashion students win the Euros
Two fashion undergraduates from Somerset College beat European style icons to win gold in EuroSkills held in Rotterdam last week.
Hilary Wells and Victoria Griffiths, who both study BA (Hons) Fashion Textiles at the College, were the only competitors from the UK to win gold except the Social, Personal & Hospitality Services group.
The undergraduates were the only UK fashion team to be entered in the event and pitched their skills against countries including the Netherlands and the Czech Republic.
Victoria, from Abergavenny, said: 'It's amazing, it's just like winning the Olympics. EuroSkills was a tough competition in a highly pressurised environment. We didn't know the standard of the other competitors, but it was exciting to see how they were taught and worked differently. It was so much fun and well worth it in the end.'
EuroSkills took place in Rotterdam last week and the winners were announced on Saturday at a glitzy closing ceremony.
Before the competition Hilary and Victoria had to do a lot of research into the fabric and other materials and they had to research the brand for which the dress was to be made. During the competition, which took three days, they had to do two toiles (presentations of the garment), fit the dress to a mannequin, pattern cut and make alterations all in just two and a half days.
Hilary, from Bristol, said: 'We've been preparing for nine months for this competition. We have really increased our skill levels in various different areas which will be essential for working in industry.
'The competition opened our eyes to what would be needed in industry as we had to prepare everything to minute details. We had to present to the judges as they though they were industry buyers. It was a really nerve wracking but enjoyable competition.'
Gary Mills, the undergraduate's tutor at Somerset College, said: 'I am over the moon for the girls. They worked so hard against stiff competition to walk away with the Gold medal. We are all so proud of them.
'Skills in the industry are important in the delivery of our courses. We have highly talented undergraduates at Somerset College. The College has a strong reputation in national shows, including Clothes Show Live and Graduate Fashion Week. Even Jeff Banks quoted us as one of the top five fashion educators in the UK. Now we've proved we're world class.'
Somerset College offer BA (Hons) Fashion Textiles in partnership with the University of Plymouth. For more information contact enquiries@somerset.ac.uk, or call (01823) 366 331.
UK Skills is a not-for-profit organisation which champions skills and learning for work through competitions and awards. The organisation was established in 1990 with the primary purpose of raising skill levels in the UK through skills competitions and managing the UK team which competes in the WorldSkills Competition and the new EuroSkills competition. EuroSkills aims to create a new platform for the promotion of the skilled workforce, and skills and vocational education in Europe.


Flying Monkey Costume | Silly you. Monkeys can't fly! Wait, in Oz they can? That must be why this flying monkey costume has a set of wings.
The ability to fly multiplies the cool factor of anything by 10. Cars are pretty cool, but flying cars are totally awesome. Bicycles are sweet, but have you ever seen a flying bike? The same is true for monkeys. A regular monkey good, but a flying monkey is super rad. That's why the Wicked Witch has an army of them, because her primate army that couldn't fly was just kind of lame.


4/09/2012 · Researching Silhouette functions and features... glad to know I can use contact paper because like you, I'm quite frugal as well. You did an AMAZING job with the sign! I too I love signs and I love fonts. Pinning and scratching vinyl and transfer paper off my Silhouette order. Thanks so much! Going to check out more of your blog.... 7/08/2013 · 1. VINYL: Use contact paper instead of vinyl when you can get away with it. Making a sign? Cut your letters from black or colored contact paper - and then use clear contact paper (instead of "transfer paper" to transfer them onto the wood.
5 Stencil Ideas using Contact Paper and a Silhouette Filed Under: Crafts , DIY Projects , Silhouette 5 Tips for making stencils using Contact Paper and a Silhouette .... 24/05/2012 · I am so in love with vinyl. I know a lot of people are now using the Silhouette, but I still love my Cricut. I like being able to carry it around with me and not need a computer to use it.
Using a new material can be intimidating at first. No need to worry! Here are a few tips and tricks for using Silhouette heat transfer vinyl to help you have the best results each time.... In Silhouette Studio you will need to adjust the settings somewhat. Ensure your design is set to "Cut Edge" then pick "Printable Heat Transfer Material" from the material list in the Cut Settings window.
Heat transfer vinyl is a special type of vinyl that can be cut on the Silhouette machines which can then be transferred to fabric be it clothing, pillow covers, bags, etc.... SILHOUETTE HANDBOOK - The Silhouette Handbook is the complete guide to everything Silhouette. With over 300 pages, this digital reference is full of helpful information on Silhouette machines, materials, software, and more.
24/05/2012 · I am so in love with vinyl. I know a lot of people are now using the Silhouette, but I still love my Cricut. I like being able to carry it around with me and not need a computer to use it.
See more What others are saying "Prevent bleeding when using vinyl stencils on wood signs" "Make money with your Silhouette Cameo, Curio, Portrait, or Mint, or Cricut Explore Air or Maker"
Silhouette - 8.5inch x 11inch Image Transfer Paper 2 pack - Simply print designs onto this unique paper with a laserjet printer and use the Silhouette cutting machines Print & Cut feature to cut around the image contour.


text:
Q: Re-installing Windows on an old laptop I have an old laptop and I want to re-install Windows XP on it. The problem is that this laptop does not have an optical drive. I checked the boot sequence in the BIOS. It does not show an option to boot from USB. It have only two options:

*

*Boot from HD.

*Boot using Realtek agent (network boot).

I tried to copy the Windows CD to second drive D:\ and run the installed from there. However, I could not format the C:\ drive. Windows complaints about setup files will be removed or something like that.
I tried to boot the laptop using PXE, but I could not. It seems that the DHCP request did not get answered.
I thought I could use a USB CD-ROM drive (I don't have one to try), but it might not work as there is no option to boot from USB. Do you think it will work? Do I have other options to try? Any recommendations?

A: Sometimes the BIOS will only show a bootable option if that option is actually available. For instance, once you've connected a USB CD Drive you may then see the option to boot from it. However, this isn't common in older machines.

A: Most older laptops support booting from FDD or usb FDD
Microsoft has a floppy disk set to get you a windows environment to work from, I have done this. Be sure to use the SP2 disk set, and choose Home or Pro.
Set the bios to boot from usb FDD or FDD, with the usb floppy drive and a usb optical drive connected, boot to the FDD, you will have to load 6 floppies, once done you can run the setup.exe command and point to the usb optical drive letter that has the XP install disc, XP setup should start. If you have an internal floppy drive then you can use that instead of the usb floppy drive.

redpajama_set_name: RedPajamaStackExchange


text:
Home / Stock Picks / Stocks to Buy / 7 A-Rated Materials Stocks to Buy
7 A-Rated Materials Stocks to Buy
These stocks are great choices for an improving economy
By Louis Navellier, Editor, Growth Investor Apr 13, 2018, 1:31 pm EDT April 13, 2018
Source: Dayne Topkin Via Unsplash
Materials stocks run the gamut. But whether a firm is making steel, refining oil and gas or making distilled spirits, the fact is, in an expanding economy these companies are in very good positions.
As witnessed by the rise in oil prices in recent days, demand is increasing for these fundamental producers as consumers and companies are demanding more products.
Some of these stocks have already started their ascent, but that doesn't mean they're near the summit. This economic unwinding is just starting to play out, now that central banks have once again relinquished control of the economy, it will spell much more dynamic growth.
And this sector is one of the major beneficiaries of this elemental economic growth.
Following are seven A-rated materials stocks to buy that are on track to return solid gains in the quarters to come. This is going to be a long ride, so get on board soon.
A-Rated Materials Stocks to Buy: Rayonier Advanced Materials (RYAM)
Rayonier Advanced Materials Inc (NYSE:RYAM) is a spinoff of Rayonier Inc. (NYSE:RYN), a timber real estate investment trust (REIT).
RYAM is one of the leading cellulose makers. Cellulose is an organic compound that can be derived from plant sources. In the case of RYAM, it can use the byproduct of the timber undergrowth from its parent company as seed stock for its cellulose.
And cellulose is a very versatile product, used in everything from computer screens to pharmaceuticals to cigarette filters. The point is, the more goods that are made, the more cellulose will be used to make them.
What's more, there's a very high barrier to entry into this sector and the top three firms — of which RYAM is one — control about 70% of the market.
RYAM is up 64% in the past year, but relatively flat year to date, so this is a good time to get in before the next leg up.
A-Rated Materials Stocks to Buy: Enduro Royalty Trust (NDRO)
Source: SMelindo via Flickr (Modified)
Enduro Royalty Trust (NYSE:NDRO) is a spinoff from privately held Enduro Resource Partners LLC, a US oil and natural exploration and production firm that operates in Texas, New Mexico and Louisiana.
NDRO is set up as a trust to oversee the properties and generate its earnings from the sales of the oil and natural gas from the properties.
NDRO stock pays a monthly dividend — technically a cash distribution, since shareholders are considered owners in a trust — slightly more than 1% of its current price. Over a year, that's a dividend reaching beyond 12%.
This is a tiny stock, with a market cap that's just over $100 million, so don't chase it. But it's a good buy at current prices as the price of the dollar and oil strengthen.
A-Rated Materials Stocks to Buy: Schnitzer Steel Industrials (SCHN)
Source: Shutterstocks
Schnitzer Steel Industries, Inc. (NASDAQ:SCHN) is a metals recycler based in Portland, Oregon.
It takes scrap metal, processes it and then sells it to steel mills, foundries and smelters, predominantly in the U.S. and Western Canada.
Given the tariff talk in Washington, domestic steel resources are a good place to be right now. In early April SCHN reported its 2Q numbers and they came in strong, which is a positive sign, since this doesn't include any of the price movement in steel and other metals since the trade war of words started.
Up 66% in the past year, this is just the beginning for this $800 million company. Metals are the bellwether for an expanding economy, so this kind of price action is bullish indeed.
A-Rated Materials Stocks to Buy: Kirkland Lake Gold (KL)
Source: Bullion Vault via Flickr (Modified)
Kirkland Lake Gold Ltd (NYSE:KL) is a gold producer with mines in Canada and Australia. It's targeting to produce 620,000 ounces of gold this year.
Regardless of the constant talk about bitcoin and other cryptocurrencies, gold is still the long-time favorite hard asset. It has not been seeing much love as some investors have found digital currencies much cooler. But gold has been a key store of value for thousands of years for a reason, and bitcoin and its ilk aren't likely to supplant the Midas metal anytime soon.
And gold has been steadily rising in the past year, given the increasing volatility in the markets and out of Washington, D.C. And as inflation starts to rise, gold rises as well. It becomes a strategic hedge against devalued currencies.
KL is a mid-tier player with a $3.5 billion market cap. Q1 production is up 13% over Q1 growth last year, which is a bullish sign.
A-Rated Materials Stocks to Buy: Sabine Royalty Trust (SBR)
Sabine Royalty Trust (NYSE:SBR) is a trust formed by Sabine Oil & Gas, an exploration and production company that operates in Texas.
SBR holds the property and mineral rights to the producing and undeveloped lands in its portfolio, which are located in Florida, Louisiana, Mississippi, New Mexico, Oklahoma and Texas.
SBR has a $640 million market cap and delivers a solid 5.5% dividend. The dividend is considered cash distribution since shareholders are viewed as partners in a trust, so this is the way investors get paid directly from profits.
Energy prices look to be in an uptrend and this may well last for years, so finding a good domestic producer to buy into now is a good idea.
A-Rated Materials Stocks to Buy: Valero (VLO)
Source: Mike Mozart via Flickr
Valero Energy Corporation (NYSE:VLO) is the world's largest independent petroleum products refiner and one of the largest markets and refiners of ethanol.
To save a lengthy explanation of how well refiners are doing as demand increases for natural gas and oil products, simply look at a price chart for VLO stock. This is a company with a $43 billion market cap that is up 66% in the past year. That is some significant price performance.
And as an independent producer, it means it can sell its products to its downstream retail and commercial distribution centers or contract it to other retailers.
As long as the global economy continues to expanding, VLO is going to be doing a bang-up business. And as U.S. natural gas exports start to ramp up in coming years, it will do even better.
A-Rated Materials Stocks to Buy: MGP Ingredients (MGPI)
MGP Ingredients Inc (NASDAQ:MGPI) has a very unique business. It produces and supplies distilled spirits and specialty wheat proteins for food products.
Given this business plan, it's no surprise that MGPI is located in Kansas, the heart of the heartland.
The company has a couple things going for it. First, it's a specialized business that has a solid competitive moat around it. Second, the craft cocktail movement is growing just like the craft beer movement did and continues to this day.
MGPI will work with customers to distill a bourbon, rye, gin or vodka to the specs the customer desires or will sell them the base ingredients for them to do it themselves.
While it has a few brands of its own — TILL American Wheat Vodka, Tanner's Creek Blended Bourbon Whiskey and George Remus Straight Bourbon Whiskey — most is distilled for other labels. And business is going very well. MGPI stock is up 63% in the past year, with more to come.
Louis Navellier is a renowned growth investor. He is the editor of five investing newsletters: Blue Chip Growth, Emerging Growth, Ultimate Growth, Family Trust and Platinum Growth. His most popular service, Blue Chip Growth, has a track record of beating the market 3:1 over the last 14 years. He uses a combination of quantitative and fundamental analysis to identify market-beating stocks. Mr. Navellier has made his proven formula accessible to investors via his free, online stock rating tool, PortfolioGrader.com. Louis Navellier may hold some of the aforementioned securities in one or more of his newsletters.
Article printed from InvestorPlace Media, https://investorplace.com/2018/04/7-a-rated-materials-stocks-to-buy-mgpi-vlo-schn/.
©2019 InvestorPlace Media, LLC
More from InvestorPlace
5 STARS Stocks Smashing the Market (FANG Stocks, Too)
By Luke Lango Jul 15, 2019
9 Retail Stocks Goldman Sachs Says Are Ready to Rip
15 Stocks Facing Big Political Risk in 2019
By Vince Martin Dec 18, 2018
3 Breakout Stocks to Buy
By Tyler Craig Jul 15, 2019
Sponsored Headlines
7 Short Squeeze Stocks With Big Upside Potential
6 Stocks to Buy Based on Insider Buying
10 Best Dividend Stocks to Buy for the Rest of 2019 and Beyond
10 Stocks to Buy for Less Than Book


This Keto Monte Cristo Breakfast Casserole is perfect to make ahead for busy mornings or even a fancy brunch with friends! This delicious low carb breakfast casserole hits all my favorite sweet and salty notes!
Typically a Monte Cristo is a ham and Gruyere (or Swiss) cheese sandwich that is then dipped in french toast batter and fried. The cool twist on it is that it's served with warm maple syrup – so it hits all of the salty and sweet notes that I love.
Since my popular keto cream cheese pancakes recipe tastes so much like french toast, I thought it would make the perfect stand in for the bread portion in this Keto Monte Cristo Breakfast Casserole. To keep it easy, I layered all of the ingredients and baked it like a casserole.
Once baked, you simply pour on the warmed sugar free syrup, which soaks into all of the layers. You can serve with additional syrup if you choose.
I particularly like Canadian bacon in this recipe because it's much heartier and more substantial in texture than deli ham, but just as convenient! I definitely recommend trying it with the Canadian bacon if you can get it.
Because I love a runny egg on almost anything, I also added a poached egg to the top of mine – it was total breakfast bliss. The egg is optional, but I personally will take the egg every time. It's amazing.
My suggestion is to make this Keto Monte Cristo Breakfast Casserole ahead of time and cut into portions. Then when you are reheating the leftovers, simply poach or fry an egg or two that morning to have with it.
If you are short on time or aren't a fan of eggs, this Keto Monte Cristo Breakfast Casserole can also be enjoyed cold if you need breakfast or lunch on the go! Because of the cheese it holds together well and can literally be eaten with your hands and a napkin on your way out the door or even in the car.
Mr. Hungry and Hungry Jr. also really liked this low carb casserole recipe – it will be a staple at our house for the next few months at least. Hope you guys like it too – look for it on an upcoming Keto Menu Plan!
This Keto Monte Cristo Breakfast Casserole makes a delicious low carb breakfast with all the sweet and salty flavors of the classic Monte Cristo sandwich!
1/3 cup Sugar Free Pancake Syrup, warmed.
Grease a 9 x 9 baking dish and place a layer of 4 cream cheese pancakes on the bottom and halfway up the sides.
Add a layer of Canadian Bacon, then sprinkle with 1/2 cup of cheese.
Repeat 2 more times until you have three layers – the top layer being the cheese.
Bake at 375 degrees (F) for 15 minutes, or until heated through.
Remove from the oven and pour the warm syrup evenly over the top.
Cut into 6 squares and serve.
Optional – top with a runny poached or fried egg and additional sugar free syrup.
I love this! I added a tablespoon of sugar free raspberry jam and just a touch of swerve confectioners sugar and i felt like i was having the "real" thing!
Love Monte Cristo's, so glad I don't have to give my fav's when I change my eating habits.
I know this is an old recipe – but I'm pretty new to Keto. I've made it twice, and the first time I felt like I was living in my kitchen cooking pancakes. This time I poured the batter into silpat-lined sheet pans and baked them at 350 for about 10 minutes (I think??)…then cut them to size to fit in my 9×9, and baked it off. Absolutely delicious!
I'm excited to make this, but I've never used Canadian bacon before – does it have to be cooked first, or is the 15 minutes in the oven enough?
This is delicious!!!!!! I highly recommend it.
What is the carb count before subtracting fiber?
To die for! I've been following meal plans 1 through 4 and this is the best recipe of all! Can't wait to have it again.
This dish looks really good! Thank you for sharing!
I found your delicious sounding recipe and want to try it for Christmas morning. I am planning on doubling the recipe… so when I look at the Cream Cheese Pancakes and multiply that by 6 it suggests 12 tsp Stevia (with one packet=2 tsp, according to CookingWithStevia.com). They recommend, tho, using only 1/2 tsp bulk Stevia Blends for every packet….. What would you do? Use the 12tsp Stevia straight conversion, or drop down to 3 tsp? That's a big difference!
Straight stevia will be much sweeter than a blend so you'll use much less of than you would the blended, which measures more like real sugar. If you are making six batches then try about 1 tsp of pure stevia, or 2 Tbsp of the blended. If you're using them in the monte cristo casserole, you don't want them super sweet anyway so this should get you where you need to be. Enjoy!
I am so glad I found this! First of all, the pancakes are such a huge treat for me right now since I'm not eating grains and this was just delicious. We all loved it. Can't wait to use the pancake recipe again and make this again.
You are a Godsend!! I have been missing Monte Cristo sandwhiches since being diagnosed with celiac. And I love the cream cheese pancakes even though i am not a pancake fan, they are fabulous and I use them as crepes.
The light in these photos (everything about these photos, actually) is amazing. I LOVE the one with the yolk coming out of the egg and the syrup coming down onto the egg. That one is really above and beyond.
Wow! This was wonderful! I used to love the Monte Cristo. This has all the great flavors and more. i could serve this at a brunch and great rave reviews.
Back on track after two weeks of business travel. This recipe is a great way to Kick start the week.
Thanks so much Diane! This would be a perfect brunch recipe!
I cooked pheasant last night and exchanged it for the chicken, making your gravy with bacon, sage and cider gravy and your corn and bacon muffins. It was delicious. I did wonder about using the cider as it was so high in carbs but it was only 1/4 cup. We had your chocolate cupcakes with the pudding filling and whip cream. I didn't have the sf toffee so I toasted sliced almonds in Splenda and stacked some on top. Thank you Melissa for your great recipes. I'm so excited to try all of them!!
Thanks so much Victoria! So glad you are enjoying the ezine recipes! And yes, the cider in minimal amounts can be worked into recipes – and it adds so much yummy flavor! Love pheasant but it's hard to get around here – I'll be it was delicious with that cider gravy! Yum!!!!
After all, anyone who is twisted…er…talented enough to create an award-winning BACON CHOCOLATE CAKE could easily conquer maple syrup!
Thanks, Melissa! You're the best.
I'll see what I can do! Btw the syrup I linked to was just for example's sake – you can get that same brand (it's one of my faves) at walmart for about 2.99 a bottle!
Sounds like if you just topped it with Hollandaise sauce and the egg instead of the maple syrup, there's your Eggs Benedict. This sounds great, too, by the way. I used to LOVE Monte Cristos, and now I can again. Thank you!
True Eric! I've got some other ideas for a play on eggs benedict and as soon as I perfect it I'll post it here too! Meanwhile I hope you enjoy this one as much as we did!
Could add some sugar free Raspberry jam to complete the illusion of a Monte Cristo.
The pancakes are very thin and could also be used as crepes – roll the ham & chees in them, then pour the sauce over. No need for extra eggs.
So many possible variations! Thanks Janet!
I'm wondering if this dish would freeze well? Sounds delicious!
I haven't tried it Janice but I don't see why not! Let us know if you try it and if it works. I've frozen the pancakes and that's always fine, so it should, in theory, work!
Thats so funny, because the only thing I have "changed" on your meal plan is that some mornings I take two cream cheese pancakes, deli ham and swiss and roll them up and add a tablespoon of sugar free raspberry jam!!!! TASTY!!!
That DOES sound tasty Brooke – and super easy! I love salty and sweet together but never considered sugar free jam – definitely going to have to experiment with that soon!
Hi Nancy! Hope you enjoy this recipe as much as we all did – it's definitely perfect snow day food! :) Sounds like you're doing everything right – hang in there and keep us posted on your results!
Amazing! I love anything with eggs and this sends it over the top. Can't wait to try it.
It really is SO good and if you love eggs this is going to be right up your alley!


text:
The Flight Efficiency Plan (FEP), the name of which derives from the application of the concept of flight efficiency, intended as the creation of an airspace structure geared towards satisfying the needs of airlines to plan increasingly shorter routes, with a vertical profile of continuous ascent and descent that guarantees the reduction of consumption, is a plan that summarises the multi-annual interventions carried out by the Group, aimed at optimising the structure of the airway network, precisely to allow the reduction of flight time, fuel consumption and carbon dioxide emissions on the part of aircraft. The Group therefore works towards the realisation of solutions that, in addition to ensuring the maintenance of safety levels (operational safety), are oriented towards flight efficiency with the aim of helping to reduce management costs, minimise the environmental impact and introduce a leading edge navigation system into the Italian air space.
The plan contains both planned interventions in terms of airspace planning (implementation of new routes or improvement of existing ones, as well as the removal, when feasible, of constraints on the availability and usability of airspace for all flight status) and interventions at the level of automation of airport collaboration for the efficiency of aircraft handling (reduction of the time of taxiing and waiting for take-off) achieved through the progressive implementation in the major airports of the A-CDM (Airport Collaborative Decision Making), in addition to training and educating operational personnel.
In the context of the FEP objectives that refer to route rectification and the implementation of an airspace structure that ensures the fulfilment of flight efficiency objectives, in December 2016 (with an advance of about 6 years on the term defined by the European regulation of the Single European Sky) ENAV implemented the Free Route Italy (FRAIT). The project has made it possible, for all aircraft flying over an altitude of 11,000 metres, to cross Italian skies with a direct route without referring any longer to a precise route network, which has consequently been eliminated.
The Free Route was a very revolutionary project for national and European air transport since it allowed airlines to plan the shortest possible trajectory, flying directly from an entry point to an exit point in Italian airspace, saving fuel, harmful emissions and consequently costs, while of course maintaining at least unchanged, as is the prerogative of the ENAV Group on each development project, the levels of safety.
From the analyses carried out, the consolidated data at the end of 2017 shows that the savings are about 30 million Kg of fuel, with an environmental benefit of 95 million kg CO2 emissions reduction .
THE "FREE ROUTE" PROJECT GENERATED A LOWER CO2 IMPACT OF 95 MILLION KG
In order to benefit from the advantages introduced by the Free Route, Airlines have changed their flight schedules, increasing their distances within the Italian airspace. The reduction of travel times, associated with a structure of airspace oriented to flight efficiency, has in fact attracted many customers to plan in Italy, recording both significant increases in frequencies on the City Pairs (city of departure and destination) that were already of interest in the Italian skies, as well as over flights for City Pairs that were never planned before the Free Route, Istanbul Caracas, Monastir Brussels, Barcelona Shanghai and Istanbul Havana to name a few.
The ENAV Group was the first, among the 5 major European service providers, to implement the Free Route and with it completed the plan of reorganisation of the Italian airspace, started in 2014, which guarantees to achieve the maximum flight efficiency, thus generating benefits for both airlines and the environment.


text:
Home Entertainment Song Hye-kyo Visited Jo In-sung on the Set of 'It's Okay, That's...
Song Hye-kyo Visited Jo In-sung on the Set of 'It's Okay, That's Love', Find Out About Their Relationship!
http://onehallyu.com
Song Hye-kyo and Jo In-sung's Relationship
After knowing each other for more than a decade, it is actually surprising that Song Hye-kyo and Jo In-sung only worked once on the same project, which was SBS's That Wind, the Winter Blows in 2013. During his interview after production, Jo In-sung revealed that Song Hye-kyo was concerned about retiring for a while, stating "She said, 'I actually thought about whether I will have to take a break for a few years." Regarding his chemistry with the actress, Jo In-sung said that he does not view her as a romantic interest so he is comfortable around her.
You might like: Is Jo In-sung Getting Married? Who Is His Wife?
http://soompi.com
Jo In-sung's statement remained true as he later became the matchmaker between Song Hye-kyo and Song Joong-ki, who he is also friends with. The couple first met in 2013 during the shooting of That Wind, the Winter Blows when Song Joong-ki visited the filming set. Then, Jo In-sung recommended Song Joong-ki to the production team of Descendant of the Sun for the main cast along with Song Hye-kyo. Both of them ended up married in October 2017.
Song Hye-kyo's Visit to Jo In-sung's Drama Set
In August 2014, Song Hye-kyo made a surprise visit to her former co-star Jo In-sung at his drama filming for SBS's It's Okay, That's Love as well as the drama director Kim Kyu-tae. The actress' visit was informed by her agency on Twitter with the post "A sudden attack on writer Jae Yeol. Young who went to meet Soo oppa after a long time. One cut taken with director Kim Kyu Tae and lighting director Park Hwan. Everyone warmly welcomed us so we are thankful."
http://allkpop.com
In addition, Song Hye-kyo brought a food truck for the staff and cast of the drama. Later, it was revealed that a lot of the staff worked on That Wind, the Winter Blows which made the reunion even more momentous for all of them.
Get Closer with 2PM's Hwang Chansung: Profile, Family, Girlfriend, Plastic Surgery, Movies and TV...
Destya - July 16, 2018
Get Closer to Actress Lee Mi-sook: Plastic Surgery, Family, Movies, and TV Shows
Destya - September 24, 2018
Everything You Need To Know About DKB's Teo: Full Profile, Fun Facts, Visual, And...
Astari - September 6, 2021
WEi's Kim Yo-han: Profile, Facts, 'Produce X 101', Debut with X1
Sierra - April 15, 2021
She's Looking Different From Her Pre-debut Photos, What's the Secret Behind DIA's Chae-yeon's Pretty...
Astari - June 12, 2019


text:
Historic newspapers collection
Identifier: SPEC-065
This collection consists of historic newspapers from Muncie, Indiana, the United States and England ranging from 1700 to 1963.
Literary rights, including copyright resides with the creators of the documents or their legal heirs and assigns. All requests to publish or quote from manuscripts must be submitted to Archives and Special Collections. The publisher must also obtain permission of the copyright holder.
.6 Cubic Feet
Arranged by location and then alphabetically.
Items in this collection were acquired through multiple accessions from multiple donors. Some of the newspapers were collected and added by Archives and Special Collections staff.
Related Archival Materials
Materials relating to this collection may be found in the following collections in Archives and Special Collections, Ball State University Libraries, Muncie IN:
SPEC.064: Nickerson newspaper collection
SPEC.073: Misiewicz newspaper collection
Newspapers Subject Source: Library of Congress Subject Headings
Part of the Special Collections Repository
http://cms.bsu.edu/academics/libraries/collectionsanddept/archives
Alexander M. Bracken Library
2000 W. University Avenue
Muncie Indiana 47306 USA
libarchives@bsu.edu
Historic newspapers collection, Archives and Special Collections, Ball State University Libraries
Historic newspapers collection, Archives and Special Collections, Ball State University Libraries https://archivessearch.bsu.edu/repositories/7/resources/3262 Accessed January 26, 2023.


text:
1300 ISLAMIC (1300 475 264)
Everyday banking
Home finance
Shariah-compliance
Our Shariah committee
FAQs about Islamic banking
Our company and team
What's a Restricted ADI?
When will we launch?
Investment enquiries
Chris Maclean
Chris is an extremely experienced Australian banker who has previously served as Chief Risk Officer at Bankwest, Group Head of Credit for ANZ and as Group Chief Risk Officer at Al Rajhi Bank, the world's largest Islamic banking group (based in Jeddah, Saudi Arabia from 2015-2020).
He has also served as Chair of the Saudi Arabian central bank's (SAMA) Chief Risk Officers Committee.
Chris not only brings intensive risk leadership experience to the IBA Group board, but brings a wealth of product/strategy/distribution knowledge also.
His knowledge of both conventional and Islamic banking assists the board greatly in assisting us to launch the first Australian Islamic bank. Chris is also a chartered accountant and holds a Bachelor of Business from Western Sydney University.
Chris is passionate about Islamic banking and is delighted to have joined the Islamic Bank Australia board.
We're not open for business yet. We're a "Restricted ADI" which allows us to build our systems and test our products before 5 July 2024. We then plan to obtain APRA approval to launch publicly.
Join our waiting list and we'll let you know the moment we're ready.
By clicking below, you agree to the terms of our Privacy Policy. We'll keep you updated, but you can unsubscribe anytime.
Your age range
Select your age range 18-24 25-34 35-44 45-54 55-64 65+
Join the waiting list!
ABOUT CONTACT CAREERS FAQ
WHAT'S A RESTRICTED ADI?
FIGHTING MONEY LAUNDERING AND TERRORISM FINANCING
Important regulatory notice
We hold a restricted ADI authorisation granted by the Australian Prudential Regulation Authority (APRA). This authorisation allows us to offer banking services, but is subject to certain restrictions such as a cap on the amount of deposits that we can hold in total. The purpose of the "restricted" status is that we can test our systems and processes before launching as a fully unrestricted bank.
We do not currently meet the full prudential framework and/or requirements, and you should consider this before depositing funds with us. After the completion of our "restricted" phase, we plan to obtain APRA's approval so that we can publicly launch.
We acknowledge the Aboriginal and Torres Strait Islander peoples as the first Australians and Traditional Custodians of the lands where we live, work and bank. Our corporate head office is in Darug Country. We pay our respects to Elders past, present and emerging.
Copyright © Islamic Bank Australia Pty Ltd. ABN 37 609 971 280. AFSL and ACL 534355. AFCA member 76324.
Information on this website does not take your personal circumstances, needs or objectives into account. Please consider its appropriateness for you. We are not yet open for business. We are a Restricted ADI and do not yet meet the full prudential framework, and you should consider this before banking with us once we are open for business. Fees and charges may apply, as well as terms and conditions which you should review. Information on this website is subject to change. In order to open a credit product in future, you will need to meet our credit criteria and be approved. Please review the product disclosure documentation provided at the time of opening your account for detailed information.


text:
#include "stdafx.h"
#include <Microsoft\MBox.Object.h>
#include <Microsoft\MBox.Process.h>
#include <KTL\KTL.Memory.SharedPtr.h>
#include <KTL\KTL.Containers.List.h>
#include <KTL\KTL.Multithreading.LockHelper.h>
#include <KTL\KTL.Multithreading.SpinLock.h>

#include "Owl.h"
#include <Vol.Kernel\Vol.Memory.h>

namespace MBox
{
    HANDLE Owl::s_DeviceGroupHandle = nullptr;

    //////////////////////////////////////////////////////////////////////////

    NTSTATUS Owl::PacketProtocol::Initialize(
        void * aSendBuffer,
        UINT32 aSendBytes,
        void * aReplyBuffer,
        UINT32 aReplyBytes)
    {
        m_SenderBuffer = aSendBuffer;
        m_SenderBytes = aSendBytes;
        m_ReplyBuffer = aReplyBuffer;
        m_ReplyBytes = aReplyBytes;

        KeInitializeEvent(&m_ReplyEvent, EVENT_TYPE::NotificationEvent, FALSE);
        return STATUS_SUCCESS;
    }

    bool Owl::CommunicationPort::IsUserThreadActived()
    {
        LARGE_INTEGER vTimeout{ 0 };
        NTSTATUS vStatus = KeWaitForSingleObject(m_UserThread, Executive, KernelMode, FALSE, &vTimeout);
        if (STATUS_TIMEOUT == vStatus)
        {
            return true;
        }
        return false;
    }

    NTSTATUS Owl::CommunicationPort::Initialize(const wchar_t * aPortName, UINT32 aPortNameLength)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        static const wchar_t sDeviceDirectory[]    = L"\\Device";
        static const wchar_t sDeviceDosDirectory[] = L"\\DosDevices\\Global";

        for (;;)
        {
            new(&m_PacketList) ktl::list<PacketProtocol *>;

            USHORT vDeviceNameMaxBytes    = USHORT((aPortNameLength * 2) + sizeof(sDeviceDirectory) + (sizeof(L"\\")));
            USHORT vDeviceDosNameMaxBytes = USHORT((aPortNameLength * 2) + sizeof(sDeviceDosDirectory) + (sizeof(L"\\")));

            m_DeviceName.Buffer     = (PWCH)new ktl::byte[vDeviceNameMaxBytes]{};
            m_DeviceDosName.Buffer  = (PWCH)new ktl::byte[vDeviceDosNameMaxBytes]{};

            if (nullptr == m_DeviceName.Buffer
                || nullptr == m_DeviceDosName.Buffer)
            {
                vStatus = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
            m_DeviceName.MaximumLength      = vDeviceNameMaxBytes;
            m_DeviceDosName.MaximumLength   = vDeviceDosNameMaxBytes;

            vStatus = RtlUnicodeStringPrintf(&m_DeviceName, L"%s%s", sDeviceDirectory, aPortName);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            vStatus = RtlUnicodeStringPrintf(&m_DeviceDosName, L"%s%s", sDeviceDosDirectory, aPortName);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            break;
        }

        if (!NT_SUCCESS(vStatus))
        {
            Uninitialize();
        }

        return vStatus;
    }

    void Owl::CommunicationPort::Uninitialize()
    {
        if (m_DeviceName.Buffer)
        {
            delete[](ktl::byte*)(m_DeviceName.Buffer);
            m_DeviceName.Buffer = nullptr;

            m_DeviceName.Length = m_DeviceName.MaximumLength = 0;
        }

        if (m_DeviceDosName.Buffer)
        {
            delete[](ktl::byte*)(m_DeviceDosName.Buffer);
            m_DeviceDosName.Buffer = nullptr;

            m_DeviceDosName.Length = m_DeviceDosName.MaximumLength = 0;
        }
    }

    //////////////////////////////////////////////////////////////////////////

    static void DriverUnload(DRIVER_OBJECT* /*aDriverObject*/)
    {
        //Uninitialize();
    }

    static NTSTATUS DeviceCreate(
        DEVICE_OBJECT* /*aDeviceObject*/,
        IRP* aIrp)
    {
        aIrp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(aIrp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }

    static NTSTATUS DeviceClose(
        DEVICE_OBJECT* /*aDeviceObject*/,
        IRP* aIrp)
    {
        aIrp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(aIrp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }

    static NTSTATUS DeviceControl(
        DEVICE_OBJECT* aDeviceObject,
        IRP* aIrp)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;
        auto vIrp = IoGetCurrentIrpStackLocation(aIrp);

        Owl* vThis = nullptr;
        UINT32 vResponseBytes = 0;

        for (;;)
        {
            vThis = (Owl*)(aDeviceObject->DeviceExtension);
            if (nullptr == vThis)
            {
                vStatus = STATUS_DEVICE_DATA_ERROR;
                break;
            }

            switch (IoCode(vIrp->Parameters.DeviceIoControl.IoControlCode))
            {
            default:
            {
                vStatus = STATUS_INVALID_DEVICE_REQUEST;
                break;
            }

            case IoCode::Connecttion:
            {
                vStatus = vThis->ConnectHandler(
                    aIrp->RequestorMode,
                    (ConnectContextHeader*)aIrp->AssociatedIrp.SystemBuffer,
                    vIrp->Parameters.DeviceIoControl.InputBufferLength,
                    &vResponseBytes);

                break;
            }

            case IoCode::Disconnection:
            {
                vStatus = vThis->DisconnectHandler();
                break;
            }

            case  IoCode::UserMessage:
            {
                void* vReplyBuffer = nullptr;
                if (vIrp->Parameters.DeviceIoControl.OutputBufferLength
                    && aIrp->MdlAddress)
                {
                    vReplyBuffer = MmGetSystemAddressForMdlSafe(aIrp->MdlAddress,
                        NormalPagePriority | MdlMappingNoExecute);
                    if (nullptr == vReplyBuffer)
                    {
                        vStatus = STATUS_INSUFFICIENT_RESOURCES;
                        break;
                    }
                }

                vStatus = vThis->UserMessageHandler(
                    aIrp->AssociatedIrp.SystemBuffer,
                    vIrp->Parameters.DeviceIoControl.InputBufferLength,
                    vReplyBuffer,
                    vIrp->Parameters.DeviceIoControl.OutputBufferLength,
                    &vResponseBytes);
                break;
            }

            case  IoCode::KernelMessage:
            {
                void* vReplyBuffer = nullptr;
                if (vIrp->Parameters.DeviceIoControl.OutputBufferLength
                    && aIrp->MdlAddress)
                {
                    vReplyBuffer = MmGetSystemAddressForMdlSafe(aIrp->MdlAddress,
                        NormalPagePriority | MdlMappingNoExecute);
                    if (nullptr == vReplyBuffer)
                    {
                        vStatus = STATUS_INSUFFICIENT_RESOURCES;
                        break;
                    }
                }

                vStatus = vThis->KernelMessageHandler(
                    (MessageHeader*)(vReplyBuffer),
                    vIrp->Parameters.DeviceIoControl.OutputBufferLength,
                    &vResponseBytes);
                break;
            }

            case  IoCode::ReplyKernelMessage:
            {
                vStatus = vThis->ReplyKernelMessageHandler(
                    (ReplyHeader*)(aIrp->AssociatedIrp.SystemBuffer),
                    vIrp->Parameters.DeviceIoControl.InputBufferLength,
                    &vResponseBytes);
                break;
            }

            }

            break;
        }

        aIrp->IoStatus.Status = vStatus;
        aIrp->IoStatus.Information = vResponseBytes;
        IoCompleteRequest(aIrp, IO_NO_INCREMENT);
        return vStatus;
    }

    //////////////////////////////////////////////////////////////////////////

    NTSTATUS Owl::Initialize()
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        for (;;)
        {
            if (nullptr == s_DeviceGroupHandle)
            {
                auto vDispatchPacket = new DriverMgr::DispatchCallbackPacket;
                if (nullptr == vDispatchPacket)
                {
                    vStatus = STATUS_INSUFFICIENT_RESOURCES;
                    break;
                }
                vDispatchPacket->m_MajorCallback[IRP_MJ_CREATE] = DeviceCreate;
                vDispatchPacket->m_MajorCallback[IRP_MJ_CLOSE]  = DeviceClose;
                vDispatchPacket->m_MajorCallback[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
                vDispatchPacket->m_UnloadCallback = DriverUnload;

                vStatus = DriverMgr::RegisterDeviceGroup(
                    &s_DeviceGroupHandle,
                    vDispatchPacket,
                    [](DriverMgr::DispatchCallbackPacket* aDispatchPacket)->void { delete aDispatchPacket; });
                if (!NT_SUCCESS(vStatus))
                {
                    delete vDispatchPacket;
                    vDispatchPacket = nullptr;

                    break;
                }
            }

            break;
        }

        if (!NT_SUCCESS(vStatus))
        {
            Uninitialize();
        }

        return vStatus;
    }

    NTSTATUS Owl::Uninitialize()
    {
        CloseCommunicationPort();
        return STATUS_SUCCESS;
    }

    HANDLE Owl::GetGroupHandle()
    {
        return s_DeviceGroupHandle;
    }

    NTSTATUS Owl::CreateCommunicationPort(
        const wchar_t * aPortName,
        UINT32 aPortNameLength,
        void * aServerPortContext)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        DEVICE_OBJECT*     vDeviceObject = nullptr;
        CommunicationPort* vCommunicationPort = nullptr;

        for (;;)
        {
            if (m_CommunicationPort)
            {
                vStatus = STATUS_ALREADY_REGISTERED;
                break;
            }

            if (nullptr == aPortName)
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            vCommunicationPort = new CommunicationPort;
            if (nullptr == vCommunicationPort)
            {
                vStatus = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            vStatus = vCommunicationPort->Initialize(aPortName, aPortNameLength);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            vStatus = DriverMgr::CreateDeviceObject(
                GetGroupHandle(),
                0,
                &(vCommunicationPort->m_DeviceName),
                FILE_DEVICE_UNKNOWN,
                FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &vDeviceObject);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            vStatus = IoCreateSymbolicLink(
                &(vCommunicationPort->m_DeviceDosName),
                &(vCommunicationPort->m_DeviceName));
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            vDeviceObject->DeviceExtension = this;

            vCommunicationPort->m_ServerPortContext  = aServerPortContext;
            vCommunicationPort->m_DeviceObject = vDeviceObject;

            vDeviceObject->Flags |= DO_BUFFERED_IO;
            vDeviceObject->Flags |= DO_DIRECT_IO;
            vDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);

            m_CommunicationPort = vCommunicationPort;
            break;
        }

        if (!NT_SUCCESS(vStatus))
        {
            CloseCommunicationPort();
        }

        return vStatus;
    }

    NTSTATUS Owl::CloseCommunicationPort()
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        if (m_CommunicationPort)
        {
            DisconnectHandler();

            if (m_CommunicationPort->m_DeviceObject)
            {
                IoDeleteSymbolicLink(&(m_CommunicationPort->m_DeviceDosName));
                vStatus = DriverMgr::DeleteDeviceObject(
                    GetGroupHandle(),
                    m_CommunicationPort->m_DeviceObject);
            }

            m_CommunicationPort->Uninitialize();
            delete m_CommunicationPort;
            m_CommunicationPort = nullptr;
        }

        return vStatus;
    }

    NTSTATUS Owl::SendMessage(
        void* aSendBuffer,
        UINT32 aSendBytes,
        void* aReplyBuffer,
        UINT32 aReplyBytes,
        UINT32 aMillisecondsTimeout)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        PacketProtocol* vPacket = nullptr;

        for (;;)
        {
            if (nullptr == m_CommunicationPort)
            {
                vStatus = STATUS_INVALID_PORT_HANDLE;
                break;
            }

            if (false == m_CommunicationPort->m_IsConnected)
            {
                vStatus = STATUS_PORT_DISCONNECTED;
                break;
            }

            if (false == m_CommunicationPort->IsUserThreadActived())
            {
                DisconnectHandler();

                vStatus = STATUS_PORT_DISCONNECTED;
                break;
            }

            if ((nullptr == aSendBuffer && aSendBytes)
                || (nullptr == aReplyBuffer && aReplyBytes))
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            vPacket = new PacketProtocol;
            if (nullptr == vPacket)
            {
                vStatus = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            vPacket->Initialize(aSendBuffer, aSendBytes, aReplyBuffer, aReplyBytes);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            do
            {
                ktl::lock_guard<ktl::spin_lock> vLock(m_CommunicationPort->m_PacketListLock);
                if (false == m_CommunicationPort->m_PacketList.push_back(vPacket))
                {
                    vStatus = STATUS_INSUFFICIENT_RESOURCES;
                    break;
                }

            } while (false);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            KeReleaseSemaphore(m_CommunicationPort->m_NotifySemaphore, IO_NO_INCREMENT, 1, FALSE);

            LARGE_INTEGER vTimeout{};
            vStatus = KeWaitForSingleObject(
                &vPacket->m_ReplyEvent,
                Executive, KernelMode, FALSE,
                Vol::DateTime::FormatTimeoutToLargeInteger(&vTimeout, aMillisecondsTimeout));
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            if (PacketProtocol::State::Get ==
                PacketProtocol::State(InterlockedCompareExchange(
                    (volatile long*)&vPacket->m_State,
                    long(PacketProtocol::State::Send),
                    long(PacketProtocol::State::Get))))
            {
                //
                // Timeout & Alread GetMessage
                //

                vStatus = KeWaitForSingleObject(
                    &vPacket->m_ReplyEvent,
                    Executive, KernelMode, FALSE,
                    Vol::DateTime::FormatTimeoutToLargeInteger(&vTimeout, aMillisecondsTimeout));
                if (!NT_SUCCESS(vStatus))
                {
                    break;
                }
            }

            if (STATUS_TIMEOUT == vStatus)
            {
                ktl::lock_guard<ktl::spin_lock> vLock(m_CommunicationPort->m_PacketListLock);

                auto vIterBegin = m_CommunicationPort->m_PacketList.begin();
                auto vIterEnd = m_CommunicationPort->m_PacketList.end();

                for (; vIterBegin != vIterEnd; ++vIterBegin)
                {
                    if (vPacket == (*vIterBegin))
                    {
                        m_CommunicationPort->m_PacketList.erase(vIterBegin);
                        break;
                    }
                }

                vPacket->m_Status = vStatus;
            }

            vStatus = vPacket->m_Status;
            break;
        }

        delete vPacket;
        return vStatus;
    }

    NTSTATUS Owl::DisconnectHandler()
    {
        m_CommunicationPort->m_IsConnected = false;

        if (m_CommunicationPort->m_UserThread)
        {
            ObDereferenceObject(m_CommunicationPort->m_UserThread);
            m_CommunicationPort->m_UserThread = nullptr;
        }

        if (m_CommunicationPort->m_NotifySemaphore)
        {
            ObDereferenceObject(m_CommunicationPort->m_NotifySemaphore);
            m_CommunicationPort->m_NotifySemaphore = nullptr;
        }

        if (m_CommunicationPort->m_PacketList.size())
        {
            ktl::lock_guard<ktl::spin_lock> vLock(m_CommunicationPort->m_PacketListLock);
            for (auto vItem : m_CommunicationPort->m_PacketList)
            {
                auto vReplyHeader = (ReplyHeader*)(vItem->m_ReplyBuffer);
                vReplyHeader->m_Status = STATUS_PORT_DISCONNECTED;

                KeSetEvent(&vItem->m_ReplyEvent, IO_NO_INCREMENT, FALSE);
            }

            m_CommunicationPort->m_PacketList.clear();
        }

        DisconnectNotifyCallbackParameter vCallackParemter;
        vCallackParemter.m_ClientPortContext = m_CommunicationPort->m_ClientPortContext;
        m_DisconnectNotifyCallback(&vCallackParemter);

        return STATUS_SUCCESS;
    }

    NTSTATUS Owl::ConnectHandler(
        KPROCESSOR_MODE aAccessMode,
        ConnectContextHeader * aConnectionContext,
        UINT32 aConnectionContextBytes,
        UINT32* aResponseReplyBytes)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        for (;;)
        {
            if (m_CommunicationPort->m_IsConnected)
            {
                if (m_CommunicationPort->IsUserThreadActived())
                {
                    vStatus = STATUS_CONNECTION_COUNT_LIMIT;
                    break;
                }

                DisconnectHandler();
            }

            if (nullptr == aConnectionContext)
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            if (0 == aConnectionContext->m_NotifySemaphore
                || 0 == aConnectionContext->m_ThreadHandle)
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            if (aConnectionContextBytes
                < sizeof(*aConnectionContext))
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            m_CommunicationPort->m_ClientProcessId = PsGetCurrentProcessId();

            vStatus = ObReferenceObjectByHandle(
                HANDLE(aConnectionContext->m_NotifySemaphore),
                SEMAPHORE_ALL_ACCESS,
                *ExSemaphoreObjectType,
                aAccessMode,
                (void**)&m_CommunicationPort->m_NotifySemaphore,
                nullptr);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            vStatus = ObReferenceObjectByHandle(
                HANDLE(aConnectionContext->m_ThreadHandle),
                THREAD_ALL_ACCESS,
                *PsThreadType,
                aAccessMode,
                (void**)&m_CommunicationPort->m_UserThread,
                nullptr);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            ConnectNotifyCallbackParameter vConnectNotifyParameter;
            vConnectNotifyParameter.m_ServerPortContext = m_CommunicationPort->m_ServerPortContext;
            vConnectNotifyParameter.m_ClientProcessId   = m_CommunicationPort->m_ClientProcessId;

            if (aConnectionContextBytes > sizeof(*aConnectionContext))
            {
                vConnectNotifyParameter.m_ConnectionContext         = ++aConnectionContext;
                vConnectNotifyParameter.m_ConnectionContextBytes    = aConnectionContextBytes - sizeof(*aConnectionContext);
            }

            vStatus = m_ConnectNotifyCallback(&vConnectNotifyParameter);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            m_CommunicationPort->m_ClientPortContext = vConnectNotifyParameter.m_ClientPortContext;
            m_CommunicationPort->m_IsConnected = true;

            *aResponseReplyBytes = aConnectionContextBytes;
            break;
        }

        if (!NT_SUCCESS(vStatus))
        {
            DisconnectHandler();
        }

        return vStatus;
    }

    NTSTATUS Owl::UserMessageHandler(
        void * aSenderBuffer,
        UINT32 aSenderBytes,
        void * aReplyBuffer,
        UINT32 aReplyBytes,
        UINT32 * aResponseReplyBytes)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        for (;;)
        {
            MessageNotifyCallbackParameter vCallbackParameter;
            vCallbackParameter.m_ClientPortContext = m_CommunicationPort->m_ClientPortContext;
            vCallbackParameter.m_SenderBuffer   = aSenderBuffer;
            vCallbackParameter.m_SenderBytes    = aSenderBytes;
            vCallbackParameter.m_ReplyBuffer    = aReplyBuffer;
            vCallbackParameter.m_ReplyBytes     = aReplyBytes;
            vCallbackParameter.m_ResponseReplyBytes = aResponseReplyBytes;

            vStatus = m_MessageNotifyCallback(&vCallbackParameter);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            break;
        }

        return vStatus;
    }

    NTSTATUS Owl::KernelMessageHandler(
        MessageHeader * aMessageBuffer,
        UINT32 aMessageBufferBytes,
        UINT32 * aNeedBytes)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        PacketProtocol* vPacket = nullptr;
        for (;;)
        {
            if (nullptr == aMessageBuffer
                || aMessageBufferBytes < sizeof(MessageHeader))
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            do
            {
                ktl::lock_guard<ktl::spin_lock> vLock(m_CommunicationPort->m_PacketListLock);
                if (0 == m_CommunicationPort->m_PacketList.size())
                {
                    vStatus = STATUS_NOT_FOUND;
                    break;
                }

                vPacket = m_CommunicationPort->m_PacketList.front();
                InterlockedExchange((volatile long*)&vPacket->m_State, long(PacketProtocol::State::Get));

                *aNeedBytes = vPacket->m_SenderBytes + sizeof(MessageHeader);
                aMessageBuffer->m_MessageId  = UINT64(vPacket);
                aMessageBuffer->m_ReplyBytes = vPacket->m_ReplyBytes + sizeof(ReplyHeader);

                if (aMessageBufferBytes < (vPacket->m_SenderBytes + sizeof(MessageHeader)))
                {
                    vStatus = STATUS_FLT_BUFFER_TOO_SMALL;
                    break;
                }

            } while (false);
            if (!NT_SUCCESS(vStatus))
            {
                break;
            }

            RtlCopyMemory(
                PVOID(UINT_PTR(aMessageBuffer) + sizeof(*aMessageBuffer)),
                vPacket->m_SenderBuffer,
                vPacket->m_SenderBytes);
            break;
        }

        return vStatus;
    }

    NTSTATUS Owl::ReplyKernelMessageHandler(
        ReplyHeader * aReplyBuffer,
        UINT32 aReplyBufferBytes,
        UINT32 * aNeedBytes)
    {
        NTSTATUS vStatus = STATUS_SUCCESS;

        for (;;)
        {
            if (nullptr == aReplyBuffer
                || aReplyBufferBytes < sizeof(ReplyHeader))
            {
                vStatus = STATUS_INVALID_PARAMETER;
                break;
            }

            if (0 == aReplyBuffer->m_MessageId)
            {
                vStatus = STATUS_FLT_NO_WAITER_FOR_REPLY;
                break;
            }

            bool vIsFound   = false;
            auto vPacket    = (PacketProtocol*)aReplyBuffer->m_MessageId;

            do
            {
                ktl::lock_guard<ktl::spin_lock> vLock(m_CommunicationPort->m_PacketListLock);

                auto vIterBegin = m_CommunicationPort->m_PacketList.begin();
                auto vIterEnd   = m_CommunicationPort->m_PacketList.end();

                for (; vIterBegin != vIterEnd; ++vIterBegin)
                {
                    if (vPacket == (*vIterBegin))
                    {
                        InterlockedExchange((volatile long*)&vPacket->m_State, long(PacketProtocol::State::Reply));
                        m_CommunicationPort->m_PacketList.erase(vIterBegin);

                        vIsFound = true;
                        break;
                    }
                }
            } while (false);
            if (false == vIsFound)
            {
                vStatus = STATUS_FLT_NO_WAITER_FOR_REPLY;
                break;
            }

            vPacket->m_Status = aReplyBuffer->m_Status;
            aReplyBufferBytes -= sizeof(ReplyHeader);
            if (vPacket->m_ReplyBytes < aReplyBufferBytes)
            {
                *aNeedBytes         = vPacket->m_ReplyBytes + sizeof(ReplyHeader);
                aReplyBufferBytes   = vPacket->m_ReplyBytes;
                vStatus             = STATUS_BUFFER_OVERFLOW;
                vPacket->m_Status   = vStatus;
            }

            RtlCopyMemory(
                vPacket->m_ReplyBuffer,
                PVOID(UINT_PTR(aReplyBuffer) + sizeof(*aReplyBuffer)),
                aReplyBufferBytes);

            KeSetEvent(&vPacket->m_ReplyEvent, IO_NO_INCREMENT, FALSE);
            break;
        }

        return vStatus;
    }

}

redpajama_set_name: RedPajamaGithub


text:
\section{Introduction} \label{intro}

In the wake of heavy ion collisions, performed in experiments in the LHC at CERN and RHIC at BNL, a state of matter of liberated quarks and gluons, known as the quark-gluon plasma (QGP), is formed \cite{STAR:2005gfr}. There are three common effective descriptions used to study the QGP, which have different regions of applicability within the evolution of a typical heavy ion collision. At early times, kinetic theory captures the weakly coupled dynamics \cite{Arnold:2002zm}. At later times, as the system undergoes hydrodynamization, strongly coupled holography \cite{Heller:2016gbp} and relativistic hydrodynamics \cite{Teaney:2009qa} become increasingly more relevant.

 Following the discussion in \cite{Kurkela:2019kip}, we can examine the analytic structure of the mentioned theories. Each theory mentioned has in common a hydrodynamic pole, but other non-analytic structures are radically different. For instance, kinetic theory in the relaxation time approximation typically has a branch cut between $-k$ and $k$ at $-i/\tau$ where $\tau$ is the relaxation time \cite{Kurkela:2017xis}. Holographic theories exhibit a so-called "Christmas tree" structure of an infinite number of poles with increasing real and imaginary values in the lower half plane \cite{Grozdanov:2018gfx}. Hydrodynamic theories such as M\"uller-Israel-Stewart (MIS) \cite{Muller:1967zza,Israel:1979wp} have a non-propagating dissipative pole.
One is left naturally to ask the question: what is the analytic structure and, ultimately, the microscopic structure of the QGP?

Here, we will aim to partly answer the above question by first underlining in Sec.~\ref{sec:oh4} that the chiral phase transition in the $O(4)$ model \cite{Rajagopal:1992qz, Son:1999pa,Son:2002ci}, a characteristic feature present in a typical heavy ion collision, can be understood via a collision of poles in the complex plane, as the system moves from diffusive to propagating degrees of freedom. Then in Sec.~\ref{sec:semi}, we will demonstrate a similar collision of poles in a theory with weak/strong coupling dynamics via a quasinormal mode analysis of a semiholographic model with a boundary scalar field.

\section{Colliding poles near the O(4) critical point}\label{sec:oh4}

Here, we will discuss reinterpret the chiral phase transition, explored via the $O(4)$ model in \cite{Grossi:2020ezz,Grossi:2021gqi, Florio:2021jlx,Soloviev:2021syx}, as a collision of poles in the complex plane.
We describe the $O(4)$ physics via the effective Hamiltonian
\begin{align}\label{ham}
\mathcal{H} =\int_x &p(T)+\frac{\chi_0}{4}\mu_{ab}^2
-\frac{1}{2}\Delta^{\mu\nu}D_\mu\phi_a D_\nu\phi_a+\frac{1}{2}m^2_0 (T-T_c) \phi_a\phi_a+\frac{\lambda}{4} (\phi_a\phi_a)^2-H_a\phi_a
\end{align}
where we denote the $O(4)$ vector via $\phi_a=(\sigma, \varphi_i)$, $\Delta^{\mu\nu}=u^\mu u^\nu +g^{\mu\nu},$ $\mu_{ab}$ is the $O(4)$ chemical potential, $\chi_0$ is the static susceptibility and $H_a$ is the explicit symmetry breaking term. Note that the mass term, $m^2=m_0^2(T-T_c)$, changes sign in the vicinity of the critical temperature.
Choosing $H_a=(H,0,0,0),$ we will work in the mean field limit, which is found by minimizing the potential in \eqref{ham} to find
\begin{align}
m^2_0(T-T_c) \sigma + \lambda \sigma^3-H=0,
\end{align}
which determines the mean field value of the condensate as a function of temperature, $\sigma(T)$, with its behavior shown in Fig.~\ref{fig:mean}.

\begin{figure}[htp]
\centering
\includegraphics[width=0.5\textwidth]{plots/fg.jpg}
\caption{Comparison of mean field order parameter to the lattice in \cite{Engels:2009tv,	Engels:2011km}.}\label{fig:mean}
\end{figure}

Computing the ideal equations of motion from \eqref{ham}, including dissipation and linearizing around mean field leads to the following coupled equations for the pions and chemical potential:
\begin{align}
{\partial_t\varphi}&=
-{{\mu}_A}
+{\Gamma(\nabla^2 -m^2)\varphi}
\\
{\partial_t \mu_A}&= {v^2(-\nabla^2+m^2)\varphi}
+{D_0 \nabla^2 \mu_A}
\end{align}
We do not consider the dynamics of the condensate, which decouple from the pions and the chemical potential in the linearized limit. From the above, we can determine the symmetrized propagators $G_{\rm sym}=T(G_R -G_A)/(i\omega)$. Here, we will focus on the
 the spectral density for the axial charge density-density correlator, which is related to the $\varphi\varphi$ symmetrized propagator via
\begin{align}
\rho_{AA}=\frac{\omega}{T (\chi_0 \omega_k)^2}G^{\varphi\varphi}_{\rm sym},
\end{align}
where $\omega_k^2=v^2(k^2+m^2).$
The behavior of this propagator is best understood by considering Fig.~\ref{fig:prop}. In the left panel, reproduced from \cite{Grossi:2021gqi}, the spectral function is plotted as a function of frequency for various $z\sim (T-T_c)/T_c$. At high temperatures, the system is in the unbroken phase, characterized by a diffusive peak that we can interpret as the diffusion of quarks in the QGP. As the temperature decreases, the system eventually goes through the phase transition, with the spectral function exhibiting two well-separated peaks that we can interpret as pions.

The right panel presents another way to view the same information in the left panel, but from the perspective of the pole structure of the spectral function. Starting from the green diffusive poles, representing the unbroken phase with $T\gg T_c$, the direction of decreasing temperature is indicated by the black arrows. Eventually the diffusive from the two poles collide, indicating that the system is undergoing a phase transition. From the collision point, further decreasing the temperature leads to two well separated poles, namely the pion modes.

In this way, the collision of poles as a function of temperature in the complex plane indicates a phase transition, a feature that should be studied in understanding the analytic structure of the QGP.

\begin{figure}[htp]
  \begin{center}
 \includegraphics[width=0.48\textwidth]{plots/propagator_plot.pdf}
\includegraphics[width=0.5\textwidth]{plots/denom.pdf}
    \end{center}
\caption{Two different ways to see the $O(4)$ phase transition via the spectral density. Left: The spectral density over frequency for different $z\sim T-T_c$. For the choice of parameters used in this plot, see the discussion in \cite{Grossi:2021gqi}. The diffusive peak in the unbroken phase $z\gg 0$ melts to two peaks in the broken phase, $z\ll 0$, representing the propagating pions. Right: the pole structure of the spectral density as a function of temperature. The green points represent $z=16$, i.e. the high temperature, unbroken phase, while the arrows indicate the decrease in temperature until the red point $z=-16.$ Like in the left plot, the diffusive poles on the imaginary axis melt down to two propagating poles. }
\label{fig:prop}
\end{figure}

\section{Colliding poles in holography}\label{sec:semi}

We now turn our attention to understanding the analytic structure of the QGP from another perspective. Although strong and weak coupling dynamics are often studied separately, a complete description of the QGP would entail understanding the interplay between the two sectors. One approach in this line of reasoning is known as semiholography \cite{Faulkner:2010tq, Iancu:2014ava, Mukhopadhyay:2015smb, Banerjee:2017ozx,Kurkela:2018dku,Ecker:2018ucc, Mitra:2020mei,Mitra:2022uhv}, a framework which self-consistently mixes {holography in the infrared} with perturbative degrees of freedom in the ultraviolet via dynamical boundary fields.

As a quick recap we first discuss a simple example of quasinormal modes (QNMs) found in holography, before moving onto the example of semiholography. QNMs describe dissipation of linearized perturbations around equilibrium solutions, i.e. the ring down of modes. As an example, consider the equation of motion for a bulk massless scalar field:
\begin{align}
\nabla_M \nabla^M \Phi =0,
\end{align}
living in the Eddington-Finkelstein Schwarzschild-AdS$_4$ background:
\begin{align}
ds^2=-\frac{L^2}{r^2}(1-Mr^3)dt^2-2 \frac{L^2}{r^2}dtdr+\frac{L^2}{r^2}(dx^2+dy^2).
\end{align}
We can decompose the scalar field into Fourier modes $\Phi(r,x^\mu)\rightarrow e^{-ix\cdot k}f(r,k_\mu)$, which leads to the linear equation
\begin{align}
0&=(Mr^3-1)f^{\prime\prime}+\frac{Mr^3+2-2ir \omega}{r}f^{\prime}+\frac{k^2r+2i\omega}{r}f
\end{align}
Computing the poles gives rise to the typical "Christmas tree" structure found in holography \cite{Horowitz:1999jd,Kovtun:2005ev,Berti:2009kk}, see the red points of Fig.~\ref{fig:homo-qnm}.

We now add an additional dynamic scalar field at the boundary of the holographic theory described above and follow the discussion in \cite{Mondkar:2021qsf}.
The semiholographic action reads
\begin{align}
S={W_{\rm CFT}}[{h(x)}=-\beta {\chi}] -\frac{1}{2}\int d^3 x\; { \partial_\mu \chi \partial^\mu \chi},
\end{align}
where $W_{\rm CFT}$ is the generating functional of the conformal field theory (dual to the gravitational theory), sourced by the boundary scalar, $\chi$, with $\beta$ governing the coupling between the two sectors.
The equation of motion for the scalar field is
\begin{align}
{\eta^{\mu\nu}\partial_\mu \partial_\nu\chi}=\beta {\frac{\delta W_{\rm CFT}}{\delta h}}=\beta {\mathcal{H}},
\end{align}
where $\mathcal{H}$ is the vacuum expectation value of the bulk scalar field, $\Phi.$
The equations of motion of the dual gravity theory to the CFT are
\begin{align}
{R_{MN}-\frac{1}{2}R G_{MN}-3G_{MN}}&={\kappa (\nabla_M \Phi \nabla_N\Phi-\frac{1}{2}G_{MN} (\nabla_P \Phi)^2 )},\\
{\nabla_M\nabla^M\Phi}&=0.
\end{align}
The bulk scalar field, ${\Phi}$, has the near boundary expansion:
\begin{align}
{\Phi}={-\beta {\chi}}
{+\ldots +\frac{3}{\kappa} \mathcal{H} r^3+\ldots}.
\end{align
Note that $\Phi$ is sourced by the dynamical boundary field, $\chi.$

The individual subsector Ward identities are
\begin{align*}
\partial_\mu {t^{\mu\nu}_\chi}=-{\mathcal{H}\partial^\nu h}, \quad
\partial_\mu {\mathcal{T}^{\mu\nu}} ={\mathcal{H}\partial^\nu h},
\end{align*}
where $t^{\mu\nu}_\chi$ is the boundary scalar stress tensor and $\mathcal{T}^{\mu\nu}$ is the holographic stress tensor
The energy momentum tensor of the full system is conserved, $\partial_\mu T^{\mu\nu}=\partial_\mu({t^{\mu\nu}_\chi}+{\mathcal{T}^{\mu\nu}})=0$.

We now study hybrid fluctuations of bulk dilaton ${\Phi}$ and the boundary scalar field ${\chi}$. In the case of homogeneous QNM,  we see in Fig.~\ref{fig:homo-qnm} that varying the coupling $\beta\sqrt{T}\rightarrow\infty$ moves the "Christmas tree" structure down into the complex plane and in the limit $\beta\sqrt{T}\rightarrow \infty,$ the system exhibits emergent conformality. Moreover, as we vary the coupling, there is a similar collision of poles on the imaginary axis as in the previous section. In this case, the diffusion-like poles become aligned on the "Christmas tree" structure for large coupling.

\begin{figure}
\center{
\includegraphics[width=0.65\linewidth]{plots/k=0_beta=0_to_10}
}\label{fig:homo-qnm}
\caption
Homogeneous quasinormal modes with arrows indicating the direction of increasing coupling, $\beta$. Red points denote the $\beta=0$ case, which is the typical "Christmas tree" pattern of the QNMs. A collision of poles indicates the breaking of the softly broken global symmetry.}
\end{figure}

  \begin{figure}[b]
\includegraphics[width=0.48\linewidth]{plots/ebh_ic1}
\includegraphics[width=0.48\linewidth]{plots/escal_ic1}
\caption{Evolution of the black hole energy and the kinetic energy in the left and right panel, respectively, for a variety of couplings.}\label{fig:evol}
    \end{figure}

In Fig.~\ref{fig:homo-qnm}, there is also a conspicious unstable mode in the upper half plane. However, the full nonlinear simulations show that the apparently unstable mode indicates that energy is driven from the holographic sector to the boundary scalar at early times, as can be seen in Fig.~\ref{fig:evol}.
Eventually the irreversible transfer of energy back to the holographic sector at later times is driven by the quasi-hydro mode. As such, the total system has no instability!

We now turn our attention to the inhomogeneous case. In particular, we examine the motion of the lowest lying poles for a demonstrative value of coupling, as can be seen in Fig.~\ref{fig:poles}. The first and last plot represent small and large $k$ behavior. The figures in between indicate the two collisions of poles that occur for intermediate momenta.  All collisions occur on the imaginary axis, with the poles acquiring a real part after the collision. The first collision occurs between the diffusion pole and the quasi-hydro pole for $k\sim 0.554\pi$, followed by a collision of the transient unstable mode (discussed above) and the semiholographic pole for $k\sim 2.433 \pi$. The two typical holographic poles (and the rest of the "Christmas tree" poles deeper in the complex plane) do not appreciably change as a function of momentum.

Finally, we also point out that in our model, we observe the formation of a $k$-gap as seen in Fig.~\ref{fig:kgap}, which is characteristic of systems with a diffusive to propagating mode crossover.
This has been observed in quasi-hydrodynamic frameworks \cite{Grozdanov:2018fic}, where the $k-$gap can be related to a softly broken global symmetry.  Here, global shift symmetry of the theory is
\begin{align}
{\chi}\rightarrow{ \chi}+{\chi_0}, \quad {\Phi}\rightarrow  {\Phi}-\beta { \chi_0}
\end{align}
The k-gap has been observed experimentally in the dispersion of transverse sound-like excitations of gallium \cite{Khusnutdinoff_2020}.

  \begin{figure}
\includegraphics[width=0.48\textwidth]{plots/inhomo1
\includegraphics[width=0.48\textwidth]{plots/inhomo2}\\%$k=0.554\pi$}
{\includegraphics[width=0.48\textwidth]{plots/inhomo3}
{\includegraphics[width=0.48\textwidth]{plots/inhomo4}}\\%$k=2.4\pi$
{\includegraphics[width=0.48\textwidth]{plots/inhomo6}
{\includegraphics[width=0.48\textwidth]{plots/inhomo5}
\caption{The first 6 poles in the complex plane for $k=\{0, 0.554\pi,0.6\pi,2.4\pi,2.4334\pi,2.54\pi \}$ (from top left to bottom right), for $\beta\sqrt{T}=0.35$. We distinguish the different poles via the following colors \textcolor{purple}{diffusion pole}, \textcolor{red}{quasi-hydro pole}, \textcolor{orange}{transient unstable mode},
\textcolor{green}{semiholographic pole} and \textcolor{blue}{holographic QNM}.}\label{fig:poles}
    \end{figure}

  \begin{figure}
\includegraphics[width=0.49\textwidth]{plots/re_omega_crossover_beta=0p15}
\includegraphics[width=0.49\textwidth]{plots/im_omega_crossover_beta=0p15}
\caption{The formation of the k-gap, shown for the particular case $\beta\sqrt{T}=0.15$.}\label{fig:kgap}
  \end{figure}

\section{Outlook}\label{sec:outlook}

The analytic structure of the QGP is rich. Due to the presence of phase transitions, such as the chiral phase transition and the one due to strong/weak coupling dynamics, we should expect to see colliding poles in the complex plane of theories relevant to the QGP. In the hybrid model outlined Sec.~\ref{sec:semi}, an immediate follow-up includes understanding the interaction of the quasinormal mode spectrum of a holographic theory with Israel-Stewart hydrodynamics \cite{mondkar:tbp}. Another important direction is to see the interplay of QNM poles with branch cuts typical to kinetic theory, especially in the vicinity of a phase transition.

\section*{Acknowledgments}
The author is supported by the Austrian Science Fund (FWF), project no. J4406.

redpajama_set_name: RedPajamaArXiv


This Thai Red Curry is Amy's dad's favourite. It has finely cut vegetables - sautéed onions, broccoli, carrots, tofu and delightfully sweet butternut squash in an authentically spiced smooth coconut milk-based curry sauce. Fragrant jasmine rice completes this meal that has no dairy and no wheat, and is absolutely delicious.